@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
|
@@ -0,0 +1,242 @@
|
|
|
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 "../index";
|
|
21
|
+
import {J} from "../../java";
|
|
22
|
+
import {Draft, produce} from "immer";
|
|
23
|
+
import {SpacesStyle, styleFromSourceFile, StyleKind} from "../style";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Import type categories for sorting order:
|
|
27
|
+
* 1. Side-effect imports (no specifier): import 'module';
|
|
28
|
+
* 2. Namespace imports: import * as foo from 'module';
|
|
29
|
+
* 3. Default imports: import foo from 'module';
|
|
30
|
+
* 4. Named imports: import { foo } from 'module';
|
|
31
|
+
* 5. Type imports: import type { Foo } from 'module';
|
|
32
|
+
*/
|
|
33
|
+
enum ImportCategory {
|
|
34
|
+
SideEffect = 0,
|
|
35
|
+
Namespace = 1,
|
|
36
|
+
Default = 2,
|
|
37
|
+
Named = 3,
|
|
38
|
+
Type = 4
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class OrderImports extends Recipe {
|
|
42
|
+
readonly name = "org.openrewrite.javascript.cleanup.order-imports";
|
|
43
|
+
readonly displayName = "Order imports";
|
|
44
|
+
readonly description = "Sort imports by category and module path. Categories: side-effect, namespace, default, named, type. Within each category, imports are sorted alphabetically by module path. Named specifiers within each import are also sorted alphabetically.";
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async editor(): Promise<TreeVisitor<any, ExecutionContext>> {
|
|
48
|
+
return new class extends JavaScriptVisitor<ExecutionContext> {
|
|
49
|
+
|
|
50
|
+
protected async visitJsCompilationUnit(cu: JS.CompilationUnit, p: ExecutionContext): Promise<J | undefined> {
|
|
51
|
+
const importCount = this.countImports(cu);
|
|
52
|
+
if (importCount === 0) {
|
|
53
|
+
return cu;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const imports = cu.statements.slice(0, importCount) as J.RightPadded<JS.Import>[];
|
|
57
|
+
const originalImportPosition = Object.fromEntries(imports.map((item, i) => [item.element.id, i]));
|
|
58
|
+
const restStatements = cu.statements.slice(importCount);
|
|
59
|
+
|
|
60
|
+
// Get style for consistent brace spacing
|
|
61
|
+
const spacesStyle = styleFromSourceFile(StyleKind.SpacesStyle, cu) as SpacesStyle | undefined;
|
|
62
|
+
const useBraceSpaces = spacesStyle?.within.es6ImportExportBraces ?? false;
|
|
63
|
+
|
|
64
|
+
// Sort named specifiers within each import
|
|
65
|
+
const sortedSpecifiers = this.sortNamedSpecifiersWithinImports(imports, useBraceSpaces);
|
|
66
|
+
|
|
67
|
+
// Sort imports by category and module path
|
|
68
|
+
sortedSpecifiers.sort((aPadded, bPadded) => {
|
|
69
|
+
const a = aPadded.element;
|
|
70
|
+
const b = bPadded.element;
|
|
71
|
+
|
|
72
|
+
// First, compare by category
|
|
73
|
+
const categoryA = this.getImportCategory(a);
|
|
74
|
+
const categoryB = this.getImportCategory(b);
|
|
75
|
+
if (categoryA !== categoryB) {
|
|
76
|
+
return categoryA - categoryB;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Within same category, sort by module path (case-insensitive)
|
|
80
|
+
const modulePathA = this.getModulePath(a).toLowerCase();
|
|
81
|
+
const modulePathB = this.getModulePath(b).toLowerCase();
|
|
82
|
+
const pathComparison = modulePathA.localeCompare(modulePathB);
|
|
83
|
+
if (pathComparison !== 0) {
|
|
84
|
+
return pathComparison;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Tiebreaker: keep original order for stability
|
|
88
|
+
return originalImportPosition[aPadded.element.id] - originalImportPosition[bPadded.element.id];
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const cuWithImportsSorted = await produceAsync(cu, async draft => {
|
|
92
|
+
draft.statements = [...sortedSpecifiers, ...restStatements];
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return produce(cuWithImportsSorted!, draft => {
|
|
96
|
+
for (let i = 0; i < importCount; i++) {
|
|
97
|
+
draft.statements[i].element.prefix.whitespace = i > 0 ? "\n" : "";
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Determine the category of an import for sorting purposes.
|
|
104
|
+
*/
|
|
105
|
+
private getImportCategory(import_: JS.Import): ImportCategory {
|
|
106
|
+
// Type imports: import type { Foo } from 'module'
|
|
107
|
+
if (import_.importClause?.typeOnly) {
|
|
108
|
+
return ImportCategory.Type;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Side-effect imports: import 'module'
|
|
112
|
+
if (import_.importClause === undefined) {
|
|
113
|
+
return ImportCategory.SideEffect;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Namespace imports: import * as foo from 'module'
|
|
117
|
+
if (import_.importClause.namedBindings?.kind === JS.Kind.Alias) {
|
|
118
|
+
const alias = import_.importClause.namedBindings as JS.Alias;
|
|
119
|
+
if (alias.propertyName.element.simpleName === "*") {
|
|
120
|
+
return ImportCategory.Namespace;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Default imports (without named imports): import foo from 'module'
|
|
125
|
+
if (import_.importClause.name && !import_.importClause.namedBindings) {
|
|
126
|
+
return ImportCategory.Default;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Default with named imports or just named imports: import foo, { bar } from 'module' or import { foo } from 'module'
|
|
130
|
+
return ImportCategory.Named;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Extract the module path from an import statement.
|
|
135
|
+
*/
|
|
136
|
+
private getModulePath(import_: JS.Import): string {
|
|
137
|
+
if (import_.moduleSpecifier?.element.kind === J.Kind.Literal) {
|
|
138
|
+
const literal = import_.moduleSpecifier.element as J.Literal;
|
|
139
|
+
// Remove quotes from the value
|
|
140
|
+
return String(literal.value ?? '');
|
|
141
|
+
}
|
|
142
|
+
return '';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private countImports(cu: JS.CompilationUnit): number {
|
|
146
|
+
let i = 0;
|
|
147
|
+
while ((i < cu.statements.length) && (cu.statements[i].element.kind === JS.Kind.Import)) {
|
|
148
|
+
i++;
|
|
149
|
+
}
|
|
150
|
+
return i;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Sort named specifiers within each import statement alphabetically.
|
|
155
|
+
*/
|
|
156
|
+
private sortNamedSpecifiersWithinImports(imports: J.RightPadded<JS.Import>[], useBraceSpaces: boolean): J.RightPadded<JS.Import>[] {
|
|
157
|
+
const ret = [];
|
|
158
|
+
for (const importPadded of imports) {
|
|
159
|
+
const import_ = importPadded.element;
|
|
160
|
+
if (this.hasNamedImports(import_)) {
|
|
161
|
+
const importSorted = produce(import_, draft => {
|
|
162
|
+
const namedBindings = draft.importClause!.namedBindings as Draft<JS.NamedImports>;
|
|
163
|
+
let elements = namedBindings.elements.elements;
|
|
164
|
+
|
|
165
|
+
if (elements.length <= 1) {
|
|
166
|
+
return; // Nothing to sort
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Handle trailing comma
|
|
170
|
+
const trailingComma = elements.length > 0 &&
|
|
171
|
+
elements[elements.length - 1].markers?.markers.find(m => m.kind === J.Markers.TrailingComma);
|
|
172
|
+
if (trailingComma) {
|
|
173
|
+
elements[elements.length - 1].markers.markers =
|
|
174
|
+
elements[elements.length - 1].markers.markers.filter(m => m.kind !== J.Markers.TrailingComma);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Sort by the imported name (not alias)
|
|
178
|
+
elements.sort((a, b) => {
|
|
179
|
+
const nameA = this.getSpecifierSortKey(a.element as JS.ImportSpecifier);
|
|
180
|
+
const nameB = this.getSpecifierSortKey(b.element as JS.ImportSpecifier);
|
|
181
|
+
return nameA.localeCompare(nameB);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Normalize spacing based on es6ImportExportBraces style
|
|
185
|
+
const braceSpace = useBraceSpaces ? " " : "";
|
|
186
|
+
for (let i = 0; i < elements.length; i++) {
|
|
187
|
+
if (i === 0) {
|
|
188
|
+
// First element: space after opening brace based on style
|
|
189
|
+
elements[i].element.prefix = {kind: J.Kind.Space, whitespace: braceSpace, comments: []};
|
|
190
|
+
} else {
|
|
191
|
+
// Other elements: space after comma
|
|
192
|
+
elements[i].element.prefix = {kind: J.Kind.Space, whitespace: ' ', comments: []};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Last element: space before closing brace based on style
|
|
196
|
+
elements[elements.length - 1].after = {kind: J.Kind.Space, whitespace: braceSpace, comments: []};
|
|
197
|
+
|
|
198
|
+
// Restore trailing comma to last element
|
|
199
|
+
if (trailingComma && elements.length > 0 &&
|
|
200
|
+
!elements[elements.length - 1].markers.markers.find(m => m.kind === J.Markers.TrailingComma)) {
|
|
201
|
+
elements[elements.length - 1].markers.markers.push(trailingComma);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
ret.push(produce(importPadded, draft => {
|
|
206
|
+
draft.element = importSorted;
|
|
207
|
+
}));
|
|
208
|
+
} else {
|
|
209
|
+
ret.push(importPadded);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return ret;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Check if an import has named imports that can be sorted.
|
|
217
|
+
*/
|
|
218
|
+
private hasNamedImports(import_: JS.Import): boolean {
|
|
219
|
+
if (import_.importClause?.namedBindings?.kind === JS.Kind.NamedImports) {
|
|
220
|
+
const namedImports = import_.importClause.namedBindings as JS.NamedImports;
|
|
221
|
+
return namedImports.elements.kind === J.Kind.Container &&
|
|
222
|
+
namedImports.elements.elements.length > 1;
|
|
223
|
+
}
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Get the sort key for an import specifier (the original name, not alias).
|
|
229
|
+
*/
|
|
230
|
+
private getSpecifierSortKey(specifier: JS.ImportSpecifier): string {
|
|
231
|
+
if (specifier.specifier.kind === JS.Kind.Alias) {
|
|
232
|
+
// import { foo as bar } - sort by 'foo'
|
|
233
|
+
return (specifier.specifier as JS.Alias).propertyName.element.simpleName;
|
|
234
|
+
} else if (specifier.specifier.kind === J.Kind.Identifier) {
|
|
235
|
+
// import { foo } - sort by 'foo'
|
|
236
|
+
return (specifier.specifier as J.Identifier).simpleName;
|
|
237
|
+
}
|
|
238
|
+
return '';
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
package/src/json/parser.ts
CHANGED
|
@@ -79,21 +79,38 @@ class ParseJsonReader extends ParserSourceReader {
|
|
|
79
79
|
}
|
|
80
80
|
if (Array.isArray(parsed)) {
|
|
81
81
|
this.cursor++; // skip '['
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
let values: Json.RightPadded<Json.Value>[];
|
|
83
|
+
if (parsed.length === 0) {
|
|
84
|
+
// Empty array - capture whitespace in an Empty element
|
|
84
85
|
const afterWhitespace = this.whitespace();
|
|
85
|
-
|
|
86
|
-
const hasComma = this.source[this.cursor] === ',';
|
|
87
|
-
if (hasComma) {
|
|
88
|
-
this.cursor++; // skip ','
|
|
89
|
-
}
|
|
90
|
-
return {
|
|
86
|
+
values = [{
|
|
91
87
|
kind: Json.Kind.RightPadded,
|
|
92
|
-
element
|
|
88
|
+
element: {
|
|
89
|
+
kind: Json.Kind.Empty,
|
|
90
|
+
id: randomId(),
|
|
91
|
+
prefix: emptySpace,
|
|
92
|
+
markers: emptyMarkers
|
|
93
|
+
} satisfies Json.Empty as Json.Empty,
|
|
93
94
|
after: space(afterWhitespace),
|
|
94
95
|
markers: emptyMarkers
|
|
95
|
-
} satisfies Json.RightPadded<Json.Value> as Json.RightPadded<Json.Value
|
|
96
|
-
}
|
|
96
|
+
} satisfies Json.RightPadded<Json.Value> as Json.RightPadded<Json.Value>];
|
|
97
|
+
} else {
|
|
98
|
+
values = parsed.map((p, i) => {
|
|
99
|
+
const element = this.json(p) as Json.Value;
|
|
100
|
+
const afterWhitespace = this.whitespace();
|
|
101
|
+
// Check if there's a comma after this element
|
|
102
|
+
const hasComma = this.source[this.cursor] === ',';
|
|
103
|
+
if (hasComma) {
|
|
104
|
+
this.cursor++; // skip ','
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
kind: Json.Kind.RightPadded,
|
|
108
|
+
element,
|
|
109
|
+
after: space(afterWhitespace),
|
|
110
|
+
markers: emptyMarkers
|
|
111
|
+
} satisfies Json.RightPadded<Json.Value> as Json.RightPadded<Json.Value>;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
97
114
|
this.cursor++; // skip ']'
|
|
98
115
|
return {
|
|
99
116
|
kind: Json.Kind.Array,
|
|
@@ -103,21 +120,38 @@ class ParseJsonReader extends ParserSourceReader {
|
|
|
103
120
|
} else if (parsed !== null && typeof parsed === "object") {
|
|
104
121
|
this.cursor++; // skip '{'
|
|
105
122
|
const keys = Object.keys(parsed);
|
|
106
|
-
|
|
107
|
-
|
|
123
|
+
let members: Json.RightPadded<Json.Member>[];
|
|
124
|
+
if (keys.length === 0) {
|
|
125
|
+
// Empty object - capture whitespace in an Empty element
|
|
108
126
|
const afterWhitespace = this.whitespace();
|
|
109
|
-
|
|
110
|
-
const hasComma = this.source[this.cursor] === ',';
|
|
111
|
-
if (hasComma) {
|
|
112
|
-
this.cursor++; // skip ','
|
|
113
|
-
}
|
|
114
|
-
return {
|
|
127
|
+
members = [{
|
|
115
128
|
kind: Json.Kind.RightPadded,
|
|
116
|
-
element
|
|
129
|
+
element: {
|
|
130
|
+
kind: Json.Kind.Empty,
|
|
131
|
+
id: randomId(),
|
|
132
|
+
prefix: emptySpace,
|
|
133
|
+
markers: emptyMarkers
|
|
134
|
+
} satisfies Json.Empty as Json.Empty as unknown as Json.Member,
|
|
117
135
|
after: space(afterWhitespace),
|
|
118
136
|
markers: emptyMarkers
|
|
119
|
-
} satisfies Json.RightPadded<Json.Member> as Json.RightPadded<Json.Member
|
|
120
|
-
}
|
|
137
|
+
} satisfies Json.RightPadded<Json.Member> as Json.RightPadded<Json.Member>];
|
|
138
|
+
} else {
|
|
139
|
+
members = keys.map((key, i) => {
|
|
140
|
+
const element = this.member(parsed, key);
|
|
141
|
+
const afterWhitespace = this.whitespace();
|
|
142
|
+
// Check if there's a comma after this element
|
|
143
|
+
const hasComma = this.source[this.cursor] === ',';
|
|
144
|
+
if (hasComma) {
|
|
145
|
+
this.cursor++; // skip ','
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
kind: Json.Kind.RightPadded,
|
|
149
|
+
element,
|
|
150
|
+
after: space(afterWhitespace),
|
|
151
|
+
markers: emptyMarkers
|
|
152
|
+
} satisfies Json.RightPadded<Json.Member> as Json.RightPadded<Json.Member>;
|
|
153
|
+
});
|
|
154
|
+
}
|
|
121
155
|
this.cursor++; // skip '}'
|
|
122
156
|
return {
|
|
123
157
|
kind: Json.Kind.Object,
|
|
@@ -147,11 +181,22 @@ class ParseJsonReader extends ParserSourceReader {
|
|
|
147
181
|
value: parsed
|
|
148
182
|
} satisfies Json.Literal as Json.Literal;
|
|
149
183
|
} else if (typeof parsed === "number") {
|
|
150
|
-
|
|
184
|
+
// Extract original source to preserve precision for large numbers
|
|
185
|
+
const sourceStart = this.cursor;
|
|
186
|
+
// Numbers can have optional sign, digits, decimal point, and exponent
|
|
187
|
+
while (this.cursor < this.source.length) {
|
|
188
|
+
const char = this.source[this.cursor];
|
|
189
|
+
if (/[\d.eE+\-]/.test(char)) {
|
|
190
|
+
this.cursor++;
|
|
191
|
+
} else {
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const source = this.source.slice(sourceStart, this.cursor);
|
|
151
196
|
return {
|
|
152
197
|
kind: Json.Kind.Literal,
|
|
153
198
|
...base,
|
|
154
|
-
source
|
|
199
|
+
source,
|
|
155
200
|
value: parsed,
|
|
156
201
|
} satisfies Json.Literal as Json.Literal;
|
|
157
202
|
} else if (typeof parsed === "boolean") {
|
package/dist/recipe/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recipe/index.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC"}
|
package/dist/recipe/index.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2025 the original author or authors.
|
|
4
|
-
* <p>
|
|
5
|
-
* Licensed under the Moderne Source Available License (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
* <p>
|
|
9
|
-
* https://docs.moderne.io/licensing/moderne-source-available-license
|
|
10
|
-
* <p>
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.OrderImports = void 0;
|
|
19
|
-
var order_imports_1 = require("./order-imports");
|
|
20
|
-
Object.defineProperty(exports, "OrderImports", { enumerable: true, get: function () { return order_imports_1.OrderImports; } });
|
|
21
|
-
//# sourceMappingURL=index.js.map
|
package/dist/recipe/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recipe/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAEH,iDAA6C;AAArC,6GAAA,YAAY,OAAA"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Recipe } from "../recipe";
|
|
2
|
-
import { TreeVisitor } from "../visitor";
|
|
3
|
-
import { ExecutionContext } from "../execution";
|
|
4
|
-
export declare class OrderImports extends Recipe {
|
|
5
|
-
name: string;
|
|
6
|
-
displayName: string;
|
|
7
|
-
description: string;
|
|
8
|
-
editor(): Promise<TreeVisitor<any, ExecutionContext>>;
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=order-imports.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"order-imports.d.ts","sourceRoot":"","sources":["../../src/recipe/order-imports.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAC,MAAM,EAAC,MAAM,WAAW,CAAC;AACjC,OAAO,EAAe,WAAW,EAAC,MAAM,YAAY,CAAC;AACrD,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAM9C,qBAAa,YAAa,SAAQ,MAAM;IACpC,IAAI,SAAkC;IACtC,WAAW,SAAmB;IAC9B,WAAW,SAAoG;IAGzG,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;CAoK9D"}
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2025 the original author or authors.
|
|
4
|
-
* <p>
|
|
5
|
-
* Licensed under the Moderne Source Available License (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
* <p>
|
|
9
|
-
* https://docs.moderne.io/licensing/moderne-source-available-license
|
|
10
|
-
* <p>
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
20
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
21
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
22
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
23
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
-
});
|
|
25
|
-
};
|
|
26
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
exports.OrderImports = void 0;
|
|
28
|
-
const recipe_1 = require("../recipe");
|
|
29
|
-
const visitor_1 = require("../visitor");
|
|
30
|
-
const javascript_1 = require("../javascript");
|
|
31
|
-
const java_1 = require("../java");
|
|
32
|
-
const immer_1 = require("immer");
|
|
33
|
-
const format_1 = require("../javascript/format");
|
|
34
|
-
class OrderImports extends recipe_1.Recipe {
|
|
35
|
-
constructor() {
|
|
36
|
-
super(...arguments);
|
|
37
|
-
this.name = "org.openrewrite.OrderImports";
|
|
38
|
-
this.displayName = "Order imports";
|
|
39
|
-
this.description = "Sort top-level imports alphabetically within groups: no qualifier, asterisk, multiple, single.";
|
|
40
|
-
}
|
|
41
|
-
editor() {
|
|
42
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
-
return new class extends javascript_1.JavaScriptVisitor {
|
|
44
|
-
visitJsCompilationUnit(cu, p) {
|
|
45
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
-
const importCount = this.countImports(cu);
|
|
47
|
-
const imports = cu.statements.slice(0, importCount);
|
|
48
|
-
const originalImportPosition = Object.fromEntries(imports.map((item, i) => [item.element.id, i]));
|
|
49
|
-
const restStatements = cu.statements.slice(importCount);
|
|
50
|
-
const sortedImports = yield this.sortNamesWithinEachLine(imports);
|
|
51
|
-
sortedImports.sort((aPadded, bPadded) => {
|
|
52
|
-
const a = aPadded.element;
|
|
53
|
-
const b = bPadded.element;
|
|
54
|
-
const noSpecifier = (a.importClause == undefined ? 1 : 0) - (b.importClause == undefined ? 1 : 0);
|
|
55
|
-
if (noSpecifier != 0) {
|
|
56
|
-
return -noSpecifier;
|
|
57
|
-
}
|
|
58
|
-
const asterisk = this.isAsteriskImport(a) - this.isAsteriskImport(b);
|
|
59
|
-
if (asterisk != 0) {
|
|
60
|
-
return -asterisk;
|
|
61
|
-
}
|
|
62
|
-
const multipleImport = this.isMultipleImport(a) - this.isMultipleImport(b);
|
|
63
|
-
if (multipleImport != 0) {
|
|
64
|
-
return -multipleImport;
|
|
65
|
-
}
|
|
66
|
-
const comparedSpecifiers = this.compareStringArrays(this.extractImportSpecifierNames(a), this.extractImportSpecifierNames(b));
|
|
67
|
-
if (comparedSpecifiers != 0) {
|
|
68
|
-
return comparedSpecifiers;
|
|
69
|
-
}
|
|
70
|
-
// Tiebreaker, keep the sort stable
|
|
71
|
-
return originalImportPosition[aPadded.element.id] - originalImportPosition[bPadded.element.id];
|
|
72
|
-
});
|
|
73
|
-
const cuWithImportsSorted = yield (0, visitor_1.produceAsync)(cu, (draft) => __awaiter(this, void 0, void 0, function* () {
|
|
74
|
-
draft.statements = [...sortedImports, ...restStatements];
|
|
75
|
-
}));
|
|
76
|
-
return (0, immer_1.produce)(cuWithImportsSorted, draft => {
|
|
77
|
-
for (let i = 0; i < importCount; i++) {
|
|
78
|
-
draft.statements[i].element.prefix.whitespace = i > 0 ? "\n" : "";
|
|
79
|
-
}
|
|
80
|
-
// TODO deal with comments in the whitespace around imports
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
isAsteriskImport(import_) {
|
|
85
|
-
if (import_.importClause != undefined) {
|
|
86
|
-
if (import_.importClause.namedBindings != undefined) {
|
|
87
|
-
if (import_.importClause.namedBindings.kind == javascript_1.JS.Kind.Alias) {
|
|
88
|
-
return import_.importClause.namedBindings.propertyName.element.simpleName == "*" ? 1 : 0;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return 0;
|
|
93
|
-
}
|
|
94
|
-
isMultipleImport(import_) {
|
|
95
|
-
if (import_.importClause != undefined) {
|
|
96
|
-
if (import_.importClause.namedBindings != undefined) {
|
|
97
|
-
if (import_.importClause.namedBindings.kind == javascript_1.JS.Kind.NamedImports) {
|
|
98
|
-
const namedImports = import_.importClause.namedBindings;
|
|
99
|
-
if (namedImports.elements.kind == java_1.J.Kind.Container) {
|
|
100
|
-
return namedImports.elements.elements.length > 1 ? 1 : 0;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return 0;
|
|
106
|
-
}
|
|
107
|
-
extractImportSpecifierNames(import_) {
|
|
108
|
-
const names = [];
|
|
109
|
-
if (import_.importClause != undefined) {
|
|
110
|
-
if (import_.importClause.namedBindings != undefined) {
|
|
111
|
-
if (import_.importClause.namedBindings.kind == javascript_1.JS.Kind.NamedImports) {
|
|
112
|
-
const namedImports = import_.importClause.namedBindings;
|
|
113
|
-
if (namedImports.elements.kind == java_1.J.Kind.Container) {
|
|
114
|
-
const elements = namedImports.elements.elements;
|
|
115
|
-
for (let i = 0; i < elements.length; i++) {
|
|
116
|
-
const importSpecifier = elements[i].element;
|
|
117
|
-
if (importSpecifier.specifier.kind == java_1.J.Kind.Identifier) {
|
|
118
|
-
names.push(importSpecifier.specifier.simpleName);
|
|
119
|
-
}
|
|
120
|
-
else if (importSpecifier.specifier.kind == javascript_1.JS.Kind.Alias) {
|
|
121
|
-
names.push(importSpecifier.specifier.propertyName.element.simpleName);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
throw new Error("Unknown kind " + elements[i].kind);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
else if (import_.importClause.namedBindings.kind == javascript_1.JS.Kind.Alias) {
|
|
130
|
-
const alias = import_.importClause.namedBindings;
|
|
131
|
-
names.push(alias.propertyName.element.simpleName);
|
|
132
|
-
if (alias.alias.kind == java_1.J.Kind.Identifier) {
|
|
133
|
-
names.push(alias.alias.simpleName);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return names;
|
|
139
|
-
}
|
|
140
|
-
compareStringArrays(a, b) {
|
|
141
|
-
let i = 0;
|
|
142
|
-
while (i < a.length && i < b.length) {
|
|
143
|
-
const comparison = a[i].localeCompare(b[i]);
|
|
144
|
-
if (comparison !== 0) {
|
|
145
|
-
return comparison;
|
|
146
|
-
}
|
|
147
|
-
i++;
|
|
148
|
-
}
|
|
149
|
-
if (i < a.length) {
|
|
150
|
-
return 1;
|
|
151
|
-
}
|
|
152
|
-
else if (i < b.length) {
|
|
153
|
-
return -1;
|
|
154
|
-
}
|
|
155
|
-
return 0;
|
|
156
|
-
}
|
|
157
|
-
countImports(cu) {
|
|
158
|
-
let i = 0;
|
|
159
|
-
while ((i < cu.statements.length) && (cu.statements[i].element.kind === javascript_1.JS.Kind.Import)) {
|
|
160
|
-
i++;
|
|
161
|
-
}
|
|
162
|
-
return i;
|
|
163
|
-
}
|
|
164
|
-
sortNamesWithinEachLine(imports) {
|
|
165
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
166
|
-
const ret = [];
|
|
167
|
-
for (const importPadded of imports) {
|
|
168
|
-
const import_ = importPadded.element;
|
|
169
|
-
if (this.isMultipleImport(import_) == 1) {
|
|
170
|
-
const importSorted = (0, immer_1.produce)(import_, draft => {
|
|
171
|
-
var _a;
|
|
172
|
-
let elements = draft.importClause.namedBindings.elements.elements;
|
|
173
|
-
const trailingComma = elements.length > 0 && ((_a = elements[elements.length - 1].markers) === null || _a === void 0 ? void 0 : _a.markers.find(m => m.kind === java_1.J.Markers.TrailingComma));
|
|
174
|
-
if (trailingComma) {
|
|
175
|
-
elements[elements.length - 1].markers.markers = elements[elements.length - 1].markers.markers.filter(m => m.kind !== java_1.J.Markers.TrailingComma);
|
|
176
|
-
}
|
|
177
|
-
elements.sort((a, b) => {
|
|
178
|
-
const namesExtracted = [a.element, b.element].map(expr => {
|
|
179
|
-
const is = expr;
|
|
180
|
-
if (is.specifier.kind == javascript_1.JS.Kind.Alias) {
|
|
181
|
-
return is.specifier.propertyName.element.simpleName;
|
|
182
|
-
}
|
|
183
|
-
else if (is.specifier.kind == java_1.J.Kind.Identifier) {
|
|
184
|
-
return is.specifier.simpleName;
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
throw new Error("Unsupported kind " + expr.kind);
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
return namesExtracted[0].localeCompare(namesExtracted[1]);
|
|
191
|
-
});
|
|
192
|
-
if (trailingComma && elements.length > 0 && !elements[elements.length - 1].markers.markers.find(m => m.kind === java_1.J.Markers.TrailingComma)) {
|
|
193
|
-
elements[elements.length - 1].markers.markers.push(trailingComma);
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
const formatted = yield new format_1.AutoformatVisitor().visit(importSorted, {});
|
|
197
|
-
ret.push((0, immer_1.produce)(importPadded, draft => {
|
|
198
|
-
draft.element = formatted;
|
|
199
|
-
}));
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
ret.push(importPadded);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return ret;
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
exports.OrderImports = OrderImports;
|
|
213
|
-
//# sourceMappingURL=order-imports.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"order-imports.js","sourceRoot":"","sources":["../../src/recipe/order-imports.ts"],"names":[],"mappings":"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"}
|