@openrewrite/rewrite 8.69.0-20251207-220615 → 8.69.0-20251207-230203
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/javascript/autodetect.d.ts +45 -0
- package/dist/javascript/autodetect.d.ts.map +1 -0
- package/dist/javascript/autodetect.js +303 -0
- package/dist/javascript/autodetect.js.map +1 -0
- package/dist/javascript/format.d.ts +12 -2
- package/dist/javascript/format.d.ts.map +1 -1
- package/dist/javascript/format.js +37 -13
- package/dist/javascript/format.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/recipes/auto-format.d.ts +25 -13
- package/dist/javascript/recipes/auto-format.d.ts.map +1 -1
- package/dist/javascript/recipes/auto-format.js +38 -13
- package/dist/javascript/recipes/auto-format.js.map +1 -1
- package/dist/javascript/style.d.ts +9 -0
- package/dist/javascript/style.d.ts.map +1 -1
- package/dist/javascript/style.js +30 -0
- package/dist/javascript/style.js.map +1 -1
- package/dist/test/rewrite-test.d.ts +17 -0
- package/dist/test/rewrite-test.d.ts.map +1 -1
- package/dist/test/rewrite-test.js +1 -0
- package/dist/test/rewrite-test.js.map +1 -1
- package/dist/version.txt +1 -1
- package/package.json +1 -1
- package/src/javascript/autodetect.ts +302 -0
- package/src/javascript/format.ts +42 -22
- package/src/javascript/index.ts +1 -0
- package/src/javascript/recipes/auto-format.ts +49 -14
- package/src/javascript/style.ts +32 -0
- package/src/test/rewrite-test.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewrite-test.js","sourceRoot":"","sources":["../../src/test/rewrite-test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"rewrite-test.js","sourceRoot":"","sources":["../../src/test/rewrite-test.ts"],"names":[],"mappings":"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"}
|
package/dist/version.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
8.69.0-20251207-
|
|
1
|
+
8.69.0-20251207-230203
|
package/package.json
CHANGED
|
@@ -0,0 +1,302 @@
|
|
|
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 {NamedStyles, Style} from "../style";
|
|
18
|
+
import {randomId} from "../uuid";
|
|
19
|
+
import {SourceFile} from "../tree";
|
|
20
|
+
import {JS} from "./tree";
|
|
21
|
+
import {JavaScriptVisitor} from "./visitor";
|
|
22
|
+
import {J} from "../java";
|
|
23
|
+
import {
|
|
24
|
+
IntelliJ,
|
|
25
|
+
SpacesStyle,
|
|
26
|
+
StyleKind,
|
|
27
|
+
TabsAndIndentsStyle,
|
|
28
|
+
WrappingAndBracesStyle,
|
|
29
|
+
WrappingAndBracesStyleDetailKind
|
|
30
|
+
} from "./style";
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Auto-detected styles for JavaScript/TypeScript code.
|
|
34
|
+
* Focuses on key formatting variations where projects differ:
|
|
35
|
+
* - Tabs vs spaces
|
|
36
|
+
* - Indent size (2, 4, etc.)
|
|
37
|
+
* - Spaces within ES6 import/export braces
|
|
38
|
+
*/
|
|
39
|
+
export class Autodetect implements NamedStyles {
|
|
40
|
+
readonly kind = "org.openrewrite.marker.NamedStyles" as const;
|
|
41
|
+
readonly id: string;
|
|
42
|
+
readonly name = "org.openrewrite.javascript.Autodetect";
|
|
43
|
+
readonly displayName = "Auto-detected";
|
|
44
|
+
readonly description = "Automatically detect styles from a repository's existing code.";
|
|
45
|
+
readonly tags: string[] = [];
|
|
46
|
+
readonly styles: Style[];
|
|
47
|
+
|
|
48
|
+
constructor(id: string, styles: Style[]) {
|
|
49
|
+
this.id = id;
|
|
50
|
+
this.styles = styles;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static detector(): Detector {
|
|
54
|
+
return new Detector();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Collects formatting statistics from source files and builds auto-detected styles.
|
|
60
|
+
*/
|
|
61
|
+
export class Detector {
|
|
62
|
+
private readonly tabsAndIndentsStats = new TabsAndIndentsStatistics();
|
|
63
|
+
private readonly spacesStats = new SpacesStatistics();
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Sample a source file to collect formatting statistics.
|
|
67
|
+
*/
|
|
68
|
+
async sample(sourceFile: SourceFile): Promise<void> {
|
|
69
|
+
if (sourceFile.kind === JS.Kind.CompilationUnit) {
|
|
70
|
+
await this.sampleJavaScript(sourceFile as JS.CompilationUnit);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Sample a JavaScript/TypeScript compilation unit.
|
|
76
|
+
*/
|
|
77
|
+
async sampleJavaScript(cu: JS.CompilationUnit): Promise<void> {
|
|
78
|
+
await new FindIndentVisitor(this.tabsAndIndentsStats).visit(cu, {});
|
|
79
|
+
await new FindSpacesVisitor(this.spacesStats).visit(cu, {});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Build the auto-detected styles from collected statistics.
|
|
84
|
+
*/
|
|
85
|
+
build(): Autodetect {
|
|
86
|
+
return new Autodetect(randomId(), [
|
|
87
|
+
this.tabsAndIndentsStats.getTabsAndIndentsStyle(),
|
|
88
|
+
this.spacesStats.getSpacesStyle(),
|
|
89
|
+
this.getWrappingAndBracesStyle(),
|
|
90
|
+
]);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
getTabsAndIndentsStyle(): TabsAndIndentsStyle {
|
|
94
|
+
return this.tabsAndIndentsStats.getTabsAndIndentsStyle();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
getSpacesStyle(): SpacesStyle {
|
|
98
|
+
return this.spacesStats.getSpacesStyle();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
getWrappingAndBracesStyle(): WrappingAndBracesStyle {
|
|
102
|
+
return {
|
|
103
|
+
kind: StyleKind.WrappingAndBracesStyle,
|
|
104
|
+
ifStatement: {
|
|
105
|
+
kind: WrappingAndBracesStyleDetailKind.WrappingAndBracesStyleIfStatement,
|
|
106
|
+
elseOnNewLine: false
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ============================================================================
|
|
113
|
+
// Statistics Classes
|
|
114
|
+
// ============================================================================
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Tracks indentation patterns to detect tabs vs spaces and indent size.
|
|
118
|
+
*/
|
|
119
|
+
class TabsAndIndentsStatistics {
|
|
120
|
+
private totalSpaceIndents = 0;
|
|
121
|
+
private totalTabIndents = 0;
|
|
122
|
+
|
|
123
|
+
// Track all observed indent sizes to compute GCD
|
|
124
|
+
private observedIndents: number[] = [];
|
|
125
|
+
|
|
126
|
+
recordSpaceIndent(spaceCount: number): void {
|
|
127
|
+
this.totalSpaceIndents++;
|
|
128
|
+
if (spaceCount > 0) {
|
|
129
|
+
this.observedIndents.push(spaceCount);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
recordTabIndent(): void {
|
|
134
|
+
this.totalTabIndents++;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
getTabsAndIndentsStyle(): TabsAndIndentsStyle {
|
|
138
|
+
// Determine if using tabs or spaces
|
|
139
|
+
const useTabs = this.totalTabIndents > this.totalSpaceIndents;
|
|
140
|
+
|
|
141
|
+
// Find indent size by computing GCD of all observed indents
|
|
142
|
+
// This correctly handles 2-space files where we see 2, 4, 6, 8... (all multiples of 2)
|
|
143
|
+
let detectedIndentSize = 4; // Default
|
|
144
|
+
if (this.observedIndents.length > 0) {
|
|
145
|
+
// Compute GCD of all observed indents
|
|
146
|
+
let gcd = this.observedIndents[0];
|
|
147
|
+
for (let i = 1; i < this.observedIndents.length; i++) {
|
|
148
|
+
gcd = this.computeGcd(gcd, this.observedIndents[i]);
|
|
149
|
+
if (gcd === 1) break; // Can't get smaller than 1
|
|
150
|
+
}
|
|
151
|
+
// Only use common indent sizes (2, 4, 8)
|
|
152
|
+
if (gcd === 2 || gcd === 4 || gcd === 8) {
|
|
153
|
+
detectedIndentSize = gcd;
|
|
154
|
+
} else if (gcd > 0 && gcd % 4 === 0) {
|
|
155
|
+
detectedIndentSize = 4;
|
|
156
|
+
} else if (gcd > 0 && gcd % 2 === 0) {
|
|
157
|
+
detectedIndentSize = 2;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
kind: StyleKind.TabsAndIndentsStyle,
|
|
163
|
+
useTabCharacter: useTabs,
|
|
164
|
+
tabSize: 4,
|
|
165
|
+
indentSize: detectedIndentSize,
|
|
166
|
+
continuationIndent: detectedIndentSize * 2,
|
|
167
|
+
keepIndentsOnEmptyLines: false,
|
|
168
|
+
indentChainedMethods: true,
|
|
169
|
+
indentAllChainedCallsInAGroup: false
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private computeGcd(a: number, b: number): number {
|
|
174
|
+
while (b !== 0) {
|
|
175
|
+
const temp = b;
|
|
176
|
+
b = a % b;
|
|
177
|
+
a = temp;
|
|
178
|
+
}
|
|
179
|
+
return a;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Tracks spacing patterns around ES6 import/export braces.
|
|
185
|
+
*/
|
|
186
|
+
class SpacesStatistics {
|
|
187
|
+
// Track spaces within ES6 import/export braces: { a } vs {a}
|
|
188
|
+
es6ImportExportBracesWithSpace = 0;
|
|
189
|
+
es6ImportExportBracesWithoutSpace = 0;
|
|
190
|
+
|
|
191
|
+
getSpacesStyle(): SpacesStyle {
|
|
192
|
+
// Use TypeScript defaults as base since most modern JS/TS projects use similar conventions
|
|
193
|
+
// TypeScript defaults include afterTypeReferenceColon: true which is commonly expected
|
|
194
|
+
const defaults = IntelliJ.TypeScript.spaces();
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
...defaults,
|
|
198
|
+
within: {
|
|
199
|
+
...defaults.within,
|
|
200
|
+
es6ImportExportBraces: this.es6ImportExportBracesWithSpace > this.es6ImportExportBracesWithoutSpace
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ============================================================================
|
|
207
|
+
// Visitor Classes for Collecting Statistics
|
|
208
|
+
// ============================================================================
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Detects indentation patterns by examining block contents.
|
|
212
|
+
*/
|
|
213
|
+
class FindIndentVisitor extends JavaScriptVisitor<any> {
|
|
214
|
+
constructor(private stats: TabsAndIndentsStatistics) {
|
|
215
|
+
super();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
protected async visitBlock(block: J.Block, p: any): Promise<J | undefined> {
|
|
219
|
+
// Check indentation of statements in the block
|
|
220
|
+
for (const stmt of block.statements) {
|
|
221
|
+
const whitespace = stmt.element.prefix?.whitespace;
|
|
222
|
+
if (whitespace) {
|
|
223
|
+
this.analyzeIndent(whitespace);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return super.visitBlock(block, p);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private analyzeIndent(whitespace: string): void {
|
|
230
|
+
const newlineIndex = whitespace.lastIndexOf('\n');
|
|
231
|
+
if (newlineIndex < 0) return;
|
|
232
|
+
|
|
233
|
+
const indent = whitespace.substring(newlineIndex + 1);
|
|
234
|
+
if (indent.length === 0) return;
|
|
235
|
+
|
|
236
|
+
// Check first character to determine type
|
|
237
|
+
if (indent[0] === '\t') {
|
|
238
|
+
this.stats.recordTabIndent();
|
|
239
|
+
} else if (indent[0] === ' ') {
|
|
240
|
+
// Count consecutive spaces
|
|
241
|
+
let spaceCount = 0;
|
|
242
|
+
for (const char of indent) {
|
|
243
|
+
if (char === ' ') spaceCount++;
|
|
244
|
+
else break;
|
|
245
|
+
}
|
|
246
|
+
if (spaceCount > 0) {
|
|
247
|
+
this.stats.recordSpaceIndent(spaceCount);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Detects spacing patterns in imports and exports.
|
|
255
|
+
*/
|
|
256
|
+
class FindSpacesVisitor extends JavaScriptVisitor<any> {
|
|
257
|
+
constructor(private stats: SpacesStatistics) {
|
|
258
|
+
super();
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
protected async visitImportDeclaration(import_: JS.Import, p: any): Promise<J | undefined> {
|
|
262
|
+
// Check ES6 import braces spacing: import { a } from 'x' vs import {a} from 'x'
|
|
263
|
+
if (import_.importClause?.namedBindings?.kind === JS.Kind.NamedImports) {
|
|
264
|
+
const namedImports = import_.importClause.namedBindings as JS.NamedImports;
|
|
265
|
+
if (namedImports.elements.elements.length > 0) {
|
|
266
|
+
const firstElement = namedImports.elements.elements[0];
|
|
267
|
+
const hasSpaceAfterOpenBrace = firstElement.element.prefix?.whitespace?.includes(' ') ?? false;
|
|
268
|
+
|
|
269
|
+
const lastElement = namedImports.elements.elements[namedImports.elements.elements.length - 1];
|
|
270
|
+
const hasSpaceBeforeCloseBrace = lastElement.after?.whitespace?.includes(' ') ?? false;
|
|
271
|
+
|
|
272
|
+
if (hasSpaceAfterOpenBrace || hasSpaceBeforeCloseBrace) {
|
|
273
|
+
this.stats.es6ImportExportBracesWithSpace++;
|
|
274
|
+
} else {
|
|
275
|
+
this.stats.es6ImportExportBracesWithoutSpace++;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return super.visitImportDeclaration(import_, p);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
protected async visitExportDeclaration(export_: JS.ExportDeclaration, p: any): Promise<J | undefined> {
|
|
283
|
+
// Check ES6 export braces spacing
|
|
284
|
+
if (export_.exportClause?.kind === JS.Kind.NamedExports) {
|
|
285
|
+
const namedExports = export_.exportClause as JS.NamedExports;
|
|
286
|
+
if (namedExports.elements.elements.length > 0) {
|
|
287
|
+
const firstElement = namedExports.elements.elements[0];
|
|
288
|
+
const hasSpaceAfterOpenBrace = firstElement.element.prefix?.whitespace?.includes(' ') ?? false;
|
|
289
|
+
|
|
290
|
+
const lastElement = namedExports.elements.elements[namedExports.elements.elements.length - 1];
|
|
291
|
+
const hasSpaceBeforeCloseBrace = lastElement.after?.whitespace?.includes(' ') ?? false;
|
|
292
|
+
|
|
293
|
+
if (hasSpaceAfterOpenBrace || hasSpaceBeforeCloseBrace) {
|
|
294
|
+
this.stats.es6ImportExportBracesWithSpace++;
|
|
295
|
+
} else {
|
|
296
|
+
this.stats.es6ImportExportBracesWithoutSpace++;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return super.visitExportDeclaration(export_, p);
|
|
301
|
+
}
|
|
302
|
+
}
|
package/src/javascript/format.ts
CHANGED
|
@@ -18,14 +18,8 @@ import {JavaScriptVisitor} from "./visitor";
|
|
|
18
18
|
import {Comment, J, lastWhitespace, replaceLastWhitespace, Statement} from "../java";
|
|
19
19
|
import {Draft, produce} from "immer";
|
|
20
20
|
import {Cursor, isScope, Tree} from "../tree";
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
SpacesStyle,
|
|
24
|
-
styleFromSourceFile,
|
|
25
|
-
StyleKind,
|
|
26
|
-
TabsAndIndentsStyle,
|
|
27
|
-
WrappingAndBracesStyle
|
|
28
|
-
} from "./style";
|
|
21
|
+
import {BlankLinesStyle, getStyle, SpacesStyle, StyleKind, TabsAndIndentsStyle, WrappingAndBracesStyle} from "./style";
|
|
22
|
+
import {NamedStyles} from "../style";
|
|
29
23
|
import {produceAsync} from "../visitor";
|
|
30
24
|
import {findMarker} from "../markers";
|
|
31
25
|
import {Generator} from "./markers";
|
|
@@ -40,22 +34,33 @@ export const maybeAutoFormat = async <J2 extends J, P>(before: J2, after: J2, p:
|
|
|
40
34
|
return after;
|
|
41
35
|
}
|
|
42
36
|
|
|
43
|
-
export const autoFormat = async <J2 extends J, P>(j: J2, p: P, stopAfter?: J, parent?: Cursor): Promise<J2> =>
|
|
44
|
-
(await new AutoformatVisitor(stopAfter).visit(j, p, parent) as J2);
|
|
37
|
+
export const autoFormat = async <J2 extends J, P>(j: J2, p: P, stopAfter?: J, parent?: Cursor, styles?: NamedStyles[]): Promise<J2> =>
|
|
38
|
+
(await new AutoformatVisitor(stopAfter, styles).visit(j, p, parent) as J2);
|
|
45
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Formats JavaScript/TypeScript code using a comprehensive set of formatting rules.
|
|
42
|
+
*
|
|
43
|
+
* Style resolution order (first match wins):
|
|
44
|
+
* 1. Styles passed to the constructor
|
|
45
|
+
* 2. Styles from source file markers (NamedStyles)
|
|
46
|
+
* 3. IntelliJ defaults
|
|
47
|
+
*/
|
|
46
48
|
export class AutoformatVisitor<P> extends JavaScriptVisitor<P> {
|
|
47
|
-
|
|
49
|
+
private readonly styles?: NamedStyles[];
|
|
50
|
+
|
|
51
|
+
constructor(private stopAfter?: Tree, styles?: NamedStyles[]) {
|
|
48
52
|
super();
|
|
53
|
+
this.styles = styles;
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
async visit<R extends J>(tree: Tree, p: P, cursor?: Cursor): Promise<R | undefined> {
|
|
52
57
|
const visitors = [
|
|
53
58
|
new NormalizeWhitespaceVisitor(this.stopAfter),
|
|
54
59
|
new MinimumViableSpacingVisitor(this.stopAfter),
|
|
55
|
-
new BlankLinesVisitor(
|
|
56
|
-
new WrappingAndBracesVisitor(
|
|
57
|
-
new SpacesVisitor(
|
|
58
|
-
new TabsAndIndentsVisitor(
|
|
60
|
+
new BlankLinesVisitor(getStyle(StyleKind.BlankLinesStyle, tree, this.styles) as BlankLinesStyle, this.stopAfter),
|
|
61
|
+
new WrappingAndBracesVisitor(getStyle(StyleKind.WrappingAndBracesStyle, tree, this.styles) as WrappingAndBracesStyle, this.stopAfter),
|
|
62
|
+
new SpacesVisitor(getStyle(StyleKind.SpacesStyle, tree, this.styles) as SpacesStyle, this.stopAfter),
|
|
63
|
+
new TabsAndIndentsVisitor(getStyle(StyleKind.TabsAndIndentsStyle, tree, this.styles) as TabsAndIndentsStyle, this.stopAfter),
|
|
59
64
|
]
|
|
60
65
|
|
|
61
66
|
let t: R | undefined = tree as R;
|
|
@@ -228,8 +233,13 @@ export class SpacesVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
228
233
|
if (draft.exportClause.kind == JS.Kind.NamedExports) {
|
|
229
234
|
const ne = (draft.exportClause as Draft<JS.NamedExports>);
|
|
230
235
|
if (ne.elements.elements.length > 0) {
|
|
231
|
-
|
|
232
|
-
ne.elements.elements
|
|
236
|
+
// Check if this is a multi-line export (any element's prefix has a newline)
|
|
237
|
+
const isMultiLine = ne.elements.elements.some(e => e.element.prefix.whitespace.includes("\n"));
|
|
238
|
+
// Only adjust brace spacing for single-line exports
|
|
239
|
+
if (!isMultiLine) {
|
|
240
|
+
ne.elements.elements[0].element.prefix.whitespace = this.style.within.es6ImportExportBraces ? " " : "";
|
|
241
|
+
ne.elements.elements[ne.elements.elements.length - 1].after.whitespace = this.style.within.es6ImportExportBraces ? " " : "";
|
|
242
|
+
}
|
|
233
243
|
}
|
|
234
244
|
}
|
|
235
245
|
}
|
|
@@ -290,8 +300,13 @@ export class SpacesVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
290
300
|
draft.importClause.namedBindings.prefix.whitespace = " ";
|
|
291
301
|
if (draft.importClause.namedBindings.kind == JS.Kind.NamedImports) {
|
|
292
302
|
const ni = draft.importClause.namedBindings as Draft<JS.NamedImports>;
|
|
293
|
-
|
|
294
|
-
ni.elements.elements
|
|
303
|
+
// Check if this is a multi-line import (any element's prefix has a newline)
|
|
304
|
+
const isMultiLine = ni.elements.elements.some(e => e.element.prefix.whitespace.includes("\n"));
|
|
305
|
+
// Only adjust brace spacing for single-line imports
|
|
306
|
+
if (!isMultiLine) {
|
|
307
|
+
ni.elements.elements[0].element.prefix.whitespace = this.style.within.es6ImportExportBraces ? " " : "";
|
|
308
|
+
ni.elements.elements[ni.elements.elements.length - 1].after.whitespace = this.style.within.es6ImportExportBraces ? " " : "";
|
|
309
|
+
}
|
|
295
310
|
}
|
|
296
311
|
}
|
|
297
312
|
}
|
|
@@ -363,9 +378,14 @@ export class SpacesVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
363
378
|
|
|
364
379
|
protected async visitPropertyAssignment(propertyAssignment: JS.PropertyAssignment, p: P): Promise<J | undefined> {
|
|
365
380
|
const pa = await super.visitPropertyAssignment(propertyAssignment, p) as JS.PropertyAssignment;
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
381
|
+
// Only adjust the space before the colon if there's an initializer (not a shorthand property)
|
|
382
|
+
// For shorthand properties like { headers }, name.after.whitespace is the space before }
|
|
383
|
+
if (pa.initializer) {
|
|
384
|
+
return produceAsync(pa, draft => {
|
|
385
|
+
draft.name.after.whitespace = this.style.other.beforePropertyNameValueSeparator ? " " : "";
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
return pa;
|
|
369
389
|
}
|
|
370
390
|
|
|
371
391
|
protected async visitSwitch(switchNode: J.Switch, p: P): Promise<J | undefined> {
|
package/src/javascript/index.ts
CHANGED
|
@@ -14,31 +14,66 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {ScanningRecipe} from "../../recipe";
|
|
18
18
|
import {TreeVisitor} from "../../visitor";
|
|
19
19
|
import {ExecutionContext} from "../../execution";
|
|
20
20
|
import {AutoformatVisitor} from "../format";
|
|
21
|
+
import {Autodetect, Detector} from "../autodetect";
|
|
22
|
+
import {JavaScriptVisitor} from "../visitor";
|
|
23
|
+
import {JS} from "../tree";
|
|
24
|
+
import {J} from "../../java";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Accumulator for the AutoFormat scanning recipe.
|
|
28
|
+
* Holds the Detector that collects formatting statistics during the scan phase.
|
|
29
|
+
*/
|
|
30
|
+
interface AutoFormatAccumulator {
|
|
31
|
+
detector: Detector;
|
|
32
|
+
detectedStyles?: Autodetect;
|
|
33
|
+
}
|
|
21
34
|
|
|
22
35
|
/**
|
|
23
36
|
* Formats JavaScript/TypeScript code using a comprehensive set of formatting rules.
|
|
24
37
|
*
|
|
25
|
-
* This
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* -
|
|
31
|
-
* -
|
|
38
|
+
* This is a scanning recipe that:
|
|
39
|
+
* 1. Scans all source files to detect the project's existing formatting style
|
|
40
|
+
* 2. Applies consistent formatting based on the detected style
|
|
41
|
+
*
|
|
42
|
+
* The detected formatting includes:
|
|
43
|
+
* - Tabs vs spaces preference
|
|
44
|
+
* - Indent size (2, 4, etc.)
|
|
45
|
+
* - ES6 import/export brace spacing
|
|
32
46
|
*
|
|
33
|
-
*
|
|
34
|
-
* or defaults to IntelliJ IDEA style if no custom style is specified.
|
|
47
|
+
* If no clear style is detected, defaults to IntelliJ IDEA style.
|
|
35
48
|
*/
|
|
36
|
-
export class AutoFormat extends
|
|
49
|
+
export class AutoFormat extends ScanningRecipe<AutoFormatAccumulator> {
|
|
37
50
|
readonly name = "org.openrewrite.javascript.format.auto-format";
|
|
38
51
|
readonly displayName = "Auto-format JavaScript/TypeScript code";
|
|
39
|
-
readonly description = "Format JavaScript and TypeScript code using
|
|
52
|
+
readonly description = "Format JavaScript and TypeScript code using formatting rules auto-detected from the project's existing code style.";
|
|
53
|
+
|
|
54
|
+
initialValue(_ctx: ExecutionContext): AutoFormatAccumulator {
|
|
55
|
+
return {
|
|
56
|
+
detector: Autodetect.detector()
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async scanner(acc: AutoFormatAccumulator): Promise<TreeVisitor<any, ExecutionContext>> {
|
|
61
|
+
return new class extends JavaScriptVisitor<ExecutionContext> {
|
|
62
|
+
protected async visitJsCompilationUnit(cu: JS.CompilationUnit, ctx: ExecutionContext): Promise<J | undefined> {
|
|
63
|
+
await acc.detector.sample(cu);
|
|
64
|
+
return cu;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async editorWithData(acc: AutoFormatAccumulator): Promise<TreeVisitor<any, ExecutionContext>> {
|
|
70
|
+
// Build detected styles once (lazily on first edit)
|
|
71
|
+
if (!acc.detectedStyles) {
|
|
72
|
+
acc.detectedStyles = acc.detector.build();
|
|
73
|
+
}
|
|
40
74
|
|
|
41
|
-
|
|
42
|
-
|
|
75
|
+
// Pass detected styles to the AutoformatVisitor
|
|
76
|
+
// Autodetect is a NamedStyles, so pass it as an array
|
|
77
|
+
return new AutoformatVisitor(undefined, [acc.detectedStyles]);
|
|
43
78
|
}
|
|
44
79
|
}
|
package/src/javascript/style.ts
CHANGED
|
@@ -498,3 +498,35 @@ export function styleFromSourceFile(styleKind: string, sourceFile: Tree): Style
|
|
|
498
498
|
}
|
|
499
499
|
return IntelliJ.TypeScript.defaults.styles.find(style => style.kind === styleKind) as Style;
|
|
500
500
|
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Get a style by kind, with passed-in styles taking precedence over source file styles.
|
|
504
|
+
* Falls back to IntelliJ defaults if no style is found.
|
|
505
|
+
*
|
|
506
|
+
* @param styleKind The kind of style to retrieve
|
|
507
|
+
* @param sourceFile The source file to check for styles
|
|
508
|
+
* @param styles Optional array of NamedStyles that take precedence over source file styles
|
|
509
|
+
*/
|
|
510
|
+
export function getStyle(styleKind: string, sourceFile: Tree, styles?: NamedStyles[]): Style | undefined {
|
|
511
|
+
// First check passed-in styles (highest precedence)
|
|
512
|
+
if (styles) {
|
|
513
|
+
for (const namedStyle of styles) {
|
|
514
|
+
const found = namedStyle.styles.find(s => s.kind === styleKind);
|
|
515
|
+
if (found) {
|
|
516
|
+
return found;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Then check source file markers
|
|
522
|
+
const namedStyles = sourceFile.markers.markers.filter(marker => marker.kind === MarkersKind.NamedStyles) as NamedStyles[];
|
|
523
|
+
for (const namedStyle of namedStyles) {
|
|
524
|
+
const found = namedStyle.styles.find(s => s.kind === styleKind);
|
|
525
|
+
if (found) {
|
|
526
|
+
return found;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Fall back to defaults
|
|
531
|
+
return IntelliJ.TypeScript.defaults.styles.find(style => style.kind === styleKind) as Style;
|
|
532
|
+
}
|
package/src/test/rewrite-test.ts
CHANGED
|
@@ -257,7 +257,7 @@ export type AfterRecipeText = string | ((actual: string) => string | undefined)
|
|
|
257
257
|
* - ` code\n` → `code` (trailing newline removed)
|
|
258
258
|
* - ` code\n\n` → `code\n` (first trailing newline removed, second preserved)
|
|
259
259
|
*/
|
|
260
|
-
function dedent(s: string): string {
|
|
260
|
+
export function dedent(s: string): string {
|
|
261
261
|
if (!s) return s;
|
|
262
262
|
|
|
263
263
|
// Remove single leading newline for ergonomics
|