@openrewrite/rewrite 8.70.0-20251219-160440 → 8.70.0-20251219-215811
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/cli/cli-utils.d.ts +6 -6
- package/dist/cli/cli-utils.d.ts.map +1 -1
- package/dist/cli/cli-utils.js +50 -228
- package/dist/cli/cli-utils.js.map +1 -1
- package/dist/javascript/assertions.d.ts.map +1 -1
- package/dist/javascript/assertions.js +87 -12
- package/dist/javascript/assertions.js.map +1 -1
- package/dist/javascript/autodetect.d.ts +11 -11
- package/dist/javascript/autodetect.d.ts.map +1 -1
- package/dist/javascript/autodetect.js +18 -21
- package/dist/javascript/autodetect.js.map +1 -1
- package/dist/javascript/format/prettier-config-loader.d.ts.map +1 -1
- package/dist/javascript/format/prettier-config-loader.js +1 -1
- package/dist/javascript/format/prettier-config-loader.js.map +1 -1
- package/dist/javascript/index.d.ts +1 -0
- package/dist/javascript/index.d.ts.map +1 -1
- package/dist/javascript/index.js +1 -0
- package/dist/javascript/index.js.map +1 -1
- package/dist/javascript/markers.d.ts.map +1 -1
- package/dist/javascript/markers.js +135 -6
- package/dist/javascript/markers.js.map +1 -1
- package/dist/javascript/node-resolution-result.d.ts +4 -1
- package/dist/javascript/node-resolution-result.d.ts.map +1 -1
- package/dist/javascript/node-resolution-result.js +22 -1
- package/dist/javascript/node-resolution-result.js.map +1 -1
- package/dist/javascript/package-json-parser.d.ts +7 -0
- package/dist/javascript/package-json-parser.d.ts.map +1 -1
- package/dist/javascript/package-json-parser.js +19 -1
- package/dist/javascript/package-json-parser.js.map +1 -1
- package/dist/javascript/parser.d.ts.map +1 -1
- package/dist/javascript/parser.js +1 -13
- package/dist/javascript/parser.js.map +1 -1
- package/dist/javascript/preconditions.js +4 -4
- package/dist/javascript/preconditions.js.map +1 -1
- package/dist/javascript/project-parser.d.ts +137 -0
- package/dist/javascript/project-parser.d.ts.map +1 -0
- package/dist/javascript/project-parser.js +726 -0
- package/dist/javascript/project-parser.js.map +1 -0
- package/dist/javascript/style.d.ts +9 -26
- package/dist/javascript/style.d.ts.map +1 -1
- package/dist/javascript/style.js +18 -42
- package/dist/javascript/style.js.map +1 -1
- package/dist/json/parser.d.ts.map +1 -1
- package/dist/json/parser.js +1 -0
- package/dist/json/parser.js.map +1 -1
- package/dist/markers.d.ts +1 -1
- package/dist/markers.js +1 -1
- package/dist/markers.js.map +1 -1
- package/dist/parser.d.ts +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/rpc/index.d.ts +0 -1
- package/dist/rpc/index.d.ts.map +1 -1
- package/dist/rpc/index.js +4 -2
- package/dist/rpc/index.js.map +1 -1
- package/dist/rpc/request/index.d.ts +1 -0
- package/dist/rpc/request/index.d.ts.map +1 -1
- package/dist/rpc/request/index.js +1 -0
- package/dist/rpc/request/index.js.map +1 -1
- package/dist/rpc/request/parse-project.d.ts +25 -0
- package/dist/rpc/request/parse-project.d.ts.map +1 -0
- package/dist/rpc/request/parse-project.js +304 -0
- package/dist/rpc/request/parse-project.js.map +1 -0
- package/dist/rpc/rewrite-rpc.d.ts.map +1 -1
- package/dist/rpc/rewrite-rpc.js +1 -0
- package/dist/rpc/rewrite-rpc.js.map +1 -1
- package/dist/text/parser.d.ts.map +1 -1
- package/dist/text/parser.js +1 -0
- package/dist/text/parser.js.map +1 -1
- package/dist/version.txt +1 -1
- package/dist/yaml/parser.d.ts.map +1 -1
- package/dist/yaml/parser.js +52 -4
- package/dist/yaml/parser.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/cli-utils.ts +46 -237
- package/src/javascript/assertions.ts +74 -10
- package/src/javascript/autodetect.ts +22 -15
- package/src/javascript/format/prettier-config-loader.ts +2 -2
- package/src/javascript/index.ts +1 -0
- package/src/javascript/markers.ts +157 -7
- package/src/javascript/node-resolution-result.ts +23 -2
- package/src/javascript/package-json-parser.ts +19 -1
- package/src/javascript/parser.ts +1 -16
- package/src/javascript/preconditions.ts +1 -1
- package/src/javascript/project-parser.ts +657 -0
- package/src/javascript/style.ts +43 -28
- package/src/json/parser.ts +3 -1
- package/src/markers.ts +1 -1
- package/src/parser.ts +1 -1
- package/src/rpc/index.ts +7 -5
- package/src/rpc/request/index.ts +1 -0
- package/src/rpc/request/parse-project.ts +283 -0
- package/src/rpc/rewrite-rpc.ts +2 -0
- package/src/text/parser.ts +3 -1
- package/src/yaml/parser.ts +53 -5
package/src/javascript/style.ts
CHANGED
|
@@ -28,7 +28,8 @@ export const StyleKind = {
|
|
|
28
28
|
WrappingAndBracesStyle: "org.openrewrite.javascript.style.WrappingAndBracesStyle",
|
|
29
29
|
BlankLinesStyle: "org.openrewrite.javascript.style.BlankLinesStyle",
|
|
30
30
|
TabsAndIndentsStyle: "org.openrewrite.javascript.style.TabsAndIndentsStyle",
|
|
31
|
-
PrettierStyle: "org.openrewrite.javascript.style.PrettierStyle"
|
|
31
|
+
PrettierStyle: "org.openrewrite.javascript.style.PrettierStyle",
|
|
32
|
+
Autodetect: "org.openrewrite.javascript.style.Autodetect"
|
|
32
33
|
} as const;
|
|
33
34
|
|
|
34
35
|
/**
|
|
@@ -41,32 +42,46 @@ export const StyleKind = {
|
|
|
41
42
|
* When this style is present, AutoformatVisitor will use Prettier for formatting
|
|
42
43
|
* instead of the built-in formatting visitors.
|
|
43
44
|
*/
|
|
44
|
-
export
|
|
45
|
-
readonly kind
|
|
46
|
-
readonly name
|
|
47
|
-
readonly displayName
|
|
48
|
-
readonly description
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
45
|
+
export interface PrettierStyle extends NamedStyles<typeof StyleKind.PrettierStyle> {
|
|
46
|
+
readonly kind: typeof StyleKind.PrettierStyle;
|
|
47
|
+
readonly name: "org.openrewrite.javascript.Prettier";
|
|
48
|
+
readonly displayName: "Prettier";
|
|
49
|
+
readonly description: "Prettier code formatter configuration.";
|
|
50
|
+
/**
|
|
51
|
+
* The resolved Prettier options for this file (with overrides applied).
|
|
52
|
+
*/
|
|
53
|
+
readonly config: Record<string, unknown>;
|
|
54
|
+
/**
|
|
55
|
+
* The Prettier version from the project's package.json.
|
|
56
|
+
* At formatting time, this version of Prettier will be loaded dynamically
|
|
57
|
+
* to ensure consistent formatting.
|
|
58
|
+
*/
|
|
59
|
+
readonly prettierVersion?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Whether this file is ignored by .prettierignore.
|
|
62
|
+
* When true, Prettier formatting should be skipped for this file.
|
|
63
|
+
*/
|
|
64
|
+
readonly ignored: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function prettierStyle(
|
|
68
|
+
id: string,
|
|
69
|
+
config: Record<string, unknown>,
|
|
70
|
+
prettierVersion?: string,
|
|
71
|
+
ignored: boolean = false
|
|
72
|
+
): PrettierStyle {
|
|
73
|
+
return {
|
|
74
|
+
kind: StyleKind.PrettierStyle,
|
|
75
|
+
id,
|
|
76
|
+
name: "org.openrewrite.javascript.Prettier",
|
|
77
|
+
displayName: "Prettier",
|
|
78
|
+
description: "Prettier code formatter configuration.",
|
|
79
|
+
tags: [],
|
|
80
|
+
styles: [],
|
|
81
|
+
config,
|
|
82
|
+
prettierVersion,
|
|
83
|
+
ignored
|
|
84
|
+
};
|
|
70
85
|
}
|
|
71
86
|
|
|
72
87
|
export const SpacesStyleDetailKind = {
|
|
@@ -187,7 +202,7 @@ export namespace SpacesStyle {
|
|
|
187
202
|
}
|
|
188
203
|
|
|
189
204
|
export const WrappingAndBracesStyleDetailKind = {
|
|
190
|
-
WrappingAndBracesStyleIfStatement: "org.openrewrite.
|
|
205
|
+
WrappingAndBracesStyleIfStatement: "org.openrewrite.javascript.style.WrappingAndBracesStyle$IfStatement",
|
|
191
206
|
WrappingAndBracesStyleKeepWhenReformatting: "org.openrewrite.javascript.style.WrappingAndBracesStyle$KeepWhenReformatting",
|
|
192
207
|
} as const;
|
|
193
208
|
|
package/src/json/parser.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import {emptyMarkers, markers, MarkersKind, ParseExceptionResult} from "../markers";
|
|
17
|
-
import {Parser, ParserInput, parserInputRead} from "../parser";
|
|
17
|
+
import {Parser, ParserInput, parserInputRead, Parsers} from "../parser";
|
|
18
18
|
import {randomId} from "../uuid";
|
|
19
19
|
import {SourceFile} from "../tree";
|
|
20
20
|
import {emptySpace, Json, space} from "./tree";
|
|
@@ -534,3 +534,5 @@ class JsoncParserReader {
|
|
|
534
534
|
} satisfies Json.Literal as Json.Literal;
|
|
535
535
|
}
|
|
536
536
|
}
|
|
537
|
+
|
|
538
|
+
Parsers.registerParser("json", JsonParser);
|
package/src/markers.ts
CHANGED
|
@@ -18,7 +18,7 @@ import {asRef} from "./reference";
|
|
|
18
18
|
|
|
19
19
|
export const MarkersKind = {
|
|
20
20
|
Markers: "org.openrewrite.marker.Markers",
|
|
21
|
-
NamedStyles: "org.openrewrite.
|
|
21
|
+
NamedStyles: "org.openrewrite.style.NamedStyles",
|
|
22
22
|
SearchResult: "org.openrewrite.marker.SearchResult",
|
|
23
23
|
ParseExceptionResult: "org.openrewrite.ParseExceptionResult",
|
|
24
24
|
|
package/src/parser.ts
CHANGED
|
@@ -148,7 +148,7 @@ export function readSourceSync(sourcePath: ParserInput) {
|
|
|
148
148
|
|
|
149
149
|
type ParserConstructor<T extends Parser> = new (options?: ParserOptions) => T;
|
|
150
150
|
|
|
151
|
-
export type ParserType = "javascript" | "packageJson";
|
|
151
|
+
export type ParserType = "javascript" | "packageJson" | "json" | "yaml" | "plainText";
|
|
152
152
|
|
|
153
153
|
export class Parsers {
|
|
154
154
|
private static registry = new Map<ParserType, ParserConstructor<Parser>>();
|
package/src/rpc/index.ts
CHANGED
|
@@ -16,11 +16,13 @@
|
|
|
16
16
|
import {Checksum, FileAttributes, TreeKind} from "../tree";
|
|
17
17
|
import {RpcCodecs, RpcReceiveQueue, RpcSendQueue} from "./queue";
|
|
18
18
|
import {createDraft, finishDraft} from "immer";
|
|
19
|
-
import {Markers, MarkersKind,
|
|
19
|
+
import {Markers, MarkersKind, MarkupDebug, MarkupError, MarkupInfo, MarkupWarn, SearchResult} from "../markers";
|
|
20
|
+
import {asRef} from "../reference";
|
|
20
21
|
|
|
21
|
-
export * from "./queue"
|
|
22
|
-
export * from "../reference"
|
|
23
|
-
|
|
22
|
+
export * from "./queue";
|
|
23
|
+
export * from "../reference";
|
|
24
|
+
// rewrite-rpc is not exported here to avoid circular dependency
|
|
25
|
+
// Import directly from "./rewrite-rpc" if needed
|
|
24
26
|
|
|
25
27
|
RpcCodecs.registerCodec(TreeKind.Checksum, {
|
|
26
28
|
async rpcReceive(before: Checksum, q: RpcReceiveQueue): Promise<Checksum> {
|
|
@@ -70,7 +72,7 @@ RpcCodecs.registerCodec(MarkersKind.Markers, {
|
|
|
70
72
|
|
|
71
73
|
async rpcSend(after: Markers, q: RpcSendQueue): Promise<void> {
|
|
72
74
|
await q.getAndSend(after, m => m.id);
|
|
73
|
-
await q.getAndSendList(after, m => m.markers, m => m.id);
|
|
75
|
+
await q.getAndSendList(after, m => m.markers.map(marker => asRef(marker)), m => m.id);
|
|
74
76
|
}
|
|
75
77
|
});
|
|
76
78
|
|
package/src/rpc/request/index.ts
CHANGED
|
@@ -0,0 +1,283 @@
|
|
|
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 * as rpc from "vscode-jsonrpc/node";
|
|
17
|
+
import * as path from "path";
|
|
18
|
+
import {ExecutionContext} from "../../execution";
|
|
19
|
+
import {randomId, UUID} from "../../uuid";
|
|
20
|
+
import {produce} from "immer";
|
|
21
|
+
import {SourceFile} from "../../tree";
|
|
22
|
+
import {Parsers} from "../../parser";
|
|
23
|
+
import {withMetrics} from "./metrics";
|
|
24
|
+
import {DEFAULT_EXCLUSIONS, ProjectParser} from "../../javascript";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Response item with object ID and source file type for proper deserialization.
|
|
28
|
+
*/
|
|
29
|
+
export interface ParseProjectResponseItem {
|
|
30
|
+
id: UUID;
|
|
31
|
+
sourceFileType: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* RPC request to parse an entire project directory.
|
|
36
|
+
* Discovers and parses:
|
|
37
|
+
* - JavaScript/TypeScript source files
|
|
38
|
+
* - package.json files (with NodeResolutionResult markers)
|
|
39
|
+
* - Lock files (package-lock.json as JSON, yarn.lock/pnpm-lock.yaml as YAML)
|
|
40
|
+
*
|
|
41
|
+
* Uses ProjectParser for file discovery and Prettier detection.
|
|
42
|
+
*/
|
|
43
|
+
export class ParseProject {
|
|
44
|
+
constructor(
|
|
45
|
+
private readonly projectPath: string,
|
|
46
|
+
private readonly exclusions?: string[]
|
|
47
|
+
) {}
|
|
48
|
+
|
|
49
|
+
static handle(
|
|
50
|
+
connection: rpc.MessageConnection,
|
|
51
|
+
localObjects: Map<string, ((input: string) => any) | any>,
|
|
52
|
+
metricsCsv?: string
|
|
53
|
+
): void {
|
|
54
|
+
connection.onRequest(
|
|
55
|
+
new rpc.RequestType<ParseProject, ParseProjectResponseItem[], Error>("ParseProject"),
|
|
56
|
+
withMetrics<ParseProject, ParseProjectResponseItem[]>(
|
|
57
|
+
"ParseProject",
|
|
58
|
+
metricsCsv,
|
|
59
|
+
(context) => async (request) => {
|
|
60
|
+
context.target = request.projectPath;
|
|
61
|
+
|
|
62
|
+
const projectPath = path.resolve(request.projectPath);
|
|
63
|
+
const exclusions = request.exclusions ?? DEFAULT_EXCLUSIONS;
|
|
64
|
+
|
|
65
|
+
// Use ProjectParser for file discovery and Prettier detection
|
|
66
|
+
const projectParser = new ProjectParser(projectPath, {exclusions});
|
|
67
|
+
const discovered = await projectParser.discoverFiles();
|
|
68
|
+
const prettierLoader = await projectParser.createPrettierLoader();
|
|
69
|
+
|
|
70
|
+
const resultItems: ParseProjectResponseItem[] = [];
|
|
71
|
+
const ctx = new ExecutionContext();
|
|
72
|
+
|
|
73
|
+
// Parse package.json files (these get NodeResolutionResult markers)
|
|
74
|
+
if (discovered.packageJsonFiles.length > 0) {
|
|
75
|
+
const parser = Parsers.createParser("packageJson", {
|
|
76
|
+
ctx,
|
|
77
|
+
relativeTo: projectPath
|
|
78
|
+
});
|
|
79
|
+
const generator = parser.parse(...discovered.packageJsonFiles);
|
|
80
|
+
|
|
81
|
+
for (const _ of discovered.packageJsonFiles) {
|
|
82
|
+
const id = randomId();
|
|
83
|
+
localObjects.set(id, async (id: string) => {
|
|
84
|
+
const sourceFile: SourceFile = (await generator.next()).value;
|
|
85
|
+
return produce(sourceFile, (draft) => {
|
|
86
|
+
draft.id = id;
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
resultItems.push({
|
|
90
|
+
id,
|
|
91
|
+
sourceFileType: "org.openrewrite.json.tree.Json$Document" // break cycle
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Parse JSON lock files
|
|
97
|
+
if (discovered.lockFiles.json.length > 0) {
|
|
98
|
+
const parser = Parsers.createParser("json", {ctx, relativeTo: projectPath});
|
|
99
|
+
const generator = parser.parse(...discovered.lockFiles.json);
|
|
100
|
+
|
|
101
|
+
for (const _ of discovered.lockFiles.json) {
|
|
102
|
+
const id = randomId();
|
|
103
|
+
localObjects.set(id, async (id: string) => {
|
|
104
|
+
const sourceFile: SourceFile = (await generator.next()).value;
|
|
105
|
+
return produce(sourceFile, (draft) => {
|
|
106
|
+
draft.id = id;
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
resultItems.push({
|
|
110
|
+
id,
|
|
111
|
+
sourceFileType: "org.openrewrite.json.tree.Json$Document" // break cycle
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Parse YAML lock files
|
|
117
|
+
if (discovered.lockFiles.yaml.length > 0) {
|
|
118
|
+
const parser = Parsers.createParser("yaml", {ctx, relativeTo: projectPath});
|
|
119
|
+
const generator = parser.parse(...discovered.lockFiles.yaml);
|
|
120
|
+
|
|
121
|
+
for (const _ of discovered.lockFiles.yaml) {
|
|
122
|
+
const id = randomId();
|
|
123
|
+
localObjects.set(id, async (id: string) => {
|
|
124
|
+
const sourceFile: SourceFile = (await generator.next()).value;
|
|
125
|
+
return produce(sourceFile, (draft) => {
|
|
126
|
+
draft.id = id;
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
resultItems.push({
|
|
130
|
+
id,
|
|
131
|
+
sourceFileType: "org.openrewrite.yaml.tree.Yaml$Documents" // break cycle
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Parse text lock files (yarn.lock Classic)
|
|
137
|
+
if (discovered.lockFiles.text.length > 0) {
|
|
138
|
+
const parser = Parsers.createParser("plainText", {ctx, relativeTo: projectPath});
|
|
139
|
+
const generator = parser.parse(...discovered.lockFiles.text);
|
|
140
|
+
|
|
141
|
+
for (const _ of discovered.lockFiles.text) {
|
|
142
|
+
const id = randomId();
|
|
143
|
+
localObjects.set(id, async (id: string) => {
|
|
144
|
+
const sourceFile: SourceFile = (await generator.next()).value;
|
|
145
|
+
return produce(sourceFile, (draft) => {
|
|
146
|
+
draft.id = id;
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
resultItems.push({
|
|
150
|
+
id,
|
|
151
|
+
sourceFileType: "org.openrewrite.text.PlainText" // break cycle
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Parse JavaScript/TypeScript source files
|
|
157
|
+
if (discovered.jsFiles.length > 0) {
|
|
158
|
+
const parser = Parsers.createParser("javascript", {
|
|
159
|
+
ctx,
|
|
160
|
+
relativeTo: projectPath
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Check if Prettier is available
|
|
164
|
+
const detection = await prettierLoader.detectPrettier();
|
|
165
|
+
|
|
166
|
+
if (detection.available) {
|
|
167
|
+
// Prettier is available: add per-file PrettierStyle markers
|
|
168
|
+
const generator = parser.parse(...discovered.jsFiles);
|
|
169
|
+
|
|
170
|
+
for (const filePath of discovered.jsFiles) {
|
|
171
|
+
const id = randomId();
|
|
172
|
+
localObjects.set(id, async (id: string) => {
|
|
173
|
+
const sourceFile: SourceFile = (await generator.next()).value;
|
|
174
|
+
// Add PrettierStyle marker if Prettier is available
|
|
175
|
+
const prettierMarker = await prettierLoader.getConfigMarker(filePath);
|
|
176
|
+
return produce(sourceFile, (draft) => {
|
|
177
|
+
draft.id = id;
|
|
178
|
+
if (prettierMarker) {
|
|
179
|
+
draft.markers.markers = draft.markers.markers.concat([prettierMarker]);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
resultItems.push({
|
|
184
|
+
id,
|
|
185
|
+
sourceFileType: "org.openrewrite.javascript.tree.JS$CompilationUnit" // break cycle
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
// Prettier is NOT available: auto-detect styles from parsed files
|
|
190
|
+
// Parse all files first to sample them
|
|
191
|
+
const parsedFiles: {id: string, sourceFile: SourceFile}[] = [];
|
|
192
|
+
for await (const sourceFile of parser.parse(...discovered.jsFiles)) {
|
|
193
|
+
const id = randomId();
|
|
194
|
+
parsedFiles.push({id, sourceFile});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Sample all parsed files and build Autodetect marker using ProjectParser helper
|
|
198
|
+
const autodetectMarker = await projectParser.buildAutodetectMarker(
|
|
199
|
+
parsedFiles.map(p => p.sourceFile)
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
// Store thunks that add the Autodetect marker
|
|
203
|
+
for (const {id, sourceFile} of parsedFiles) {
|
|
204
|
+
localObjects.set(id, async (newId: string) => {
|
|
205
|
+
return produce(sourceFile, (draft) => {
|
|
206
|
+
draft.id = newId;
|
|
207
|
+
draft.markers.markers = draft.markers.markers.concat([autodetectMarker]);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
resultItems.push({
|
|
211
|
+
id,
|
|
212
|
+
sourceFileType: "org.openrewrite.javascript.tree.JS$CompilationUnit" // break cycle
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Parse other YAML files
|
|
219
|
+
if (discovered.yamlFiles.length > 0) {
|
|
220
|
+
const parser = Parsers.createParser("yaml", {ctx, relativeTo: projectPath});
|
|
221
|
+
const generator = parser.parse(...discovered.yamlFiles);
|
|
222
|
+
|
|
223
|
+
for (const _ of discovered.yamlFiles) {
|
|
224
|
+
const id = randomId();
|
|
225
|
+
localObjects.set(id, async (id: string) => {
|
|
226
|
+
const sourceFile: SourceFile = (await generator.next()).value;
|
|
227
|
+
return produce(sourceFile, (draft) => {
|
|
228
|
+
draft.id = id;
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
resultItems.push({
|
|
232
|
+
id,
|
|
233
|
+
sourceFileType: "org.openrewrite.yaml.tree.Yaml$Documents" // break cycle
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Parse other JSON files
|
|
239
|
+
if (discovered.jsonFiles.length > 0) {
|
|
240
|
+
const parser = Parsers.createParser("json", {ctx, relativeTo: projectPath});
|
|
241
|
+
const generator = parser.parse(...discovered.jsonFiles);
|
|
242
|
+
|
|
243
|
+
for (const _ of discovered.jsonFiles) {
|
|
244
|
+
const id = randomId();
|
|
245
|
+
localObjects.set(id, async (id: string) => {
|
|
246
|
+
const sourceFile: SourceFile = (await generator.next()).value;
|
|
247
|
+
return produce(sourceFile, (draft) => {
|
|
248
|
+
draft.id = id;
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
resultItems.push({
|
|
252
|
+
id,
|
|
253
|
+
sourceFileType: "org.openrewrite.json.tree.Json$Document" // break cycle
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Parse text config files (.prettierignore, .gitignore, etc.)
|
|
259
|
+
if (discovered.textFiles.length > 0) {
|
|
260
|
+
const parser = Parsers.createParser("plainText", {ctx, relativeTo: projectPath});
|
|
261
|
+
const generator = parser.parse(...discovered.textFiles);
|
|
262
|
+
|
|
263
|
+
for (const _ of discovered.textFiles) {
|
|
264
|
+
const id = randomId();
|
|
265
|
+
localObjects.set(id, async (id: string) => {
|
|
266
|
+
const sourceFile: SourceFile = (await generator.next()).value;
|
|
267
|
+
return produce(sourceFile, (draft) => {
|
|
268
|
+
draft.id = id;
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
resultItems.push({
|
|
272
|
+
id,
|
|
273
|
+
sourceFileType: "org.openrewrite.text.PlainText" // break cycle
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return resultItems;
|
|
279
|
+
}
|
|
280
|
+
)
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
}
|
package/src/rpc/rewrite-rpc.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
GetObject,
|
|
25
25
|
GetRecipes,
|
|
26
26
|
Parse,
|
|
27
|
+
ParseProject,
|
|
27
28
|
PrepareRecipe,
|
|
28
29
|
PrepareRecipeResponse,
|
|
29
30
|
Print,
|
|
@@ -90,6 +91,7 @@ export class RewriteRpc {
|
|
|
90
91
|
GetLanguages.handle(this.connection, options.metricsCsv);
|
|
91
92
|
PrepareRecipe.handle(this.connection, registry, preparedRecipes, options.metricsCsv);
|
|
92
93
|
Parse.handle(this.connection, this.localObjects, options.metricsCsv);
|
|
94
|
+
ParseProject.handle(this.connection, this.localObjects, options.metricsCsv);
|
|
93
95
|
Print.handle(this.connection, getObject, options.logger, options.metricsCsv);
|
|
94
96
|
InstallRecipes.handle(this.connection, options.recipeInstallDir ?? ".rewrite", registry, options.logger, options.metricsCsv);
|
|
95
97
|
|
package/src/text/parser.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {Parser, ParserInput, readSourceSync} from "../parser";
|
|
16
|
+
import {Parser, ParserInput, readSourceSync, Parsers} from "../parser";
|
|
17
17
|
import {PlainText} from "./tree";
|
|
18
18
|
import {randomId} from "../uuid";
|
|
19
19
|
import {emptyMarkers} from "../markers";
|
|
@@ -32,3 +32,5 @@ export class PlainTextParser extends Parser {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
|
|
36
|
+
Parsers.registerParser("plainText", PlainTextParser);
|
package/src/yaml/parser.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import {emptyMarkers, markers, MarkersKind, ParseExceptionResult} from "../markers";
|
|
17
|
-
import {Parser, ParserInput, parserInputRead} from "../parser";
|
|
17
|
+
import {Parser, ParserInput, parserInputRead, Parsers} from "../parser";
|
|
18
18
|
import {randomId} from "../uuid";
|
|
19
19
|
import {SourceFile} from "../tree";
|
|
20
20
|
import {Yaml} from "./tree";
|
|
@@ -389,15 +389,49 @@ class YamlCstReader {
|
|
|
389
389
|
|
|
390
390
|
private convertSequenceEntry(item: CstCollectionItem, dash: boolean, pendingPrefix: string = ""): {entry: Yaml.SequenceEntry, trailingContent: string} {
|
|
391
391
|
// Build prefix from start tokens, but exclude the dash indicator itself
|
|
392
|
+
// Also extract anchor and tag if present
|
|
392
393
|
let prefix = pendingPrefix;
|
|
393
394
|
let afterDashSpace = "";
|
|
394
395
|
let seenDash = false;
|
|
396
|
+
let anchorForValue: Yaml.Anchor | undefined;
|
|
397
|
+
let tagForValue: Yaml.Tag | undefined;
|
|
395
398
|
|
|
396
|
-
|
|
399
|
+
const startTokens = item.start || [];
|
|
400
|
+
for (let i = 0; i < startTokens.length; i++) {
|
|
401
|
+
const token = startTokens[i];
|
|
397
402
|
if (token.type === 'seq-item-ind') {
|
|
398
403
|
seenDash = true;
|
|
399
404
|
} else if (seenDash) {
|
|
400
|
-
|
|
405
|
+
if (token.type === 'anchor') {
|
|
406
|
+
// Collect all remaining tokens after anchor as postfix
|
|
407
|
+
let postfix = "";
|
|
408
|
+
for (let j = i + 1; j < startTokens.length; j++) {
|
|
409
|
+
const nextToken = startTokens[j];
|
|
410
|
+
if (nextToken.type === 'tag') {
|
|
411
|
+
tagForValue = this.parseTagTokenWithSuffix(nextToken.source, postfix, startTokens, j + 1);
|
|
412
|
+
postfix = "";
|
|
413
|
+
break;
|
|
414
|
+
} else {
|
|
415
|
+
postfix += nextToken.source;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
anchorForValue = {
|
|
419
|
+
kind: Yaml.Kind.Anchor,
|
|
420
|
+
id: randomId(),
|
|
421
|
+
prefix: afterDashSpace,
|
|
422
|
+
markers: emptyMarkers,
|
|
423
|
+
postfix,
|
|
424
|
+
key: token.source.substring(1) // Remove &
|
|
425
|
+
};
|
|
426
|
+
afterDashSpace = "";
|
|
427
|
+
break; // We've consumed all remaining tokens
|
|
428
|
+
} else if (token.type === 'tag') {
|
|
429
|
+
tagForValue = this.parseTagTokenWithSuffix(token.source, afterDashSpace, startTokens, i + 1);
|
|
430
|
+
afterDashSpace = "";
|
|
431
|
+
break; // Tag handler consumed remaining tokens
|
|
432
|
+
} else {
|
|
433
|
+
afterDashSpace += token.source;
|
|
434
|
+
}
|
|
401
435
|
} else {
|
|
402
436
|
prefix += token.source;
|
|
403
437
|
}
|
|
@@ -410,8 +444,20 @@ class YamlCstReader {
|
|
|
410
444
|
const valueResult = this.convertTokenWithTrailing(item.value);
|
|
411
445
|
block = valueResult.node as Yaml.Block;
|
|
412
446
|
trailing = valueResult.trailing;
|
|
413
|
-
|
|
414
|
-
|
|
447
|
+
|
|
448
|
+
// Apply anchor and tag if found in start tokens
|
|
449
|
+
if (anchorForValue && 'anchor' in block) {
|
|
450
|
+
block = {...block, anchor: anchorForValue} as Yaml.Block;
|
|
451
|
+
}
|
|
452
|
+
if (tagForValue && 'tag' in block) {
|
|
453
|
+
block = {...block, tag: tagForValue} as Yaml.Block;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Prepend the space after dash to the block
|
|
457
|
+
// Use prependWhitespaceToValue to ensure Mapping/Sequence keep empty prefix
|
|
458
|
+
if (afterDashSpace) {
|
|
459
|
+
block = this.prependWhitespaceToValue(block, afterDashSpace);
|
|
460
|
+
}
|
|
415
461
|
} else {
|
|
416
462
|
block = this.createEmptyScalar(afterDashSpace);
|
|
417
463
|
}
|
|
@@ -848,3 +894,5 @@ class YamlCstReader {
|
|
|
848
894
|
return tokens.map(t => t.source).join('');
|
|
849
895
|
}
|
|
850
896
|
}
|
|
897
|
+
|
|
898
|
+
Parsers.registerParser("yaml", YamlParser);
|