@openrewrite/rewrite 8.70.0-20251222-101414 → 8.70.0-20251222-213047
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/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/java/formatting-utils.d.ts +1 -1
- package/dist/java/formatting-utils.js +4 -4
- package/dist/java/formatting-utils.js.map +1 -1
- package/dist/java/markers.js +8 -8
- package/dist/java/markers.js.map +1 -1
- package/dist/java/type-visitor.d.ts +0 -3
- package/dist/java/type-visitor.d.ts.map +1 -1
- package/dist/java/type-visitor.js +67 -68
- package/dist/java/type-visitor.js.map +1 -1
- package/dist/java/visitor.d.ts +3 -3
- package/dist/java/visitor.d.ts.map +1 -1
- package/dist/java/visitor.js +5 -5
- package/dist/java/visitor.js.map +1 -1
- package/dist/javascript/assertions.js +4 -3
- package/dist/javascript/assertions.js.map +1 -1
- package/dist/javascript/cleanup/use-object-property-shorthand.js +3 -3
- package/dist/javascript/cleanup/use-object-property-shorthand.js.map +1 -1
- package/dist/javascript/format/format.d.ts +28 -7
- package/dist/javascript/format/format.d.ts.map +1 -1
- package/dist/javascript/format/format.js +149 -158
- package/dist/javascript/format/format.js.map +1 -1
- package/dist/javascript/format/minimum-viable-spacing-visitor.js +23 -23
- package/dist/javascript/format/minimum-viable-spacing-visitor.js.map +1 -1
- package/dist/javascript/format/prettier-format.d.ts.map +1 -1
- package/dist/javascript/format/prettier-format.js +8 -11
- package/dist/javascript/format/prettier-format.js.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.js +7 -7
- package/dist/javascript/format/tabs-and-indents-visitor.js.map +1 -1
- package/dist/javascript/format/whitespace-reconciler.d.ts.map +1 -1
- package/dist/javascript/format/whitespace-reconciler.js +12 -11
- package/dist/javascript/format/whitespace-reconciler.js.map +1 -1
- package/dist/javascript/markers.d.ts.map +1 -1
- package/dist/javascript/markers.js +6 -5
- package/dist/javascript/markers.js.map +1 -1
- package/dist/javascript/migrate/es6/modernize-octal-escape-sequences.js +2 -2
- package/dist/javascript/migrate/es6/modernize-octal-escape-sequences.js.map +1 -1
- package/dist/javascript/migrate/es6/modernize-octal-literals.js +2 -2
- package/dist/javascript/migrate/es6/modernize-octal-literals.js.map +1 -1
- package/dist/javascript/migrate/es6/remove-duplicate-object-keys.js +2 -2
- package/dist/javascript/migrate/es6/remove-duplicate-object-keys.js.map +1 -1
- package/dist/javascript/migrate/typescript/export-assignment-to-export-default.js +2 -2
- package/dist/javascript/migrate/typescript/export-assignment-to-export-default.js.map +1 -1
- package/dist/javascript/node-resolution-result.js +3 -9
- package/dist/javascript/node-resolution-result.js.map +1 -1
- package/dist/javascript/parser.d.ts.map +1 -1
- package/dist/javascript/parser.js +35 -35
- package/dist/javascript/parser.js.map +1 -1
- package/dist/javascript/project-parser.d.ts.map +1 -1
- package/dist/javascript/project-parser.js +6 -5
- package/dist/javascript/project-parser.js.map +1 -1
- package/dist/javascript/recipes/auto-format.d.ts +7 -23
- package/dist/javascript/recipes/auto-format.d.ts.map +1 -1
- package/dist/javascript/recipes/auto-format.js +8 -54
- package/dist/javascript/recipes/auto-format.js.map +1 -1
- package/dist/javascript/recipes/change-import.js +8 -8
- package/dist/javascript/recipes/change-import.js.map +1 -1
- package/dist/javascript/recipes/order-imports.js +4 -4
- package/dist/javascript/recipes/order-imports.js.map +1 -1
- package/dist/javascript/templating/engine.js +2 -2
- package/dist/javascript/templating/engine.js.map +1 -1
- package/dist/javascript/templating/index.d.ts +1 -0
- package/dist/javascript/templating/index.d.ts.map +1 -1
- package/dist/javascript/templating/index.js +4 -1
- package/dist/javascript/templating/index.js.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.js +16 -16
- package/dist/javascript/templating/placeholder-replacement.js.map +1 -1
- package/dist/javascript/type-mapping.d.ts.map +1 -1
- package/dist/javascript/type-mapping.js +49 -58
- package/dist/javascript/type-mapping.js.map +1 -1
- package/dist/javascript/visitor.d.ts +3 -3
- package/dist/javascript/visitor.d.ts.map +1 -1
- package/dist/javascript/visitor.js +3 -3
- package/dist/javascript/visitor.js.map +1 -1
- package/dist/json/rpc.js +48 -49
- package/dist/json/rpc.js.map +1 -1
- package/dist/json/visitor.d.ts +3 -3
- package/dist/json/visitor.d.ts.map +1 -1
- package/dist/json/visitor.js +3 -3
- package/dist/json/visitor.js.map +1 -1
- package/dist/parse-error.js +11 -11
- package/dist/parse-error.js.map +1 -1
- package/dist/reference.d.ts.map +1 -1
- package/dist/reference.js +0 -3
- package/dist/reference.js.map +1 -1
- package/dist/rpc/index.js +42 -42
- package/dist/rpc/index.js.map +1 -1
- package/dist/rpc/queue.d.ts.map +1 -1
- package/dist/rpc/queue.js +6 -8
- package/dist/rpc/queue.js.map +1 -1
- package/dist/rpc/request/install-recipes.js +1 -1
- package/dist/rpc/request/install-recipes.js.map +1 -1
- package/dist/rpc/request/parse-project.d.ts.map +1 -1
- package/dist/rpc/request/parse-project.js +12 -32
- package/dist/rpc/request/parse-project.js.map +1 -1
- package/dist/rpc/request/parse.d.ts.map +1 -1
- package/dist/rpc/request/parse.js +1 -4
- package/dist/rpc/request/parse.js.map +1 -1
- package/dist/text/rpc.js +18 -18
- package/dist/text/rpc.js.map +1 -1
- package/dist/version.txt +1 -1
- package/dist/visitor.d.ts +6 -4
- package/dist/visitor.d.ts.map +1 -1
- package/dist/visitor.js +19 -17
- package/dist/visitor.js.map +1 -1
- package/dist/yaml/rpc.js +65 -65
- package/dist/yaml/rpc.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +8 -8
- package/src/java/formatting-utils.ts +2 -2
- package/src/java/markers.ts +8 -8
- package/src/java/type-visitor.ts +59 -68
- package/src/java/visitor.ts +8 -8
- package/src/javascript/assertions.ts +3 -3
- package/src/javascript/cleanup/use-object-property-shorthand.ts +1 -1
- package/src/javascript/format/format.ts +109 -107
- package/src/javascript/format/minimum-viable-spacing-visitor.ts +1 -1
- package/src/javascript/format/prettier-format.ts +9 -12
- package/src/javascript/format/tabs-and-indents-visitor.ts +1 -1
- package/src/javascript/format/whitespace-reconciler.ts +12 -11
- package/src/javascript/markers.ts +6 -6
- package/src/javascript/migrate/es6/modernize-octal-escape-sequences.ts +1 -1
- package/src/javascript/migrate/es6/modernize-octal-literals.ts +1 -1
- package/src/javascript/migrate/es6/remove-duplicate-object-keys.ts +1 -1
- package/src/javascript/migrate/typescript/export-assignment-to-export-default.ts +1 -1
- package/src/javascript/node-resolution-result.ts +8 -14
- package/src/javascript/parser.ts +5 -4
- package/src/javascript/project-parser.ts +4 -4
- package/src/javascript/recipes/auto-format.ts +9 -71
- package/src/javascript/recipes/change-import.ts +4 -4
- package/src/javascript/recipes/order-imports.ts +1 -1
- package/src/javascript/templating/engine.ts +1 -1
- package/src/javascript/templating/index.ts +5 -0
- package/src/javascript/templating/placeholder-replacement.ts +2 -2
- package/src/javascript/type-mapping.ts +28 -34
- package/src/javascript/visitor.ts +6 -6
- package/src/json/rpc.ts +51 -52
- package/src/json/visitor.ts +6 -6
- package/src/parse-error.ts +11 -11
- package/src/reference.ts +0 -5
- package/src/rpc/index.ts +43 -43
- package/src/rpc/queue.ts +6 -8
- package/src/rpc/request/install-recipes.ts +1 -1
- package/src/rpc/request/parse-project.ts +20 -32
- package/src/rpc/request/parse.ts +1 -4
- package/src/text/rpc.ts +18 -18
- package/src/visitor.ts +29 -30
- package/src/yaml/rpc.ts +80 -81
|
@@ -17,7 +17,7 @@ import {findMarker, Marker, Markers} from "../markers";
|
|
|
17
17
|
import {randomId, UUID} from "../uuid";
|
|
18
18
|
import {asRef} from "../reference";
|
|
19
19
|
import {RpcCodecs, RpcReceiveQueue, RpcSendQueue} from "../rpc";
|
|
20
|
-
import {castDraft} from "
|
|
20
|
+
import {castDraft} from "mutative";
|
|
21
21
|
import {updateIfChanged} from "../util";
|
|
22
22
|
import * as semver from "semver";
|
|
23
23
|
import * as fsp from "fs/promises";
|
|
@@ -295,7 +295,7 @@ export function createNodeResolutionResultMarker(
|
|
|
295
295
|
function extractPackageInfo(pkgPath: string): { name: string; version?: string } {
|
|
296
296
|
// For nested packages, we want the last package name
|
|
297
297
|
const nodeModulesIndex = pkgPath.lastIndexOf('node_modules/');
|
|
298
|
-
if (nodeModulesIndex === -1) return {
|
|
298
|
+
if (nodeModulesIndex === -1) return {name: pkgPath};
|
|
299
299
|
|
|
300
300
|
let nameWithVersion = pkgPath.slice(nodeModulesIndex + 'node_modules/'.length);
|
|
301
301
|
|
|
@@ -320,7 +320,7 @@ export function createNodeResolutionResultMarker(
|
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
-
return {
|
|
323
|
+
return {name: nameWithVersion};
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
/**
|
|
@@ -347,7 +347,7 @@ export function createNodeResolutionResultMarker(
|
|
|
347
347
|
optionalDependencies: undefined,
|
|
348
348
|
engines: normalizeEngines(pkgEntry?.engines),
|
|
349
349
|
license: normalizeLicense(pkgEntry?.license),
|
|
350
|
-
});
|
|
350
|
+
}) as ResolvedDependency;
|
|
351
351
|
resolvedDependencyCache.set(key, resolved);
|
|
352
352
|
|
|
353
353
|
// Maintain name index for O(1) lookup during semver fallback
|
|
@@ -470,7 +470,7 @@ export function createNodeResolutionResultMarker(
|
|
|
470
470
|
name,
|
|
471
471
|
versionConstraint,
|
|
472
472
|
resolved,
|
|
473
|
-
});
|
|
473
|
+
}) as Dependency;
|
|
474
474
|
dependencyCache.set(key, dep);
|
|
475
475
|
}
|
|
476
476
|
return dep;
|
|
@@ -514,7 +514,7 @@ export function createNodeResolutionResultMarker(
|
|
|
514
514
|
const packages = lockContent.packages;
|
|
515
515
|
|
|
516
516
|
// First pass: Create all ResolvedDependency placeholders and build path map
|
|
517
|
-
const packageInfos: Array<{path: string; name: string; version: string; entry: PackageLockEntry}> = [];
|
|
517
|
+
const packageInfos: Array<{ path: string; name: string; version: string; entry: PackageLockEntry }> = [];
|
|
518
518
|
for (const [pkgPath, pkgEntry] of Object.entries(packages)) {
|
|
519
519
|
// Skip the root package (empty string key)
|
|
520
520
|
if (pkgPath === '') continue;
|
|
@@ -535,7 +535,7 @@ export function createNodeResolutionResultMarker(
|
|
|
535
535
|
// Note: Using castDraft here is safe because all objects are created within this
|
|
536
536
|
// parsing context and haven't been returned to callers yet. The objects in
|
|
537
537
|
// resolvedDependencyCache are plain JS objects marked with asRef() for RPC
|
|
538
|
-
// reference deduplication
|
|
538
|
+
// reference deduplication.
|
|
539
539
|
for (const {path: pkgPath, name, version, entry} of packageInfos) {
|
|
540
540
|
const key = `${name}@${version}`;
|
|
541
541
|
const resolved = resolvedDependencyCache.get(key);
|
|
@@ -590,7 +590,7 @@ export function createNodeResolutionResultMarker(
|
|
|
590
590
|
packageManager,
|
|
591
591
|
engines: packageJsonContent.engines,
|
|
592
592
|
npmrcConfigs,
|
|
593
|
-
};
|
|
593
|
+
} as NodeResolutionResult;
|
|
594
594
|
}
|
|
595
595
|
|
|
596
596
|
/**
|
|
@@ -817,7 +817,6 @@ export namespace NodeResolutionResultQueries {
|
|
|
817
817
|
RpcCodecs.registerCodec(NpmrcKind, {
|
|
818
818
|
async rpcReceive(before: Npmrc, q: RpcReceiveQueue): Promise<Npmrc> {
|
|
819
819
|
return updateIfChanged(before, {
|
|
820
|
-
kind: NpmrcKind,
|
|
821
820
|
scope: await q.receive(before.scope),
|
|
822
821
|
properties: await q.receive(before.properties),
|
|
823
822
|
});
|
|
@@ -835,7 +834,6 @@ RpcCodecs.registerCodec(NpmrcKind, {
|
|
|
835
834
|
RpcCodecs.registerCodec(DependencyKind, {
|
|
836
835
|
async rpcReceive(before: Dependency, q: RpcReceiveQueue): Promise<Dependency> {
|
|
837
836
|
return updateIfChanged(before, {
|
|
838
|
-
kind: DependencyKind,
|
|
839
837
|
name: await q.receive(before.name),
|
|
840
838
|
versionConstraint: await q.receive(before.versionConstraint),
|
|
841
839
|
resolved: await q.receive(before.resolved),
|
|
@@ -855,7 +853,6 @@ RpcCodecs.registerCodec(DependencyKind, {
|
|
|
855
853
|
RpcCodecs.registerCodec(ResolvedDependencyKind, {
|
|
856
854
|
async rpcReceive(before: ResolvedDependency, q: RpcReceiveQueue): Promise<ResolvedDependency> {
|
|
857
855
|
return updateIfChanged(before, {
|
|
858
|
-
kind: ResolvedDependencyKind,
|
|
859
856
|
name: await q.receive(before.name),
|
|
860
857
|
version: await q.receive(before.version),
|
|
861
858
|
dependencies: (await q.receiveList(before.dependencies)) || undefined,
|
|
@@ -886,9 +883,6 @@ RpcCodecs.registerCodec(ResolvedDependencyKind, {
|
|
|
886
883
|
/**
|
|
887
884
|
* Register RPC codec for NodeResolutionResult marker.
|
|
888
885
|
* This handles serialization/deserialization for communication between JS and Java.
|
|
889
|
-
* Note: We avoid Immer here because the dependency graph can contain cycles
|
|
890
|
-
* (e.g., Dependency -> ResolvedDependency -> Dependency[]), and Immer's proxies
|
|
891
|
-
* don't handle cyclic structures correctly.
|
|
892
886
|
*/
|
|
893
887
|
RpcCodecs.registerCodec(NodeResolutionResultKind, {
|
|
894
888
|
async rpcReceive(before: NodeResolutionResult, q: RpcReceiveQueue): Promise<NodeResolutionResult> {
|
package/src/javascript/parser.ts
CHANGED
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
VariableDeclarator,
|
|
31
31
|
} from '../java';
|
|
32
32
|
import {DelegatedYield, FunctionDeclaration, Generator, JS, JSX, NonNullAssertion, Optional, Spread} from '.';
|
|
33
|
-
import {emptyMarkers, markers, Markers, MarkersKind, ParseExceptionResult} from "../markers";
|
|
33
|
+
import {emptyMarkers, markers, Markers, MarkersKind, ParseExceptionResult, replaceMarkerByKind} from "../markers";
|
|
34
34
|
import {NamedStyles} from "../style";
|
|
35
35
|
import {Parser, ParserInput, parserInputFile, parserInputRead, ParserOptions, Parsers, SourcePath} from "../parser";
|
|
36
36
|
import {randomId} from "../uuid";
|
|
@@ -47,10 +47,11 @@ import {
|
|
|
47
47
|
TextSpan
|
|
48
48
|
} from "./parser-utils";
|
|
49
49
|
import {JavaScriptTypeMapping} from "./type-mapping";
|
|
50
|
-
import {produce} from "
|
|
50
|
+
import {create as produce} from "mutative";
|
|
51
51
|
import ComputedPropertyName = JS.ComputedPropertyName;
|
|
52
52
|
import Attribute = JSX.Attribute;
|
|
53
53
|
import SpreadAttribute = JSX.SpreadAttribute;
|
|
54
|
+
|
|
54
55
|
export interface JavaScriptParserOptions extends ParserOptions {
|
|
55
56
|
styles?: NamedStyles[],
|
|
56
57
|
sourceFileCache?: Map<string, ts.SourceFile>,
|
|
@@ -168,7 +169,7 @@ export class JavaScriptParser extends Parser {
|
|
|
168
169
|
if (this.styles) {
|
|
169
170
|
const styles = this.styles;
|
|
170
171
|
return produce(result, draft => {
|
|
171
|
-
draft.markers
|
|
172
|
+
draft.markers = styles.reduce((m, s) => replaceMarkerByKind(m, s), draft.markers);
|
|
172
173
|
});
|
|
173
174
|
}
|
|
174
175
|
return result;
|
|
@@ -359,7 +360,7 @@ export class JavaScriptParser extends Parser {
|
|
|
359
360
|
.visit(sourceFile) as SourceFile,
|
|
360
361
|
draft => {
|
|
361
362
|
if (this.styles) {
|
|
362
|
-
draft.markers
|
|
363
|
+
draft.markers = this.styles.reduce((m, s) => replaceMarkerByKind(m, s), draft.markers);
|
|
363
364
|
}
|
|
364
365
|
});
|
|
365
366
|
} catch (error) {
|
|
@@ -18,12 +18,12 @@ import * as fs from "fs";
|
|
|
18
18
|
import * as fsp from "fs/promises";
|
|
19
19
|
import {spawnSync} from "child_process";
|
|
20
20
|
import picomatch from "picomatch";
|
|
21
|
-
import {produce} from "
|
|
21
|
+
import {create as produce} from "mutative";
|
|
22
22
|
import {SourceFile} from "../tree";
|
|
23
23
|
import {Parsers} from "../parser";
|
|
24
24
|
import {PrettierConfigLoader} from "./format/prettier-config-loader";
|
|
25
25
|
import {ExecutionContext} from "../execution";
|
|
26
|
-
import {Marker} from "../markers";
|
|
26
|
+
import {Marker, replaceMarkerByKind} from "../markers";
|
|
27
27
|
|
|
28
28
|
// Lock file names defined here to avoid circular dependency with package-manager.ts
|
|
29
29
|
// These must be kept in sync with the definitions in package-manager.ts
|
|
@@ -303,7 +303,7 @@ export class ProjectParser {
|
|
|
303
303
|
);
|
|
304
304
|
if (prettierMarker) {
|
|
305
305
|
yield produce(sf, draft => {
|
|
306
|
-
draft.markers
|
|
306
|
+
draft.markers = replaceMarkerByKind(draft.markers, prettierMarker);
|
|
307
307
|
});
|
|
308
308
|
} else {
|
|
309
309
|
yield sf;
|
|
@@ -341,7 +341,7 @@ export class ProjectParser {
|
|
|
341
341
|
// Yield all files with the Autodetect marker
|
|
342
342
|
for (const sf of parsedFiles) {
|
|
343
343
|
yield produce(sf, draft => {
|
|
344
|
-
draft.markers
|
|
344
|
+
draft.markers = replaceMarkerByKind(draft.markers, autodetectMarker);
|
|
345
345
|
});
|
|
346
346
|
}
|
|
347
347
|
}
|
|
@@ -14,93 +14,31 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {Recipe} 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
|
-
import {findMarker, MarkersKind} from "../../markers";
|
|
26
|
-
import {StyleKind} from "../style";
|
|
27
|
-
import {NamedStyles} from "../../style";
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Accumulator for the AutoFormat scanning recipe.
|
|
31
|
-
* Holds the Detector that collects formatting statistics during the scan phase.
|
|
32
|
-
*/
|
|
33
|
-
interface AutoFormatAccumulator {
|
|
34
|
-
detector: Detector;
|
|
35
|
-
detectedStyles?: Autodetect;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Checks if a compilation unit already has formatting styles attached.
|
|
40
|
-
* Returns true if either PrettierStyle or Autodetect markers are present.
|
|
41
|
-
*/
|
|
42
|
-
function hasFormattingStyles(cu: JS.CompilationUnit): boolean {
|
|
43
|
-
// Check for PrettierStyle marker
|
|
44
|
-
if (findMarker(cu, StyleKind.PrettierStyle)) {
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Check for Autodetect marker (NamedStyles with specific name)
|
|
49
|
-
const namedStyles = cu.markers.markers.filter(
|
|
50
|
-
m => m.kind === MarkersKind.NamedStyles
|
|
51
|
-
) as NamedStyles[];
|
|
52
|
-
|
|
53
|
-
return namedStyles.some(s => s.name === "org.openrewrite.javascript.Autodetect");
|
|
54
|
-
}
|
|
55
21
|
|
|
56
22
|
/**
|
|
57
23
|
* Formats JavaScript/TypeScript code using a comprehensive set of formatting rules.
|
|
58
24
|
*
|
|
59
|
-
* This
|
|
60
|
-
*
|
|
61
|
-
*
|
|
25
|
+
* This recipe applies formatting based on styles detected at parse time:
|
|
26
|
+
* - If PrettierStyle marker is present, uses Prettier formatting
|
|
27
|
+
* - If Autodetect marker is present, uses auto-detected project style
|
|
28
|
+
* - Otherwise, defaults to IntelliJ IDEA style
|
|
62
29
|
*
|
|
63
30
|
* The detected formatting includes:
|
|
64
31
|
* - Tabs vs spaces preference
|
|
65
32
|
* - Indent size (2, 4, etc.)
|
|
66
33
|
* - ES6 import/export brace spacing
|
|
67
|
-
*
|
|
68
|
-
* If no clear style is detected, defaults to IntelliJ IDEA style.
|
|
69
|
-
*
|
|
70
|
-
* Files with existing formatting styles (PrettierStyle or Autodetect markers)
|
|
71
|
-
* are skipped during style detection since they already have their formatting configured.
|
|
72
34
|
*/
|
|
73
|
-
export class AutoFormat extends
|
|
35
|
+
export class AutoFormat extends Recipe {
|
|
74
36
|
readonly name = "org.openrewrite.javascript.format.auto-format";
|
|
75
37
|
readonly displayName = "Auto-format JavaScript/TypeScript code";
|
|
76
38
|
readonly description = "Format JavaScript and TypeScript code using formatting rules auto-detected from the project's existing code style.";
|
|
77
39
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async scanner(acc: AutoFormatAccumulator): Promise<TreeVisitor<any, ExecutionContext>> {
|
|
85
|
-
return new class extends JavaScriptVisitor<ExecutionContext> {
|
|
86
|
-
protected async visitJsCompilationUnit(cu: JS.CompilationUnit, ctx: ExecutionContext): Promise<J | undefined> {
|
|
87
|
-
// Skip sampling files that already have formatting styles attached
|
|
88
|
-
if (!hasFormattingStyles(cu)) {
|
|
89
|
-
await acc.detector.sample(cu);
|
|
90
|
-
}
|
|
91
|
-
return cu;
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async editorWithData(acc: AutoFormatAccumulator): Promise<TreeVisitor<any, ExecutionContext>> {
|
|
97
|
-
// Build detected styles once (lazily on first edit)
|
|
98
|
-
if (!acc.detectedStyles) {
|
|
99
|
-
acc.detectedStyles = acc.detector.build();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Pass detected styles to the AutoformatVisitor
|
|
103
|
-
// Autodetect is a NamedStyles, so pass it as an array
|
|
104
|
-
return new AutoformatVisitor(undefined, [acc.detectedStyles]);
|
|
40
|
+
async editor(): Promise<TreeVisitor<any, ExecutionContext>> {
|
|
41
|
+
// AutoformatVisitor looks up styles from source file markers
|
|
42
|
+
return new AutoformatVisitor();
|
|
105
43
|
}
|
|
106
44
|
}
|
|
@@ -20,7 +20,7 @@ import {ExecutionContext} from "../../execution";
|
|
|
20
20
|
import {JavaScriptVisitor, JS} from "../index";
|
|
21
21
|
import {maybeAddImport} from "../add-import";
|
|
22
22
|
import {J, isIdentifier, Type} from "../../java";
|
|
23
|
-
import {produce,
|
|
23
|
+
import {create as produce, Draft} from "mutative";
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Changes an import from one module to another, updating all type attributions.
|
|
@@ -206,7 +206,7 @@ export class ChangeImport extends Recipe {
|
|
|
206
206
|
this.transformedImport = true;
|
|
207
207
|
return produce(imp, draft => {
|
|
208
208
|
if (draft.moduleSpecifier) {
|
|
209
|
-
const literal = draft.moduleSpecifier.element as
|
|
209
|
+
const literal = draft.moduleSpecifier.element as Draft<J.Literal>;
|
|
210
210
|
literal.value = newModule;
|
|
211
211
|
// Update valueSource to preserve quote style
|
|
212
212
|
const originalSource = literal.valueSource || `"${oldModule}"`;
|
|
@@ -217,7 +217,7 @@ export class ChangeImport extends Recipe {
|
|
|
217
217
|
if (newMember !== oldMember && oldMember !== 'default' && oldMember !== '*') {
|
|
218
218
|
const importClause = draft.importClause;
|
|
219
219
|
if (importClause?.namedBindings?.kind === JS.Kind.NamedImports) {
|
|
220
|
-
const namedImports = importClause.namedBindings as
|
|
220
|
+
const namedImports = importClause.namedBindings as Draft<JS.NamedImports>;
|
|
221
221
|
for (const elem of namedImports.elements.elements) {
|
|
222
222
|
const specifier = elem.element;
|
|
223
223
|
if (specifier.specifier.kind === J.Kind.Identifier &&
|
|
@@ -241,7 +241,7 @@ export class ChangeImport extends Recipe {
|
|
|
241
241
|
if (!importClause?.namedBindings) return;
|
|
242
242
|
if (importClause.namedBindings.kind !== JS.Kind.NamedImports) return;
|
|
243
243
|
|
|
244
|
-
const namedImports = importClause.namedBindings as
|
|
244
|
+
const namedImports = importClause.namedBindings as Draft<JS.NamedImports>;
|
|
245
245
|
const elements = namedImports.elements.elements;
|
|
246
246
|
const filteredElements = elements.filter(elem => {
|
|
247
247
|
const specifier = elem.element;
|
|
@@ -19,7 +19,7 @@ import {produceAsync, TreeVisitor} from "../../visitor";
|
|
|
19
19
|
import {ExecutionContext} from "../../execution";
|
|
20
20
|
import {JavaScriptVisitor, JS} from "../index";
|
|
21
21
|
import {J} from "../../java";
|
|
22
|
-
import {
|
|
22
|
+
import {create as produce, Draft} from "mutative";
|
|
23
23
|
import {SpacesStyle, styleFromSourceFile, StyleKind} from "../style";
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import {Cursor, isTree, produceAsync, Tree, updateIfChanged} from '../..';
|
|
17
17
|
import {emptySpace, J, Statement, Type} from '../../java';
|
|
18
18
|
import {Any, Capture, JavaScriptParser, JavaScriptVisitor, JS} from '..';
|
|
19
|
-
import {produce} from '
|
|
19
|
+
import {create as produce} from 'mutative';
|
|
20
20
|
import {CaptureMarker, PlaceholderUtils, WRAPPER_FUNCTION_NAME} from './utils';
|
|
21
21
|
import {CAPTURE_NAME_SYMBOL, CAPTURE_TYPE_SYMBOL, CaptureImpl, CaptureValue, RAW_CODE_SYMBOL, RawCode} from './capture';
|
|
22
22
|
import {PlaceholderReplacementVisitor} from './placeholder-replacement';
|
|
@@ -17,7 +17,7 @@ import {Cursor, isTree} from '../..';
|
|
|
17
17
|
import {J} from '../../java';
|
|
18
18
|
import {JS} from '..';
|
|
19
19
|
import {JavaScriptVisitor} from '../visitor';
|
|
20
|
-
import {produce} from '
|
|
20
|
+
import {create as produce} from 'mutative';
|
|
21
21
|
import {PlaceholderUtils} from './utils';
|
|
22
22
|
import {CaptureImpl, TemplateParamImpl, CaptureValue, CAPTURE_NAME_SYMBOL} from './capture';
|
|
23
23
|
import {Parameter} from './types';
|
|
@@ -260,7 +260,7 @@ export class PlaceholderReplacementVisitor extends JavaScriptVisitor<any> {
|
|
|
260
260
|
newElements.push(produce(item, draft => {
|
|
261
261
|
if (i === 0 && draft.element) {
|
|
262
262
|
// Merge the placeholder's prefix with the first item's prefix
|
|
263
|
-
// Modify prefix directly
|
|
263
|
+
// Modify prefix directly within the draft
|
|
264
264
|
draft.element.prefix = this.mergePrefix(draft.element.prefix, element.prefix);
|
|
265
265
|
}
|
|
266
266
|
// Keep all other wrapper properties (including markers with Semicolon)
|
|
@@ -15,14 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import ts from "typescript";
|
|
17
17
|
import {Type} from "../java";
|
|
18
|
-
import {immerable} from "immer";
|
|
19
18
|
import FUNCTION_TYPE_NAME = Type.FUNCTION_TYPE_NAME;
|
|
20
19
|
|
|
21
|
-
// Helper class to create Type objects that immer won't traverse
|
|
22
|
-
class NonDraftableType {
|
|
23
|
-
[immerable] = false;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
20
|
export class JavaScriptTypeMapping {
|
|
27
21
|
// Primary cache: Use type signatures (preferring type.id) as cache keys
|
|
28
22
|
// TypeScript assigns stable IDs to all types, so we don't need secondary caches
|
|
@@ -180,7 +174,7 @@ export class JavaScriptTypeMapping {
|
|
|
180
174
|
}
|
|
181
175
|
|
|
182
176
|
// Create the parameterized type wrapper
|
|
183
|
-
const parameterized =
|
|
177
|
+
const parameterized = {
|
|
184
178
|
kind: Type.Kind.Parameterized,
|
|
185
179
|
type: classType,
|
|
186
180
|
typeParameters: typeParameters,
|
|
@@ -188,7 +182,7 @@ export class JavaScriptTypeMapping {
|
|
|
188
182
|
toJSON: function () {
|
|
189
183
|
return Type.signature(this);
|
|
190
184
|
}
|
|
191
|
-
}
|
|
185
|
+
} as Type.Parameterized;
|
|
192
186
|
|
|
193
187
|
// Cache the parameterized type
|
|
194
188
|
this.typeCache.set(signature, parameterized);
|
|
@@ -418,7 +412,7 @@ export class JavaScriptTypeMapping {
|
|
|
418
412
|
if (ts.isStringLiteral(importDecl.moduleSpecifier)) {
|
|
419
413
|
const moduleSpecifier = importDecl.moduleSpecifier.text;
|
|
420
414
|
// Create a Type.Class representing the module
|
|
421
|
-
ownerType =
|
|
415
|
+
ownerType = {
|
|
422
416
|
kind: Type.Kind.Class,
|
|
423
417
|
flags: 0,
|
|
424
418
|
classKind: Type.Class.Kind.Interface,
|
|
@@ -431,7 +425,7 @@ export class JavaScriptTypeMapping {
|
|
|
431
425
|
toJSON: function () {
|
|
432
426
|
return Type.signature(this);
|
|
433
427
|
}
|
|
434
|
-
}
|
|
428
|
+
} as Type.Class;
|
|
435
429
|
}
|
|
436
430
|
}
|
|
437
431
|
}
|
|
@@ -461,7 +455,7 @@ export class JavaScriptTypeMapping {
|
|
|
461
455
|
// Store the module as the owningClass for now
|
|
462
456
|
// (This is a bit of a hack, but works with the current type system)
|
|
463
457
|
if (Type.isClass(ownerType)) {
|
|
464
|
-
(ownerType as any).owningClass =
|
|
458
|
+
(ownerType as any).owningClass = {
|
|
465
459
|
kind: Type.Kind.Class,
|
|
466
460
|
flags: 0,
|
|
467
461
|
classKind: Type.Class.Kind.Interface,
|
|
@@ -474,7 +468,7 @@ export class JavaScriptTypeMapping {
|
|
|
474
468
|
toJSON: function () {
|
|
475
469
|
return Type.signature(this);
|
|
476
470
|
}
|
|
477
|
-
}
|
|
471
|
+
} as Type.Class;
|
|
478
472
|
}
|
|
479
473
|
}
|
|
480
474
|
}
|
|
@@ -485,7 +479,7 @@ export class JavaScriptTypeMapping {
|
|
|
485
479
|
}
|
|
486
480
|
|
|
487
481
|
// Create the Type.Variable
|
|
488
|
-
const variable =
|
|
482
|
+
const variable = {
|
|
489
483
|
kind: Type.Kind.Variable,
|
|
490
484
|
name: actualSymbol.getName(),
|
|
491
485
|
owner: ownerType,
|
|
@@ -494,7 +488,7 @@ export class JavaScriptTypeMapping {
|
|
|
494
488
|
toJSON: function () {
|
|
495
489
|
return Type.signature(this);
|
|
496
490
|
}
|
|
497
|
-
}
|
|
491
|
+
} as Type.Variable;
|
|
498
492
|
|
|
499
493
|
return variable;
|
|
500
494
|
}
|
|
@@ -593,7 +587,7 @@ export class JavaScriptTypeMapping {
|
|
|
593
587
|
}
|
|
594
588
|
|
|
595
589
|
// Create the Type.Method object
|
|
596
|
-
const method =
|
|
590
|
+
const method = {
|
|
597
591
|
kind: Type.Kind.Method,
|
|
598
592
|
flags: 0, // FIXME - determine flags
|
|
599
593
|
declaringType: declaringType,
|
|
@@ -608,7 +602,7 @@ export class JavaScriptTypeMapping {
|
|
|
608
602
|
toJSON: function () {
|
|
609
603
|
return Type.signature(this);
|
|
610
604
|
}
|
|
611
|
-
}
|
|
605
|
+
} as Type.Method;
|
|
612
606
|
|
|
613
607
|
this.methodCache.set(cacheKey, method);
|
|
614
608
|
return method;
|
|
@@ -1062,7 +1056,7 @@ export class JavaScriptTypeMapping {
|
|
|
1062
1056
|
}
|
|
1063
1057
|
|
|
1064
1058
|
// Create empty class type shell (no members yet to avoid recursion)
|
|
1065
|
-
return
|
|
1059
|
+
return {
|
|
1066
1060
|
kind: Type.Kind.Class,
|
|
1067
1061
|
flags: 0, // TODO - determine flags
|
|
1068
1062
|
classKind: classKind,
|
|
@@ -1075,7 +1069,7 @@ export class JavaScriptTypeMapping {
|
|
|
1075
1069
|
toJSON: function () {
|
|
1076
1070
|
return Type.signature(this);
|
|
1077
1071
|
}
|
|
1078
|
-
}
|
|
1072
|
+
} as Type.Class;
|
|
1079
1073
|
}
|
|
1080
1074
|
|
|
1081
1075
|
/**
|
|
@@ -1191,7 +1185,7 @@ export class JavaScriptTypeMapping {
|
|
|
1191
1185
|
} else {
|
|
1192
1186
|
// Create Type.Variable for fields/properties
|
|
1193
1187
|
const propType = this.checker.getTypeOfSymbolAtLocation(prop, declaration);
|
|
1194
|
-
const variable: Type.Variable =
|
|
1188
|
+
const variable: Type.Variable = {
|
|
1195
1189
|
kind: Type.Kind.Variable,
|
|
1196
1190
|
name: prop.getName(),
|
|
1197
1191
|
owner: classType, // Cyclic reference to the containing class (already in cache)
|
|
@@ -1200,7 +1194,7 @@ export class JavaScriptTypeMapping {
|
|
|
1200
1194
|
toJSON: function () {
|
|
1201
1195
|
return Type.signature(this);
|
|
1202
1196
|
}
|
|
1203
|
-
}
|
|
1197
|
+
} as Type.Variable;
|
|
1204
1198
|
classType.members.push(variable);
|
|
1205
1199
|
}
|
|
1206
1200
|
}
|
|
@@ -1261,10 +1255,10 @@ export class JavaScriptTypeMapping {
|
|
|
1261
1255
|
*/
|
|
1262
1256
|
private createUnionType(unionType: ts.UnionType, cacheKey: string | number): Type.Union {
|
|
1263
1257
|
// Shell-cache FIRST to prevent infinite recursion (before resolving constituent types)
|
|
1264
|
-
const union =
|
|
1258
|
+
const union = {
|
|
1265
1259
|
kind: Type.Kind.Union,
|
|
1266
1260
|
bounds: []
|
|
1267
|
-
}
|
|
1261
|
+
} as Type.Union;
|
|
1268
1262
|
|
|
1269
1263
|
this.typeCache.set(cacheKey, union);
|
|
1270
1264
|
|
|
@@ -1286,10 +1280,10 @@ export class JavaScriptTypeMapping {
|
|
|
1286
1280
|
*/
|
|
1287
1281
|
private createIntersectionType(intersectionType: ts.IntersectionType, cacheKey: string | number): Type.Intersection {
|
|
1288
1282
|
// Shell-cache FIRST to prevent infinite recursion (before resolving constituent types)
|
|
1289
|
-
const intersection =
|
|
1283
|
+
const intersection = {
|
|
1290
1284
|
kind: Type.Kind.Intersection,
|
|
1291
1285
|
bounds: []
|
|
1292
|
-
}
|
|
1286
|
+
} as Type.Intersection;
|
|
1293
1287
|
|
|
1294
1288
|
this.typeCache.set(cacheKey, intersection);
|
|
1295
1289
|
|
|
@@ -1315,12 +1309,12 @@ export class JavaScriptTypeMapping {
|
|
|
1315
1309
|
const name = symbol ? symbol.getName() : '?';
|
|
1316
1310
|
|
|
1317
1311
|
// Shell-cache: Create stub, cache it, then populate (prevents cycles)
|
|
1318
|
-
const gtv =
|
|
1312
|
+
const gtv = {
|
|
1319
1313
|
kind: Type.Kind.GenericTypeVariable,
|
|
1320
1314
|
name: name,
|
|
1321
1315
|
variance: Type.GenericTypeVariable.Variance.Invariant,
|
|
1322
1316
|
bounds: []
|
|
1323
|
-
}
|
|
1317
|
+
} as Type.GenericTypeVariable;
|
|
1324
1318
|
|
|
1325
1319
|
this.typeCache.set(cacheKey, gtv);
|
|
1326
1320
|
|
|
@@ -1350,7 +1344,7 @@ export class JavaScriptTypeMapping {
|
|
|
1350
1344
|
* The shell will be populated later to handle circular references.
|
|
1351
1345
|
*/
|
|
1352
1346
|
private createEmptyFunctionType(): Type.Class {
|
|
1353
|
-
return
|
|
1347
|
+
return {
|
|
1354
1348
|
kind: Type.Kind.Class,
|
|
1355
1349
|
flags: 0,
|
|
1356
1350
|
classKind: Type.Class.Kind.Interface,
|
|
@@ -1363,7 +1357,7 @@ export class JavaScriptTypeMapping {
|
|
|
1363
1357
|
toJSON: function () {
|
|
1364
1358
|
return Type.signature(this);
|
|
1365
1359
|
}
|
|
1366
|
-
}
|
|
1360
|
+
} as Type.Class;
|
|
1367
1361
|
}
|
|
1368
1362
|
|
|
1369
1363
|
/**
|
|
@@ -1394,27 +1388,27 @@ export class JavaScriptTypeMapping {
|
|
|
1394
1388
|
const typeParameters: Type[] = [];
|
|
1395
1389
|
|
|
1396
1390
|
// Return type parameter (covariant)
|
|
1397
|
-
typeParameters.push(
|
|
1391
|
+
typeParameters.push({
|
|
1398
1392
|
kind: Type.Kind.GenericTypeVariable,
|
|
1399
1393
|
name: 'R',
|
|
1400
1394
|
variance: Type.GenericTypeVariable.Variance.Covariant,
|
|
1401
1395
|
bounds: [returnType]
|
|
1402
|
-
}
|
|
1396
|
+
} as Type.GenericTypeVariable);
|
|
1403
1397
|
|
|
1404
1398
|
// Parameter type variables (contravariant)
|
|
1405
1399
|
parameterTypes.forEach((paramType, index) => {
|
|
1406
|
-
typeParameters.push(
|
|
1400
|
+
typeParameters.push({
|
|
1407
1401
|
kind: Type.Kind.GenericTypeVariable,
|
|
1408
1402
|
name: `P${index + 1}`,
|
|
1409
1403
|
variance: Type.GenericTypeVariable.Variance.Contravariant,
|
|
1410
1404
|
bounds: [paramType]
|
|
1411
|
-
}
|
|
1405
|
+
} as Type.GenericTypeVariable);
|
|
1412
1406
|
});
|
|
1413
1407
|
|
|
1414
1408
|
functionClass.typeParameters = typeParameters;
|
|
1415
1409
|
|
|
1416
1410
|
// Create the apply() method
|
|
1417
|
-
const applyMethod =
|
|
1411
|
+
const applyMethod = {
|
|
1418
1412
|
kind: Type.Kind.Method,
|
|
1419
1413
|
flags: 0,
|
|
1420
1414
|
declaringType: functionClass,
|
|
@@ -1429,7 +1423,7 @@ export class JavaScriptTypeMapping {
|
|
|
1429
1423
|
toJSON: function () {
|
|
1430
1424
|
return Type.signature(this);
|
|
1431
1425
|
}
|
|
1432
|
-
}
|
|
1426
|
+
} as Type.Method;
|
|
1433
1427
|
|
|
1434
1428
|
// Add the apply method to the function class
|
|
1435
1429
|
functionClass.methods.push(applyMethod);
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import {mapAsync, updateIfChanged} from "../util";
|
|
19
19
|
import {Cursor, SourceFile} from "../tree";
|
|
20
|
-
import {
|
|
20
|
+
import {ValidRecipeReturnType} from "../visitor";
|
|
21
21
|
import {Expression, J, Type, JavaVisitor, NameTree, Statement, TypedTree} from "../java";
|
|
22
|
-
import {
|
|
22
|
+
import {create, Draft} from "mutative";
|
|
23
23
|
import {isJavaScript, JS, JSX} from "./tree";
|
|
24
24
|
import ComputedPropertyName = JS.ComputedPropertyName;
|
|
25
25
|
|
|
@@ -58,16 +58,16 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
|
|
|
58
58
|
before: J2,
|
|
59
59
|
p: P,
|
|
60
60
|
recipe?: (draft: Draft<J2>) =>
|
|
61
|
-
|
|
62
|
-
PromiseLike<
|
|
61
|
+
ValidRecipeReturnType<Draft<J2>> |
|
|
62
|
+
PromiseLike<ValidRecipeReturnType<Draft<J2>>>
|
|
63
63
|
): Promise<J2> {
|
|
64
|
-
const draft
|
|
64
|
+
const [draft, finishDraft] = create(before!);
|
|
65
65
|
(draft as Draft<J>).prefix = await this.visitSpace(before!.prefix, p);
|
|
66
66
|
(draft as Draft<J>).markers = await this.visitMarkers(before!.markers, p);
|
|
67
67
|
if (recipe) {
|
|
68
68
|
await recipe(draft);
|
|
69
69
|
}
|
|
70
|
-
return finishDraft(
|
|
70
|
+
return finishDraft() as J2;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
protected async visitAlias(alias: JS.Alias, p: P): Promise<J | undefined> {
|