@openrewrite/rewrite 8.96.3 → 8.96.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/execution.d.ts +2 -0
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +4 -0
- package/dist/execution.js.map +1 -1
- package/dist/heavyweight.d.ts +8 -0
- package/dist/heavyweight.d.ts.map +1 -0
- package/dist/heavyweight.js +45 -0
- package/dist/heavyweight.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/java/tree.d.ts +11 -11
- package/dist/java/tree.d.ts.map +1 -1
- package/dist/java/visitor.d.ts.map +1 -1
- package/dist/java/visitor.js +46 -2
- package/dist/java/visitor.js.map +1 -1
- package/dist/javascript/add-import.d.ts +2 -1
- package/dist/javascript/add-import.d.ts.map +1 -1
- package/dist/javascript/add-import.js +14 -2
- package/dist/javascript/add-import.js.map +1 -1
- package/dist/javascript/amd.d.ts.map +1 -1
- package/dist/javascript/amd.js +2 -1
- package/dist/javascript/amd.js.map +1 -1
- package/dist/javascript/cleanup/add-parse-int-radix.js +1 -1
- package/dist/javascript/cleanup/add-parse-int-radix.js.map +1 -1
- package/dist/javascript/format/format.d.ts +12 -0
- package/dist/javascript/format/format.d.ts.map +1 -1
- package/dist/javascript/format/format.js +17 -3
- package/dist/javascript/format/format.js.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.d.ts.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.js +4 -0
- package/dist/javascript/format/tabs-and-indents-visitor.js.map +1 -1
- package/dist/javascript/format/whitespace-reconciler.d.ts.map +1 -1
- package/dist/javascript/format/whitespace-reconciler.js +4 -0
- package/dist/javascript/format/whitespace-reconciler.js.map +1 -1
- package/dist/javascript/node-resolution-result.d.ts.map +1 -1
- package/dist/javascript/node-resolution-result.js +2 -0
- package/dist/javascript/node-resolution-result.js.map +1 -1
- package/dist/javascript/parser-utils.d.ts.map +1 -1
- package/dist/javascript/parser-utils.js +16 -5
- package/dist/javascript/parser-utils.js.map +1 -1
- package/dist/javascript/templating/engine.d.ts.map +1 -1
- package/dist/javascript/templating/engine.js +11 -6
- package/dist/javascript/templating/engine.js.map +1 -1
- package/dist/javascript/templating/pattern.d.ts.map +1 -1
- package/dist/javascript/templating/pattern.js +8 -0
- package/dist/javascript/templating/pattern.js.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.d.ts.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.js +15 -0
- package/dist/javascript/templating/placeholder-replacement.js.map +1 -1
- package/dist/javascript/templating/precedence.js +1 -1
- package/dist/javascript/templating/precedence.js.map +1 -1
- package/dist/javascript/tree.d.ts +12 -12
- package/dist/javascript/tree.d.ts.map +1 -1
- package/dist/javascript/visitor.d.ts.map +1 -1
- package/dist/javascript/visitor.js +96 -0
- package/dist/javascript/visitor.js.map +1 -1
- package/dist/recipe.d.ts +5 -0
- package/dist/recipe.d.ts.map +1 -1
- package/dist/recipe.js +5 -0
- package/dist/recipe.js.map +1 -1
- package/dist/rewrite-javascript-version.txt +1 -1
- package/dist/run.d.ts +7 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +40 -2
- package/dist/run.js.map +1 -1
- package/dist/test/accumulator-contents.d.ts +15 -0
- package/dist/test/accumulator-contents.d.ts.map +1 -0
- package/dist/test/accumulator-contents.js +185 -0
- package/dist/test/accumulator-contents.js.map +1 -0
- package/dist/test/empty-sources.d.ts +14 -0
- package/dist/test/empty-sources.d.ts.map +1 -0
- package/dist/test/empty-sources.js +98 -0
- package/dist/test/empty-sources.js.map +1 -0
- package/dist/test/formatting-scope.d.ts +18 -0
- package/dist/test/formatting-scope.d.ts.map +1 -0
- package/dist/test/formatting-scope.js +244 -0
- package/dist/test/formatting-scope.js.map +1 -0
- package/dist/test/probes.d.ts +25 -0
- package/dist/test/probes.d.ts.map +1 -0
- package/dist/test/probes.js +189 -0
- package/dist/test/probes.js.map +1 -0
- package/dist/test/rewrite-test.d.ts +27 -0
- package/dist/test/rewrite-test.d.ts.map +1 -1
- package/dist/test/rewrite-test.js +191 -21
- package/dist/test/rewrite-test.js.map +1 -1
- package/dist/test/tree-shapes.d.ts +15 -0
- package/dist/test/tree-shapes.d.ts.map +1 -0
- package/dist/test/tree-shapes.js +288 -0
- package/dist/test/tree-shapes.js.map +1 -0
- package/dist/test/unparsed-sources.d.ts +17 -0
- package/dist/test/unparsed-sources.d.ts.map +1 -0
- package/dist/test/unparsed-sources.js +113 -0
- package/dist/test/unparsed-sources.js.map +1 -0
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +2 -0
- package/dist/tree.js.map +1 -1
- package/dist/visitor.d.ts.map +1 -1
- package/dist/visitor.js +2 -0
- package/dist/visitor.js.map +1 -1
- package/node_modules/picomatch/LICENSE +21 -0
- package/node_modules/picomatch/README.md +743 -0
- package/node_modules/picomatch/index.js +17 -0
- package/node_modules/picomatch/lib/constants.js +184 -0
- package/node_modules/picomatch/lib/parse.js +1506 -0
- package/node_modules/picomatch/lib/picomatch.js +361 -0
- package/node_modules/picomatch/lib/scan.js +403 -0
- package/node_modules/picomatch/lib/utils.js +72 -0
- package/node_modules/picomatch/package.json +83 -0
- package/node_modules/picomatch/posix.js +3 -0
- package/package.json +88 -90
- package/src/execution.ts +6 -0
- package/src/heavyweight.ts +42 -0
- package/src/index.ts +1 -0
- package/src/java/tree.ts +11 -11
- package/src/java/visitor.ts +52 -2
- package/src/javascript/add-import.ts +11 -2
- package/src/javascript/amd.ts +4 -2
- package/src/javascript/cleanup/add-parse-int-radix.ts +2 -2
- package/src/javascript/format/format.ts +25 -1
- package/src/javascript/format/tabs-and-indents-visitor.ts +4 -0
- package/src/javascript/format/whitespace-reconciler.ts +4 -0
- package/src/javascript/node-resolution-result.ts +3 -0
- package/src/javascript/parser-utils.ts +19 -7
- package/src/javascript/templating/engine.ts +11 -6
- package/src/javascript/templating/pattern.ts +10 -0
- package/src/javascript/templating/placeholder-replacement.ts +16 -0
- package/src/javascript/templating/precedence.ts +1 -1
- package/src/javascript/tree.ts +12 -12
- package/src/javascript/visitor.ts +120 -0
- package/src/recipe.ts +5 -0
- package/src/run.ts +30 -2
- package/src/test/accumulator-contents.ts +194 -0
- package/src/test/empty-sources.ts +99 -0
- package/src/test/formatting-scope.ts +231 -0
- package/src/test/probes.ts +156 -0
- package/src/test/rewrite-test.ts +177 -24
- package/src/test/tree-shapes.ts +332 -0
- package/src/test/unparsed-sources.ts +138 -0
- package/src/tree.ts +3 -0
- package/src/visitor.ts +3 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 the original author or authors.
|
|
3
|
+
* <p>
|
|
4
|
+
* Licensed under the Moderne Source Available License (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
* <p>
|
|
8
|
+
* https://docs.moderne.io/licensing/moderne-source-available-license
|
|
9
|
+
* <p>
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import {Recipe} from "../recipe";
|
|
17
|
+
import {ExecutionContext} from "../execution";
|
|
18
|
+
import {SourceFile} from "../tree";
|
|
19
|
+
import {Result} from "../run";
|
|
20
|
+
import {TreePrinters} from "../print";
|
|
21
|
+
import {isParseError} from "../parse-error";
|
|
22
|
+
import {MarkersKind} from "../markers";
|
|
23
|
+
import {PlainText} from "../text";
|
|
24
|
+
import {randomId} from "../uuid";
|
|
25
|
+
import {describeThrown, probeOnce, thrownBy, typeName, withMarkersOf} from "./probes";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Runs the recipe without a source it changed, as it meets a file its parser failed on, and with that source as plain
|
|
29
|
+
* text, and fails the test if the recipe throws there.
|
|
30
|
+
*/
|
|
31
|
+
export class UnparsedSources {
|
|
32
|
+
private readonly changed: Set<SourceFile>;
|
|
33
|
+
|
|
34
|
+
constructor(private readonly recipe: Recipe, results: Result[]) {
|
|
35
|
+
this.changed = new Set(results.filter(r => r.before && r.after !== r.before).map(r => r.before!));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async assertNoneThrow(sources: SourceFile[], recipeCtx: ExecutionContext, cycles: number): Promise<void> {
|
|
39
|
+
if (await declaredInline(this.recipe)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const probedKinds = new Set<string>();
|
|
43
|
+
for (const before of sources) {
|
|
44
|
+
if (!this.changed.has(before) || isParseError(before) || probedKinds.has(before.kind)) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
probedKinds.add(before.kind);
|
|
48
|
+
await probeOnce(this.recipe, `unparsed ${before.kind} missing`, async () => {
|
|
49
|
+
const thrown = await thrownBy(this.recipe, sources.filter(s => s !== before), recipeCtx, cycles);
|
|
50
|
+
if (thrown) {
|
|
51
|
+
throw new Error(this.missingMessage(before, thrown.error));
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
if (before.kind !== PlainText.Kind.PlainText) {
|
|
55
|
+
await probeOnce(this.recipe, `unparsed ${before.kind} ${PlainText.Kind.PlainText}`, async () => {
|
|
56
|
+
const unparsed = await asPlainText(before);
|
|
57
|
+
const thrown = await thrownBy(this.recipe, sources.map(s => s === before ? unparsed : s),
|
|
58
|
+
recipeCtx, cycles);
|
|
59
|
+
if (thrown) {
|
|
60
|
+
throw new Error(this.plainTextMessage(unparsed, thrown.error));
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private missingMessage(missing: SourceFile, thrown: unknown): string {
|
|
68
|
+
return [
|
|
69
|
+
"Check that the scanner found the files the recipe needs before using what it keeps of them, so that " +
|
|
70
|
+
"the recipe changes nothing instead of throwing when one is missing.",
|
|
71
|
+
`${this.recipe.name} threw when ${missing.sourcePath} was missing, which is how a JavaScript recipe sees ` +
|
|
72
|
+
"a file its parser failed on or left unparsed:",
|
|
73
|
+
describeThrown(thrown, " "),
|
|
74
|
+
"Besides the files the test gives it, a repository holds files their parser failed on or left " +
|
|
75
|
+
"unparsed. The host sends a JavaScript recipe only the JS/TS, JSON, YAML and plain-text files it " +
|
|
76
|
+
"parsed, so such a file is simply not there for the recipe.",
|
|
77
|
+
" - when the scanner found no file of the kind the recipe needs, generate and change nothing, instead " +
|
|
78
|
+
"of reading an empty accumulator",
|
|
79
|
+
" - check for undefined before using what the scanner keeps of a file it may not find " +
|
|
80
|
+
"(`acc.get(\"package.json\")?.version`)",
|
|
81
|
+
" - don't catch the exception to make this pass"
|
|
82
|
+
].join("\n");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private plainTextMessage(unparsed: SourceFile, thrown: unknown): string {
|
|
86
|
+
return [
|
|
87
|
+
"Check the kind of source file before casting it, so that the recipe leaves a file it can't edit " +
|
|
88
|
+
"unchanged instead of throwing.",
|
|
89
|
+
`${this.recipe.name} threw when ${unparsed.sourcePath} was a ${typeName(unparsed.kind)} (a file read ` +
|
|
90
|
+
`as plain text)${withMarkersOf(unparsed.markers.markers)}:`,
|
|
91
|
+
describeThrown(thrown, " "),
|
|
92
|
+
"Besides the files the test gives it, a repository holds files read as plain text, at the same paths " +
|
|
93
|
+
"and with the same markers as files the recipe edits.",
|
|
94
|
+
" - visit with the visitor of the language the recipe edits, such as JavaScriptVisitor, JsonVisitor or " +
|
|
95
|
+
"YamlVisitor, whose isAcceptable skips other kinds of source file",
|
|
96
|
+
" - in a TreeVisitor<any, ExecutionContext>, check the kind before a cast " +
|
|
97
|
+
"(`tree.kind === JS.Kind.CompilationUnit`), not the file's path or markers",
|
|
98
|
+
" - don't catch the exception to make this pass"
|
|
99
|
+
].join("\n");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** The file `before` was parsed from, as the plain text a repository holds when no parser claims the file. */
|
|
104
|
+
async function asPlainText(before: SourceFile): Promise<PlainText> {
|
|
105
|
+
return {
|
|
106
|
+
kind: PlainText.Kind.PlainText,
|
|
107
|
+
id: randomId(),
|
|
108
|
+
// these come from parsing the file itself
|
|
109
|
+
markers: {
|
|
110
|
+
...before.markers,
|
|
111
|
+
markers: before.markers.markers.filter(m => m.kind !== MarkersKind.ParseExceptionResult &&
|
|
112
|
+
!m.kind.endsWith("ResolutionResult"))
|
|
113
|
+
},
|
|
114
|
+
sourcePath: before.sourcePath,
|
|
115
|
+
charsetName: before.charsetName,
|
|
116
|
+
charsetBomMarked: before.charsetBomMarked,
|
|
117
|
+
checksum: before.checksum,
|
|
118
|
+
fileAttributes: before.fileAttributes,
|
|
119
|
+
text: await TreePrinters.print(before),
|
|
120
|
+
snippets: []
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Whether the recipe, or one in its recipe list, is an anonymous class, which a test declares inline for itself as Java
|
|
126
|
+
* tests declare their scaffolding.
|
|
127
|
+
*/
|
|
128
|
+
async function declaredInline(recipe: Recipe): Promise<boolean> {
|
|
129
|
+
if (recipe.constructor.name === "") {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
for (const child of await recipe.recipeList()) {
|
|
133
|
+
if (await declaredInline(child)) {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
138
|
+
}
|
package/src/tree.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {Markers} from "./markers";
|
|
|
17
17
|
import {UUID} from "./uuid";
|
|
18
18
|
import {PlainText} from "./text";
|
|
19
19
|
import {RpcCodecs} from "./rpc";
|
|
20
|
+
import {registerHeavyweight} from "./heavyweight";
|
|
20
21
|
|
|
21
22
|
export const TreeKind = {
|
|
22
23
|
Checksum: "org.openrewrite.Checksum",
|
|
@@ -112,6 +113,8 @@ export class Cursor {
|
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
115
|
|
|
116
|
+
registerHeavyweight(Cursor);
|
|
117
|
+
|
|
115
118
|
export function rootCursor(): Cursor {
|
|
116
119
|
return new Cursor("root");
|
|
117
120
|
}
|
package/src/visitor.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {emptyMarkers, Marker, Markers} from "./markers";
|
|
|
17
17
|
import {Cursor, isSourceFile, rootCursor, SourceFile, Tree} from "./tree";
|
|
18
18
|
import {create, Draft} from "mutative";
|
|
19
19
|
import {mapAsync, updateIfChanged} from "./util";
|
|
20
|
+
import {registerHeavyweight} from "./heavyweight";
|
|
20
21
|
|
|
21
22
|
type Objectish = Record<string, any> | Array<any>;
|
|
22
23
|
|
|
@@ -165,6 +166,8 @@ export abstract class TreeVisitor<T extends Tree, P> {
|
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
168
|
|
|
169
|
+
registerHeavyweight(TreeVisitor);
|
|
170
|
+
|
|
168
171
|
export function noopVisitor<T extends Tree, P>(): TreeVisitor<T, P> {
|
|
169
172
|
return new class extends TreeVisitor<T, P> {
|
|
170
173
|
async visit<R extends Tree>(tree: Tree): Promise<R | undefined> {
|