@openrewrite/rewrite 8.69.0-20251207-184829 → 8.69.0-20251207-214914
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.map +1 -1
- package/dist/cli/cli-utils.js +3 -2
- package/dist/cli/cli-utils.js.map +1 -1
- package/dist/cli/rewrite.js +2 -1
- package/dist/cli/rewrite.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/javascript/parser.d.ts.map +1 -1
- package/dist/javascript/parser.js +48 -8
- package/dist/javascript/parser.js.map +1 -1
- package/dist/javascript/recipes/change-import.d.ts +51 -0
- package/dist/javascript/recipes/change-import.d.ts.map +1 -0
- package/dist/javascript/recipes/change-import.js +658 -0
- package/dist/javascript/recipes/change-import.js.map +1 -0
- package/dist/javascript/recipes/index.d.ts +2 -0
- package/dist/javascript/recipes/index.d.ts.map +1 -1
- package/dist/javascript/recipes/index.js +2 -0
- package/dist/javascript/recipes/index.js.map +1 -1
- package/dist/javascript/recipes/order-imports.d.ts +10 -0
- package/dist/javascript/recipes/order-imports.d.ts.map +1 -0
- package/dist/javascript/recipes/order-imports.js +240 -0
- package/dist/javascript/recipes/order-imports.js.map +1 -0
- package/dist/json/parser.js +78 -30
- package/dist/json/parser.js.map +1 -1
- package/dist/version.txt +1 -1
- package/package.json +1 -1
- package/src/cli/cli-utils.ts +3 -2
- package/src/cli/rewrite.ts +2 -1
- package/src/index.ts +2 -2
- package/src/javascript/parser.ts +49 -8
- package/src/javascript/recipes/change-import.ts +700 -0
- package/src/javascript/recipes/index.ts +2 -0
- package/src/javascript/recipes/order-imports.ts +242 -0
- package/src/json/parser.ts +69 -24
- package/dist/recipe/index.d.ts +0 -2
- package/dist/recipe/index.d.ts.map +0 -1
- package/dist/recipe/index.js +0 -21
- package/dist/recipe/index.js.map +0 -1
- package/dist/recipe/order-imports.d.ts +0 -10
- package/dist/recipe/order-imports.d.ts.map +0 -1
- package/dist/recipe/order-imports.js +0 -213
- package/dist/recipe/order-imports.js.map +0 -1
- package/src/recipe/index.ts +0 -17
- package/src/recipe/order-imports.ts +0 -195
package/src/recipe/index.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
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
|
-
|
|
17
|
-
export {OrderImports} from "./order-imports";
|
|
@@ -1,195 +0,0 @@
|
|
|
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
|
-
|
|
17
|
-
import {Recipe} from "../recipe";
|
|
18
|
-
import {produceAsync, TreeVisitor} from "../visitor";
|
|
19
|
-
import {ExecutionContext} from "../execution";
|
|
20
|
-
import {JavaScriptVisitor, JS} from "../javascript";
|
|
21
|
-
import {J} from "../java";
|
|
22
|
-
import {Draft, produce} from "immer";
|
|
23
|
-
import {AutoformatVisitor} from "../javascript/format";
|
|
24
|
-
|
|
25
|
-
export class OrderImports extends Recipe {
|
|
26
|
-
name = "org.openrewrite.OrderImports";
|
|
27
|
-
displayName = "Order imports";
|
|
28
|
-
description = "Sort top-level imports alphabetically within groups: no qualifier, asterisk, multiple, single.";
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
async editor(): Promise<TreeVisitor<any, ExecutionContext>> {
|
|
32
|
-
return new class extends JavaScriptVisitor<ExecutionContext> {
|
|
33
|
-
|
|
34
|
-
protected async visitJsCompilationUnit(cu: JS.CompilationUnit, p: ExecutionContext): Promise<J | undefined> {
|
|
35
|
-
const importCount = this.countImports(cu);
|
|
36
|
-
const imports = cu.statements.slice(0, importCount) as J.RightPadded<JS.Import>[];
|
|
37
|
-
const originalImportPosition = Object.fromEntries(imports.map((item, i) => [item.element.id, i]));
|
|
38
|
-
const restStatements = cu.statements.slice(importCount);
|
|
39
|
-
const sortedImports = await this.sortNamesWithinEachLine(imports);
|
|
40
|
-
sortedImports.sort((aPadded, bPadded) => {
|
|
41
|
-
const a = aPadded.element;
|
|
42
|
-
const b = bPadded.element;
|
|
43
|
-
|
|
44
|
-
const noSpecifier = (a.importClause == undefined ? 1 : 0) - (b.importClause == undefined ? 1 : 0);
|
|
45
|
-
if (noSpecifier != 0) {
|
|
46
|
-
return -noSpecifier;
|
|
47
|
-
}
|
|
48
|
-
const asterisk = this.isAsteriskImport(a) - this.isAsteriskImport(b);
|
|
49
|
-
if (asterisk != 0) {
|
|
50
|
-
return -asterisk;
|
|
51
|
-
}
|
|
52
|
-
const multipleImport = this.isMultipleImport(a) - this.isMultipleImport(b);
|
|
53
|
-
if (multipleImport != 0) {
|
|
54
|
-
return -multipleImport;
|
|
55
|
-
}
|
|
56
|
-
const comparedSpecifiers = this.compareStringArrays(this.extractImportSpecifierNames(a), this.extractImportSpecifierNames(b));
|
|
57
|
-
if (comparedSpecifiers != 0) {
|
|
58
|
-
return comparedSpecifiers;
|
|
59
|
-
}
|
|
60
|
-
// Tiebreaker, keep the sort stable
|
|
61
|
-
return originalImportPosition[aPadded.element.id] - originalImportPosition[bPadded.element.id];
|
|
62
|
-
});
|
|
63
|
-
const cuWithImportsSorted = await produceAsync(cu, async draft => {
|
|
64
|
-
draft.statements = [...sortedImports, ...restStatements];
|
|
65
|
-
});
|
|
66
|
-
return produce(cuWithImportsSorted!, draft => {
|
|
67
|
-
for (let i = 0; i < importCount; i++) {
|
|
68
|
-
draft.statements[i].element.prefix.whitespace = i > 0 ? "\n" : "";
|
|
69
|
-
}
|
|
70
|
-
// TODO deal with comments in the whitespace around imports
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
private isAsteriskImport(import_: JS.Import): 0 | 1 {
|
|
75
|
-
if (import_.importClause != undefined) {
|
|
76
|
-
if (import_.importClause.namedBindings != undefined) {
|
|
77
|
-
if (import_.importClause.namedBindings.kind == JS.Kind.Alias) {
|
|
78
|
-
return (import_.importClause.namedBindings as JS.Alias).propertyName.element.simpleName == "*" ? 1 : 0;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return 0;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private isMultipleImport(import_: JS.Import): 0 | 1 {
|
|
86
|
-
if (import_.importClause != undefined) {
|
|
87
|
-
if (import_.importClause.namedBindings != undefined) {
|
|
88
|
-
if (import_.importClause.namedBindings.kind == JS.Kind.NamedImports) {
|
|
89
|
-
const namedImports = import_.importClause.namedBindings as JS.NamedImports;
|
|
90
|
-
if (namedImports.elements.kind == J.Kind.Container) {
|
|
91
|
-
return namedImports.elements.elements.length > 1 ? 1 : 0;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return 0;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private extractImportSpecifierNames(import_: JS.Import): string[] {
|
|
100
|
-
const names: string[] = [];
|
|
101
|
-
if (import_.importClause != undefined) {
|
|
102
|
-
if (import_.importClause.namedBindings != undefined) {
|
|
103
|
-
if (import_.importClause.namedBindings.kind == JS.Kind.NamedImports) {
|
|
104
|
-
const namedImports = import_.importClause.namedBindings as JS.NamedImports;
|
|
105
|
-
if (namedImports.elements.kind == J.Kind.Container) {
|
|
106
|
-
const elements = namedImports.elements.elements;
|
|
107
|
-
for (let i = 0; i < elements.length; i++) {
|
|
108
|
-
const importSpecifier = elements[i].element as JS.ImportSpecifier;
|
|
109
|
-
if (importSpecifier.specifier.kind == J.Kind.Identifier) {
|
|
110
|
-
names.push((importSpecifier.specifier as J.Identifier).simpleName);
|
|
111
|
-
} else if (importSpecifier.specifier.kind == JS.Kind.Alias) {
|
|
112
|
-
names.push((importSpecifier.specifier as JS.Alias).propertyName.element.simpleName);
|
|
113
|
-
} else {
|
|
114
|
-
throw new Error("Unknown kind " + elements[i].kind);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
} else if (import_.importClause.namedBindings.kind == JS.Kind.Alias) {
|
|
119
|
-
const alias = import_.importClause.namedBindings as JS.Alias;
|
|
120
|
-
names.push(alias.propertyName.element.simpleName);
|
|
121
|
-
if (alias.alias.kind == J.Kind.Identifier) {
|
|
122
|
-
names.push((alias.alias as J.Identifier).simpleName)
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return names;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
private compareStringArrays(a: string[], b: string[]): number {
|
|
131
|
-
let i = 0;
|
|
132
|
-
while (i < a.length && i < b.length) {
|
|
133
|
-
const comparison = a[i].localeCompare(b[i]);
|
|
134
|
-
if (comparison !== 0) {
|
|
135
|
-
return comparison;
|
|
136
|
-
}
|
|
137
|
-
i++;
|
|
138
|
-
}
|
|
139
|
-
if (i < a.length) {
|
|
140
|
-
return 1;
|
|
141
|
-
} else if (i < b.length) {
|
|
142
|
-
return -1;
|
|
143
|
-
}
|
|
144
|
-
return 0;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
private countImports(cu: JS.CompilationUnit): number {
|
|
148
|
-
let i = 0;
|
|
149
|
-
while ((i < cu.statements.length) && (cu.statements[i].element.kind === JS.Kind.Import)) {
|
|
150
|
-
i++;
|
|
151
|
-
}
|
|
152
|
-
return i;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
private async sortNamesWithinEachLine(imports: J.RightPadded<JS.Import>[]): Promise<J.RightPadded<JS.Import>[]> {
|
|
156
|
-
const ret = [];
|
|
157
|
-
for (const importPadded of imports) {
|
|
158
|
-
const import_ = importPadded.element;
|
|
159
|
-
if (this.isMultipleImport(import_) == 1) {
|
|
160
|
-
const importSorted = produce(import_, draft => {
|
|
161
|
-
let elements = (draft.importClause!.namedBindings as Draft<JS.NamedImports>).elements.elements;
|
|
162
|
-
const trailingComma = elements.length > 0 && elements[elements.length - 1].markers?.markers.find(m => m.kind === J.Markers.TrailingComma);
|
|
163
|
-
if (trailingComma) {
|
|
164
|
-
elements[elements.length - 1].markers.markers = elements[elements.length - 1].markers.markers.filter(m => m.kind !== J.Markers.TrailingComma);
|
|
165
|
-
}
|
|
166
|
-
elements.sort((a, b) => {
|
|
167
|
-
const namesExtracted: string[] = [a.element, b.element].map(expr => {
|
|
168
|
-
const is = expr as JS.ImportSpecifier;
|
|
169
|
-
if (is.specifier.kind == JS.Kind.Alias) {
|
|
170
|
-
return (is.specifier as JS.Alias).propertyName.element.simpleName;
|
|
171
|
-
} else if (is.specifier.kind == J.Kind.Identifier) {
|
|
172
|
-
return (is.specifier as J.Identifier).simpleName;
|
|
173
|
-
} else {
|
|
174
|
-
throw new Error("Unsupported kind " + expr.kind);
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
return namesExtracted[0].localeCompare(namesExtracted[1]);
|
|
178
|
-
});
|
|
179
|
-
if (trailingComma && elements.length > 0 && !elements[elements.length - 1].markers.markers.find(m => m.kind === J.Markers.TrailingComma)) {
|
|
180
|
-
elements[elements.length - 1].markers.markers.push(trailingComma);
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
const formatted = await new AutoformatVisitor().visit(importSorted, {}) as JS.Import;
|
|
184
|
-
ret.push(produce(importPadded, draft => {
|
|
185
|
-
draft.element = formatted;
|
|
186
|
-
}));
|
|
187
|
-
} else {
|
|
188
|
-
ret.push(importPadded);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return ret;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|