@openrewrite/rewrite 8.96.3 → 8.96.5
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/execution.d.ts +2 -0
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +4 -0
- package/dist/execution.js.map +1 -1
- package/dist/heavyweight.d.ts +8 -0
- package/dist/heavyweight.d.ts.map +1 -0
- package/dist/heavyweight.js +45 -0
- package/dist/heavyweight.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/java/tree.d.ts +11 -11
- package/dist/java/tree.d.ts.map +1 -1
- package/dist/java/visitor.d.ts.map +1 -1
- package/dist/java/visitor.js +46 -2
- package/dist/java/visitor.js.map +1 -1
- package/dist/javascript/add-import.d.ts +2 -1
- package/dist/javascript/add-import.d.ts.map +1 -1
- package/dist/javascript/add-import.js +14 -2
- package/dist/javascript/add-import.js.map +1 -1
- package/dist/javascript/amd.d.ts.map +1 -1
- package/dist/javascript/amd.js +2 -1
- package/dist/javascript/amd.js.map +1 -1
- package/dist/javascript/cleanup/add-parse-int-radix.js +1 -1
- package/dist/javascript/cleanup/add-parse-int-radix.js.map +1 -1
- package/dist/javascript/format/format.d.ts +12 -0
- package/dist/javascript/format/format.d.ts.map +1 -1
- package/dist/javascript/format/format.js +17 -3
- package/dist/javascript/format/format.js.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.d.ts.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.js +4 -0
- 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 +4 -0
- package/dist/javascript/format/whitespace-reconciler.js.map +1 -1
- package/dist/javascript/node-resolution-result.d.ts.map +1 -1
- package/dist/javascript/node-resolution-result.js +2 -0
- package/dist/javascript/node-resolution-result.js.map +1 -1
- package/dist/javascript/parser-utils.d.ts.map +1 -1
- package/dist/javascript/parser-utils.js +16 -5
- package/dist/javascript/parser-utils.js.map +1 -1
- package/dist/javascript/templating/engine.d.ts.map +1 -1
- package/dist/javascript/templating/engine.js +11 -6
- package/dist/javascript/templating/engine.js.map +1 -1
- package/dist/javascript/templating/pattern.d.ts.map +1 -1
- package/dist/javascript/templating/pattern.js +8 -0
- package/dist/javascript/templating/pattern.js.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.d.ts.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.js +15 -0
- package/dist/javascript/templating/placeholder-replacement.js.map +1 -1
- package/dist/javascript/templating/precedence.js +1 -1
- package/dist/javascript/templating/precedence.js.map +1 -1
- package/dist/javascript/tree.d.ts +12 -12
- package/dist/javascript/tree.d.ts.map +1 -1
- package/dist/javascript/visitor.d.ts.map +1 -1
- package/dist/javascript/visitor.js +96 -0
- package/dist/javascript/visitor.js.map +1 -1
- package/dist/recipe.d.ts +5 -0
- package/dist/recipe.d.ts.map +1 -1
- package/dist/recipe.js +5 -0
- package/dist/recipe.js.map +1 -1
- package/dist/rewrite-javascript-version.txt +1 -1
- package/dist/run.d.ts +7 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +40 -2
- package/dist/run.js.map +1 -1
- package/dist/test/accumulator-contents.d.ts +15 -0
- package/dist/test/accumulator-contents.d.ts.map +1 -0
- package/dist/test/accumulator-contents.js +185 -0
- package/dist/test/accumulator-contents.js.map +1 -0
- package/dist/test/empty-sources.d.ts +14 -0
- package/dist/test/empty-sources.d.ts.map +1 -0
- package/dist/test/empty-sources.js +98 -0
- package/dist/test/empty-sources.js.map +1 -0
- package/dist/test/formatting-scope.d.ts +18 -0
- package/dist/test/formatting-scope.d.ts.map +1 -0
- package/dist/test/formatting-scope.js +244 -0
- package/dist/test/formatting-scope.js.map +1 -0
- package/dist/test/probes.d.ts +25 -0
- package/dist/test/probes.d.ts.map +1 -0
- package/dist/test/probes.js +189 -0
- package/dist/test/probes.js.map +1 -0
- package/dist/test/rewrite-test.d.ts +27 -0
- package/dist/test/rewrite-test.d.ts.map +1 -1
- package/dist/test/rewrite-test.js +191 -21
- package/dist/test/rewrite-test.js.map +1 -1
- package/dist/test/tree-shapes.d.ts +15 -0
- package/dist/test/tree-shapes.d.ts.map +1 -0
- package/dist/test/tree-shapes.js +288 -0
- package/dist/test/tree-shapes.js.map +1 -0
- package/dist/test/unparsed-sources.d.ts +17 -0
- package/dist/test/unparsed-sources.d.ts.map +1 -0
- package/dist/test/unparsed-sources.js +113 -0
- package/dist/test/unparsed-sources.js.map +1 -0
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +2 -0
- package/dist/tree.js.map +1 -1
- package/dist/visitor.d.ts.map +1 -1
- package/dist/visitor.js +2 -0
- package/dist/visitor.js.map +1 -1
- package/node_modules/picomatch/LICENSE +21 -0
- package/node_modules/picomatch/README.md +743 -0
- package/node_modules/picomatch/index.js +17 -0
- package/node_modules/picomatch/lib/constants.js +184 -0
- package/node_modules/picomatch/lib/parse.js +1506 -0
- package/node_modules/picomatch/lib/picomatch.js +361 -0
- package/node_modules/picomatch/lib/scan.js +403 -0
- package/node_modules/picomatch/lib/utils.js +72 -0
- package/node_modules/picomatch/package.json +83 -0
- package/node_modules/picomatch/posix.js +3 -0
- package/package.json +88 -90
- package/src/execution.ts +6 -0
- package/src/heavyweight.ts +42 -0
- package/src/index.ts +1 -0
- package/src/java/tree.ts +11 -11
- package/src/java/visitor.ts +52 -2
- package/src/javascript/add-import.ts +11 -2
- package/src/javascript/amd.ts +4 -2
- package/src/javascript/cleanup/add-parse-int-radix.ts +2 -2
- package/src/javascript/format/format.ts +25 -1
- package/src/javascript/format/tabs-and-indents-visitor.ts +4 -0
- package/src/javascript/format/whitespace-reconciler.ts +4 -0
- package/src/javascript/node-resolution-result.ts +3 -0
- package/src/javascript/parser-utils.ts +19 -7
- package/src/javascript/templating/engine.ts +11 -6
- package/src/javascript/templating/pattern.ts +10 -0
- package/src/javascript/templating/placeholder-replacement.ts +16 -0
- package/src/javascript/templating/precedence.ts +1 -1
- package/src/javascript/tree.ts +12 -12
- package/src/javascript/visitor.ts +120 -0
- package/src/recipe.ts +5 -0
- package/src/run.ts +30 -2
- package/src/test/accumulator-contents.ts +194 -0
- package/src/test/empty-sources.ts +99 -0
- package/src/test/formatting-scope.ts +231 -0
- package/src/test/probes.ts +156 -0
- package/src/test/rewrite-test.ts +177 -24
- package/src/test/tree-shapes.ts +332 -0
- package/src/test/unparsed-sources.ts +138 -0
- package/src/tree.ts +3 -0
- package/src/visitor.ts +3 -0
package/package.json
CHANGED
|
@@ -1,108 +1,106 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "@openrewrite/rewrite",
|
|
3
|
-
"version": "8.96.
|
|
4
|
-
"license": "Moderne Source Available License",
|
|
5
|
-
"description": "OpenRewrite JavaScript.",
|
|
6
|
-
"repository": {
|
|
7
|
-
"type": "git",
|
|
8
|
-
"url": "https://github.com/openrewrite/rewrite",
|
|
9
|
-
"directory": "rewrite-javascript/rewrite"
|
|
2
|
+
"name" : "@openrewrite/rewrite",
|
|
3
|
+
"version" : "8.96.5",
|
|
4
|
+
"license" : "Moderne Source Available License",
|
|
5
|
+
"description" : "OpenRewrite JavaScript.",
|
|
6
|
+
"repository" : {
|
|
7
|
+
"type" : "git",
|
|
8
|
+
"url" : "https://github.com/openrewrite/rewrite",
|
|
9
|
+
"directory" : "rewrite-javascript/rewrite"
|
|
10
10
|
},
|
|
11
|
-
"homepage": "https://github.com/openrewrite/rewrite",
|
|
12
|
-
"main": "./dist/index.js",
|
|
13
|
-
"types": "./dist/index.d.ts",
|
|
14
|
-
"files": [
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
"allowScripts": {
|
|
19
|
-
"bun": true,
|
|
20
|
-
"@datadog/pprof": true
|
|
11
|
+
"homepage" : "https://github.com/openrewrite/rewrite",
|
|
12
|
+
"main" : "./dist/index.js",
|
|
13
|
+
"types" : "./dist/index.d.ts",
|
|
14
|
+
"files" : [ "dist/**", "src/**" ],
|
|
15
|
+
"allowScripts" : {
|
|
16
|
+
"bun" : true,
|
|
17
|
+
"@datadog/pprof" : true
|
|
21
18
|
},
|
|
22
|
-
"exports": {
|
|
23
|
-
".": {
|
|
24
|
-
"types": "./dist/index.d.ts",
|
|
25
|
-
"default": "./dist/index.js"
|
|
19
|
+
"exports" : {
|
|
20
|
+
"." : {
|
|
21
|
+
"types" : "./dist/index.d.ts",
|
|
22
|
+
"default" : "./dist/index.js"
|
|
26
23
|
},
|
|
27
|
-
"./text": {
|
|
28
|
-
"types": "./dist/text/index.d.ts",
|
|
29
|
-
"default": "./dist/text/index.js"
|
|
24
|
+
"./text" : {
|
|
25
|
+
"types" : "./dist/text/index.d.ts",
|
|
26
|
+
"default" : "./dist/text/index.js"
|
|
30
27
|
},
|
|
31
|
-
"./json": {
|
|
32
|
-
"types": "./dist/json/index.d.ts",
|
|
33
|
-
"default": "./dist/json/index.js"
|
|
28
|
+
"./json" : {
|
|
29
|
+
"types" : "./dist/json/index.d.ts",
|
|
30
|
+
"default" : "./dist/json/index.js"
|
|
34
31
|
},
|
|
35
|
-
"./java": {
|
|
36
|
-
"types": "./dist/java/index.d.ts",
|
|
37
|
-
"default": "./dist/java/index.js"
|
|
32
|
+
"./java" : {
|
|
33
|
+
"types" : "./dist/java/index.d.ts",
|
|
34
|
+
"default" : "./dist/java/index.js"
|
|
38
35
|
},
|
|
39
|
-
"./javascript": {
|
|
40
|
-
"types": "./dist/javascript/index.d.ts",
|
|
41
|
-
"default": "./dist/javascript/index.js"
|
|
36
|
+
"./javascript" : {
|
|
37
|
+
"types" : "./dist/javascript/index.d.ts",
|
|
38
|
+
"default" : "./dist/javascript/index.js"
|
|
42
39
|
},
|
|
43
|
-
"./rpc": {
|
|
44
|
-
"types": "./dist/rpc/index.d.ts",
|
|
45
|
-
"default": "./dist/rpc/index.js"
|
|
40
|
+
"./rpc" : {
|
|
41
|
+
"types" : "./dist/rpc/index.d.ts",
|
|
42
|
+
"default" : "./dist/rpc/index.js"
|
|
46
43
|
},
|
|
47
|
-
"./test": {
|
|
48
|
-
"types": "./dist/test/index.d.ts",
|
|
49
|
-
"default": "./dist/test/index.js"
|
|
44
|
+
"./test" : {
|
|
45
|
+
"types" : "./dist/test/index.d.ts",
|
|
46
|
+
"default" : "./dist/test/index.js"
|
|
50
47
|
},
|
|
51
|
-
"./test/java-rpc": {
|
|
52
|
-
"types": "./dist/test/java-rpc.d.ts",
|
|
53
|
-
"default": "./dist/test/java-rpc.js"
|
|
48
|
+
"./test/java-rpc" : {
|
|
49
|
+
"types" : "./dist/test/java-rpc.d.ts",
|
|
50
|
+
"default" : "./dist/test/java-rpc.js"
|
|
54
51
|
},
|
|
55
|
-
"./yaml": {
|
|
56
|
-
"types": "./dist/yaml/index.d.ts",
|
|
57
|
-
"default": "./dist/yaml/index.js"
|
|
52
|
+
"./yaml" : {
|
|
53
|
+
"types" : "./dist/yaml/index.d.ts",
|
|
54
|
+
"default" : "./dist/yaml/index.js"
|
|
58
55
|
}
|
|
59
56
|
},
|
|
60
|
-
"scripts": {
|
|
61
|
-
"prebuild": "bun -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && bun -e \"require('fs').rmSync('tsconfig.build.tsbuildinfo',{force:true})\"",
|
|
62
|
-
"build": "tsc --build tsconfig.build.json",
|
|
63
|
-
"postbuild": "bun -e \"require('fs').chmodSync('dist/rpc/server.js', 0o755); require('fs').chmodSync('dist/javascript/type-report-cli.js', 0o755)\" && npm link --no-audit --no-fund --loglevel=warn",
|
|
64
|
-
"typecheck": "tsc --noEmit -p tsconfig.test.json",
|
|
65
|
-
"dev": "tsc --watch -p tsconfig.json",
|
|
66
|
-
"test": "npm run typecheck && npm run build && vitest run",
|
|
67
|
-
"testhelper": "vitest run",
|
|
68
|
-
"build:fixtures": "tsc --build fixtures/tsconfig.json",
|
|
69
|
-
"start": "npm run build && node ./dist/rpc/server.js"
|
|
57
|
+
"scripts" : {
|
|
58
|
+
"prebuild" : "bun -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && bun -e \"require('fs').rmSync('tsconfig.build.tsbuildinfo',{force:true})\"",
|
|
59
|
+
"build" : "tsc --build tsconfig.build.json",
|
|
60
|
+
"postbuild" : "bun -e \"require('fs').chmodSync('dist/rpc/server.js', 0o755); require('fs').chmodSync('dist/javascript/type-report-cli.js', 0o755)\" && npm link --no-audit --no-fund --loglevel=warn",
|
|
61
|
+
"typecheck" : "tsc --noEmit -p tsconfig.test.json",
|
|
62
|
+
"dev" : "tsc --watch -p tsconfig.json",
|
|
63
|
+
"test" : "npm run typecheck && npm run build && vitest run",
|
|
64
|
+
"testhelper" : "vitest run",
|
|
65
|
+
"build:fixtures" : "tsc --build fixtures/tsconfig.json",
|
|
66
|
+
"start" : "npm run build && node ./dist/rpc/server.js"
|
|
70
67
|
},
|
|
71
|
-
"dependencies": {
|
|
72
|
-
"@akashrajpurohit/snowflake-id": "^2.0.0",
|
|
73
|
-
"@types/node": "^22.5.4",
|
|
74
|
-
"commander": "^10.0.1",
|
|
75
|
-
"diff": "^8.0.0",
|
|
76
|
-
"jsonc-parser": "^3.3.1",
|
|
77
|
-
"mutative": "^1.3.0",
|
|
78
|
-
"picomatch": "
|
|
79
|
-
"semver": "^7.7.4",
|
|
80
|
-
"tmp-promise": "^3.0.3",
|
|
81
|
-
"typescript": "^6.0.3",
|
|
82
|
-
"vscode-jsonrpc": "^8.2.1",
|
|
83
|
-
"yaml": "^2.9.0"
|
|
68
|
+
"dependencies" : {
|
|
69
|
+
"@akashrajpurohit/snowflake-id" : "^2.0.0",
|
|
70
|
+
"@types/node" : "^22.5.4",
|
|
71
|
+
"commander" : "^10.0.1",
|
|
72
|
+
"diff" : "^8.0.0",
|
|
73
|
+
"jsonc-parser" : "^3.3.1",
|
|
74
|
+
"mutative" : "^1.3.0",
|
|
75
|
+
"picomatch" : "4.0.8-backpatch-00001",
|
|
76
|
+
"semver" : "^7.7.4",
|
|
77
|
+
"tmp-promise" : "^3.0.3",
|
|
78
|
+
"typescript" : "^6.0.3",
|
|
79
|
+
"vscode-jsonrpc" : "^8.2.1",
|
|
80
|
+
"yaml" : "^2.9.0"
|
|
84
81
|
},
|
|
85
|
-
"devDependencies": {
|
|
86
|
-
"@types/benchmark": "^2.1.5",
|
|
87
|
-
"@types/diff": "^8.0.0",
|
|
88
|
-
"@types/picomatch": "^4.0.2",
|
|
89
|
-
"@types/semver": "^7.7.1",
|
|
90
|
-
"@types/tmp": "^0.2.6",
|
|
91
|
-
"benchmark": "^2.1.4",
|
|
92
|
-
"bun": "^1.3.5",
|
|
93
|
-
"prettier": "^3.7.4",
|
|
94
|
-
"vitest": "^4.1.8"
|
|
82
|
+
"devDependencies" : {
|
|
83
|
+
"@types/benchmark" : "^2.1.5",
|
|
84
|
+
"@types/diff" : "^8.0.0",
|
|
85
|
+
"@types/picomatch" : "^4.0.2",
|
|
86
|
+
"@types/semver" : "^7.7.1",
|
|
87
|
+
"@types/tmp" : "^0.2.6",
|
|
88
|
+
"benchmark" : "^2.1.4",
|
|
89
|
+
"bun" : "^1.3.5",
|
|
90
|
+
"prettier" : "^3.7.4",
|
|
91
|
+
"vitest" : "^4.1.8"
|
|
95
92
|
},
|
|
96
|
-
"optionalDependencies": {
|
|
97
|
-
"@pyroscope/nodejs": "^0.4.0",
|
|
98
|
-
"prettier": "^3.7.4"
|
|
93
|
+
"optionalDependencies" : {
|
|
94
|
+
"@pyroscope/nodejs" : "^0.4.0",
|
|
95
|
+
"prettier" : "^3.7.4"
|
|
99
96
|
},
|
|
100
|
-
"overrides": {
|
|
101
|
-
"tmp": "^0.2.7",
|
|
102
|
-
"lodash": "^4.18.1"
|
|
97
|
+
"overrides" : {
|
|
98
|
+
"tmp" : "^0.2.7",
|
|
99
|
+
"lodash" : "^4.18.1"
|
|
103
100
|
},
|
|
104
|
-
"bin": {
|
|
105
|
-
"rewrite-rpc": "./dist/rpc/server.js",
|
|
106
|
-
"rewrite-javascript-types": "./dist/javascript/type-report-cli.js"
|
|
107
|
-
}
|
|
108
|
-
|
|
101
|
+
"bin" : {
|
|
102
|
+
"rewrite-rpc" : "./dist/rpc/server.js",
|
|
103
|
+
"rewrite-javascript-types" : "./dist/javascript/type-report-cli.js"
|
|
104
|
+
},
|
|
105
|
+
"bundleDependencies" : [ "picomatch" ]
|
|
106
|
+
}
|
package/src/execution.ts
CHANGED
|
@@ -14,11 +14,15 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import {RpcCodec, RpcCodecs, RpcReceiveQueue, RpcSendQueue} from "./rpc";
|
|
17
|
+
import {registerHeavyweight} from "./heavyweight";
|
|
17
18
|
|
|
18
19
|
export class ExecutionContext {
|
|
19
20
|
/** Mirrors `org.openrewrite.ExecutionContext.REQUIRE_PRINT_EQUALS_INPUT`. */
|
|
20
21
|
static readonly REQUIRE_PRINT_EQUALS_INPUT = "org.openrewrite.requirePrintEqualsInput";
|
|
21
22
|
|
|
23
|
+
/** Mirrors `org.openrewrite.ExecutionContext.SCANNING_MUTATION_VALIDATION`, which the test harness sets. */
|
|
24
|
+
static readonly SCANNING_MUTATION_VALIDATION = "org.openrewrite.test.scanningMutationValidation";
|
|
25
|
+
|
|
22
26
|
readonly kind: string = "org.openrewrite.InMemoryExecutionContext"
|
|
23
27
|
|
|
24
28
|
constructor(public readonly messages: { [key: string | symbol]: any } = {}) {
|
|
@@ -45,6 +49,8 @@ export class ExecutionContext {
|
|
|
45
49
|
}
|
|
46
50
|
}
|
|
47
51
|
|
|
52
|
+
registerHeavyweight(ExecutionContext);
|
|
53
|
+
|
|
48
54
|
const executionContextCodec: RpcCodec<ExecutionContext> = {
|
|
49
55
|
rpcNew(): ExecutionContext {
|
|
50
56
|
return new ExecutionContext();
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 the original author or authors.
|
|
3
|
+
* <p>
|
|
4
|
+
* Licensed under the Moderne Source Available License (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
* <p>
|
|
8
|
+
* https://docs.moderne.io/licensing/moderne-source-available-license
|
|
9
|
+
* <p>
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import {MarkersKind} from "./markers";
|
|
17
|
+
|
|
18
|
+
const heavyweightClasses: Function[] = [];
|
|
19
|
+
const heavyweightKinds = new Set<string>();
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Registers a class, or the kind of a plain object such as a marker, as a type too expensive to keep in memory for a
|
|
23
|
+
* whole run, as in a ScanningRecipe's accumulator.
|
|
24
|
+
*/
|
|
25
|
+
export function registerHeavyweight(type: string | (abstract new (...args: any[]) => unknown)): void {
|
|
26
|
+
if (typeof type === "string") {
|
|
27
|
+
heavyweightKinds.add(type);
|
|
28
|
+
} else if (!heavyweightClasses.includes(type)) {
|
|
29
|
+
heavyweightClasses.push(type);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The registered kind or class that `value` is of, or the kind of a tree, which is always heavyweight. */
|
|
34
|
+
export function heavyweightType(value: object): string | Function | undefined {
|
|
35
|
+
const kind = (value as { kind?: unknown }).kind;
|
|
36
|
+
// a tree has an id and markers, and so do the Markers that hold its markers
|
|
37
|
+
if (typeof kind === "string" && (heavyweightKinds.has(kind) ||
|
|
38
|
+
"id" in value && "markers" in value && kind !== MarkersKind.Markers)) {
|
|
39
|
+
return kind;
|
|
40
|
+
}
|
|
41
|
+
return heavyweightClasses.find(type => value instanceof type);
|
|
42
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -33,6 +33,7 @@ export * from "./util";
|
|
|
33
33
|
export * from "./recipe";
|
|
34
34
|
export * from "./run";
|
|
35
35
|
export * from "./marketplace";
|
|
36
|
+
export {registerHeavyweight} from "./heavyweight";
|
|
36
37
|
|
|
37
38
|
// Install all recipes in this package
|
|
38
39
|
export async function activate(marketplace: RecipeMarketplace): Promise<void> {
|
package/src/java/tree.ts
CHANGED
|
@@ -267,7 +267,7 @@ export namespace J {
|
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
-
export interface Block extends J {
|
|
270
|
+
export interface Block extends J, Statement {
|
|
271
271
|
readonly kind: typeof Kind.Block;
|
|
272
272
|
readonly static: RightPadded<boolean>;
|
|
273
273
|
readonly statements: RightPadded<Statement>[];
|
|
@@ -426,7 +426,7 @@ export namespace J {
|
|
|
426
426
|
}
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
-
export interface Import extends J {
|
|
429
|
+
export interface Import extends J, Statement {
|
|
430
430
|
readonly kind: typeof Kind.Import;
|
|
431
431
|
readonly static: LeftPadded<boolean>;
|
|
432
432
|
readonly qualid: FieldAccess;
|
|
@@ -442,7 +442,7 @@ export namespace J {
|
|
|
442
442
|
readonly modifier?: Modifier;
|
|
443
443
|
}
|
|
444
444
|
|
|
445
|
-
export interface DeconstructionPattern extends J, TypedTree {
|
|
445
|
+
export interface DeconstructionPattern extends J, Expression, TypedTree {
|
|
446
446
|
readonly kind: typeof Kind.DeconstructionPattern;
|
|
447
447
|
readonly deconstructor: Expression;
|
|
448
448
|
readonly nested: Container<J>;
|
|
@@ -490,7 +490,7 @@ export namespace J {
|
|
|
490
490
|
readonly codePoint: string;
|
|
491
491
|
}
|
|
492
492
|
|
|
493
|
-
export interface MemberReference extends J, MethodCall {
|
|
493
|
+
export interface MemberReference extends J, TypedTree, MethodCall {
|
|
494
494
|
readonly kind: typeof Kind.MemberReference;
|
|
495
495
|
readonly containing: RightPadded<Expression>;
|
|
496
496
|
readonly typeParameters?: Container<Expression>;
|
|
@@ -499,7 +499,7 @@ export namespace J {
|
|
|
499
499
|
readonly variableType?: Type.Variable;
|
|
500
500
|
}
|
|
501
501
|
|
|
502
|
-
export interface MethodDeclaration extends J, TypedTree {
|
|
502
|
+
export interface MethodDeclaration extends J, Statement, TypedTree {
|
|
503
503
|
readonly kind: typeof Kind.MethodDeclaration;
|
|
504
504
|
readonly leadingAnnotations: Annotation[];
|
|
505
505
|
readonly modifiers: Modifier[];
|
|
@@ -515,7 +515,7 @@ export namespace J {
|
|
|
515
515
|
readonly methodType?: Type.Method;
|
|
516
516
|
}
|
|
517
517
|
|
|
518
|
-
export interface MethodInvocation extends J, TypedTree, MethodCall {
|
|
518
|
+
export interface MethodInvocation extends J, Statement, TypedTree, MethodCall {
|
|
519
519
|
readonly kind: typeof Kind.MethodInvocation;
|
|
520
520
|
readonly select?: RightPadded<Expression>;
|
|
521
521
|
readonly typeParameters?: Container<Expression>;
|
|
@@ -567,7 +567,7 @@ export namespace J {
|
|
|
567
567
|
readonly type?: Type;
|
|
568
568
|
}
|
|
569
569
|
|
|
570
|
-
export interface NewClass extends J, TypedTree, MethodCall {
|
|
570
|
+
export interface NewClass extends J, Statement, TypedTree, MethodCall {
|
|
571
571
|
readonly kind: typeof Kind.NewClass;
|
|
572
572
|
readonly enclosing?: RightPadded<Expression>;
|
|
573
573
|
readonly new: Space;
|
|
@@ -583,13 +583,13 @@ export namespace J {
|
|
|
583
583
|
readonly typeTree: RightPadded<TypeTree>;
|
|
584
584
|
}
|
|
585
585
|
|
|
586
|
-
export interface Package extends J {
|
|
586
|
+
export interface Package extends J, Statement {
|
|
587
587
|
readonly kind: typeof Kind.Package;
|
|
588
588
|
readonly expression: Expression;
|
|
589
589
|
readonly annotations?: Annotation[];
|
|
590
590
|
}
|
|
591
591
|
|
|
592
|
-
export interface ParameterizedType extends J, TypeTree {
|
|
592
|
+
export interface ParameterizedType extends J, TypeTree, Expression {
|
|
593
593
|
readonly kind: typeof Kind.ParameterizedType;
|
|
594
594
|
readonly class: NameTree;
|
|
595
595
|
readonly typeParameters?: Container<Expression>;
|
|
@@ -711,7 +711,7 @@ export namespace J {
|
|
|
711
711
|
}
|
|
712
712
|
}
|
|
713
713
|
|
|
714
|
-
export interface VariableDeclarations extends J, TypedTree {
|
|
714
|
+
export interface VariableDeclarations extends J, Statement, TypedTree {
|
|
715
715
|
readonly kind: typeof Kind.VariableDeclarations;
|
|
716
716
|
readonly leadingAnnotations: Annotation[];
|
|
717
717
|
readonly modifiers: Modifier[];
|
|
@@ -721,7 +721,7 @@ export namespace J {
|
|
|
721
721
|
}
|
|
722
722
|
|
|
723
723
|
export namespace VariableDeclarations {
|
|
724
|
-
export interface NamedVariable extends J {
|
|
724
|
+
export interface NamedVariable extends J, NameTree {
|
|
725
725
|
readonly kind: typeof Kind.NamedVariable;
|
|
726
726
|
readonly name: VariableDeclarator;
|
|
727
727
|
readonly dimensionsAfterName: LeftPadded<Space>[];
|
package/src/java/visitor.ts
CHANGED
|
@@ -199,6 +199,12 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
199
199
|
}
|
|
200
200
|
assignOp = expression as J.AssignmentOperation;
|
|
201
201
|
|
|
202
|
+
const statement = await this.visitStatement(assignOp, p);
|
|
203
|
+
if (!statement?.kind || statement.kind !== J.Kind.AssignmentOperation) {
|
|
204
|
+
return statement;
|
|
205
|
+
}
|
|
206
|
+
assignOp = statement as J.AssignmentOperation;
|
|
207
|
+
|
|
202
208
|
const updates = {
|
|
203
209
|
prefix: await this.visitSpace(assignOp.prefix, p),
|
|
204
210
|
markers: await this.visitMarkers(assignOp.markers, p),
|
|
@@ -215,6 +221,12 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
215
221
|
if (!expression?.kind || expression.kind !== J.Kind.Binary) {
|
|
216
222
|
return expression;
|
|
217
223
|
}
|
|
224
|
+
const given = this.cursor;
|
|
225
|
+
if (expression !== binary && given.value === binary) {
|
|
226
|
+
// the operands are visited under the binary that holds them, where a template reads their slots
|
|
227
|
+
this.cursor = new Cursor(expression, given.parent);
|
|
228
|
+
given.messages.forEach((value, key) => this.cursor.messages.set(key, value));
|
|
229
|
+
}
|
|
218
230
|
binary = expression as J.Binary;
|
|
219
231
|
|
|
220
232
|
const updates = {
|
|
@@ -225,10 +237,21 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
225
237
|
right: await this.visitDefined(binary.right, p) as Expression,
|
|
226
238
|
type: await this.visitType(binary.type, p)
|
|
227
239
|
};
|
|
240
|
+
if (this.cursor !== given) {
|
|
241
|
+
// what follows reads the cursor of the binary it was given, as for every other tree
|
|
242
|
+
this.cursor.messages.forEach((value, key) => given.messages.set(key, value));
|
|
243
|
+
this.cursor = given;
|
|
244
|
+
}
|
|
228
245
|
return updateIfChanged(binary, updates);
|
|
229
246
|
}
|
|
230
247
|
|
|
231
248
|
protected async visitBlock(block: J.Block, p: P): Promise<J | undefined> {
|
|
249
|
+
const statement = await this.visitStatement(block, p);
|
|
250
|
+
if (!statement?.kind || statement.kind !== J.Kind.Block) {
|
|
251
|
+
return statement;
|
|
252
|
+
}
|
|
253
|
+
block = statement as J.Block;
|
|
254
|
+
|
|
232
255
|
const updates = {
|
|
233
256
|
prefix: await this.visitSpace(block.prefix, p),
|
|
234
257
|
markers: await this.visitMarkers(block.markers, p),
|
|
@@ -340,6 +363,12 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
340
363
|
}
|
|
341
364
|
|
|
342
365
|
protected async visitControlParentheses<T extends J>(controlParens: J.ControlParentheses<T>, p: P): Promise<J | undefined> {
|
|
366
|
+
const expression = await this.visitExpression(controlParens, p);
|
|
367
|
+
if (!expression?.kind || expression.kind !== J.Kind.ControlParentheses) {
|
|
368
|
+
return expression;
|
|
369
|
+
}
|
|
370
|
+
controlParens = expression as J.ControlParentheses<T>;
|
|
371
|
+
|
|
343
372
|
const updates: any = {
|
|
344
373
|
prefix: await this.visitSpace(controlParens.prefix, p),
|
|
345
374
|
markers: await this.visitMarkers(controlParens.markers, p),
|
|
@@ -797,6 +826,12 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
797
826
|
}
|
|
798
827
|
newClass = expression as J.NewClass;
|
|
799
828
|
|
|
829
|
+
const statement = await this.visitStatement(newClass, p);
|
|
830
|
+
if (!statement?.kind || statement.kind !== J.Kind.NewClass) {
|
|
831
|
+
return statement;
|
|
832
|
+
}
|
|
833
|
+
newClass = statement as J.NewClass;
|
|
834
|
+
|
|
800
835
|
const updates: any = {
|
|
801
836
|
prefix: await this.visitSpace(newClass.prefix, p),
|
|
802
837
|
markers: await this.visitMarkers(newClass.markers, p),
|
|
@@ -845,6 +880,12 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
845
880
|
}
|
|
846
881
|
|
|
847
882
|
protected async visitParameterizedType(parameterizedType: J.ParameterizedType, p: P): Promise<J | undefined> {
|
|
883
|
+
const expression = await this.visitExpression(parameterizedType, p);
|
|
884
|
+
if (!expression?.kind || expression.kind !== J.Kind.ParameterizedType) {
|
|
885
|
+
return expression;
|
|
886
|
+
}
|
|
887
|
+
parameterizedType = expression as J.ParameterizedType;
|
|
888
|
+
|
|
848
889
|
const updates: any = {
|
|
849
890
|
prefix: await this.visitSpace(parameterizedType.prefix, p),
|
|
850
891
|
markers: await this.visitMarkers(parameterizedType.markers, p),
|
|
@@ -856,6 +897,12 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
856
897
|
}
|
|
857
898
|
|
|
858
899
|
protected async visitParentheses<T extends J>(parentheses: J.Parentheses<T>, p: P): Promise<J | undefined> {
|
|
900
|
+
const expression = await this.visitExpression(parentheses, p);
|
|
901
|
+
if (!expression?.kind || expression.kind !== J.Kind.Parentheses) {
|
|
902
|
+
return expression;
|
|
903
|
+
}
|
|
904
|
+
parentheses = expression as J.Parentheses<T>;
|
|
905
|
+
|
|
859
906
|
const updates: any = {
|
|
860
907
|
prefix: await this.visitSpace(parentheses.prefix, p),
|
|
861
908
|
markers: await this.visitMarkers(parentheses.markers, p),
|
|
@@ -1205,9 +1252,12 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
1205
1252
|
|
|
1206
1253
|
const updates: any = {
|
|
1207
1254
|
prefix: await this.visitSpace(aYield.prefix, p),
|
|
1208
|
-
markers: await this.visitMarkers(aYield.markers, p)
|
|
1209
|
-
value: await this.visitDefined(aYield.value, p) as Expression
|
|
1255
|
+
markers: await this.visitMarkers(aYield.markers, p)
|
|
1210
1256
|
};
|
|
1257
|
+
// a bare `yield` has no value
|
|
1258
|
+
if (aYield.value) {
|
|
1259
|
+
updates.value = await this.visitDefined(aYield.value, p) as Expression;
|
|
1260
|
+
}
|
|
1211
1261
|
return updateIfChanged(aYield, updates);
|
|
1212
1262
|
}
|
|
1213
1263
|
|
|
@@ -12,6 +12,7 @@ import {bindingNames, compilationUnitOf, cursorOf, declarationsOf, deconflict, i
|
|
|
12
12
|
import {create as produce, Draft} from "mutative";
|
|
13
13
|
import {autoFormat} from "./format";
|
|
14
14
|
import {getPrettierStyle} from "./format/prettier-format";
|
|
15
|
+
import ts from "typescript";
|
|
15
16
|
|
|
16
17
|
export type QuoteChar = "'" | '"';
|
|
17
18
|
|
|
@@ -562,7 +563,8 @@ function claimedName(v: unknown): string | undefined {
|
|
|
562
563
|
/**
|
|
563
564
|
* The parser lifts surrogate pairs out of `valueSource` into `unicodeEscapes` and, when it does,
|
|
564
565
|
* sets `value` to the quoted source (`parser.ts` `mapLiteral`), so neither field alone is the
|
|
565
|
-
* module name. Reuniting them and
|
|
566
|
+
* module name. Reuniting them and reading the quoted text as the language does yields it for
|
|
567
|
+
* either shape of literal.
|
|
566
568
|
*/
|
|
567
569
|
export function moduleNameOf(module: string | J.Literal): string {
|
|
568
570
|
if (typeof module === 'string') {
|
|
@@ -579,6 +581,13 @@ export function moduleNameOf(module: string | J.Literal): string {
|
|
|
579
581
|
cut = escape.valueSourceIndex;
|
|
580
582
|
}
|
|
581
583
|
restored += source.slice(cut);
|
|
584
|
+
// an escape such as `\u00dc` names the character it spells
|
|
585
|
+
const scanner = ts.createScanner(ts.ScriptTarget.Latest, false, ts.LanguageVariant.Standard, restored);
|
|
586
|
+
const token = scanner.scan();
|
|
587
|
+
if ((token === ts.SyntaxKind.StringLiteral || token === ts.SyntaxKind.NoSubstitutionTemplateLiteral) &&
|
|
588
|
+
scanner.getTokenEnd() === restored.length) {
|
|
589
|
+
return scanner.getTokenValue();
|
|
590
|
+
}
|
|
582
591
|
const quote = restored.charAt(0);
|
|
583
592
|
return (quote === "'" || quote === '"' || quote === '`') && restored.endsWith(quote) && restored.length > 1
|
|
584
593
|
? restored.slice(1, -1)
|
|
@@ -1583,7 +1592,7 @@ export class AddImport<P> extends JavaScriptVisitor<P> {
|
|
|
1583
1592
|
value: this.module,
|
|
1584
1593
|
valueSource,
|
|
1585
1594
|
unicodeEscapes: this.moduleUnicodeEscapes,
|
|
1586
|
-
type:
|
|
1595
|
+
type: Type.Primitive.String
|
|
1587
1596
|
};
|
|
1588
1597
|
}
|
|
1589
1598
|
|
package/src/javascript/amd.ts
CHANGED
|
@@ -25,7 +25,8 @@ import {
|
|
|
25
25
|
rightPadded,
|
|
26
26
|
space,
|
|
27
27
|
Statement,
|
|
28
|
-
TrailingComma
|
|
28
|
+
TrailingComma,
|
|
29
|
+
Type
|
|
29
30
|
} from "../java";
|
|
30
31
|
import {JS} from "./tree";
|
|
31
32
|
import {moduleNameOf} from "./add-import";
|
|
@@ -428,7 +429,8 @@ function dependencyLiteral(module: string, quote: string): J.Literal {
|
|
|
428
429
|
prefix: emptySpace,
|
|
429
430
|
markers: emptyMarkers,
|
|
430
431
|
value: module,
|
|
431
|
-
valueSource: `${quote}${module}${quote}
|
|
432
|
+
valueSource: `${quote}${module}${quote}`,
|
|
433
|
+
type: Type.Primitive.String
|
|
432
434
|
};
|
|
433
435
|
}
|
|
434
436
|
|
|
@@ -18,7 +18,7 @@ import {Recipe} from "../../recipe";
|
|
|
18
18
|
import {TreeVisitor} from "../../visitor";
|
|
19
19
|
import {ExecutionContext} from "../../execution";
|
|
20
20
|
import {JavaScriptVisitor} from "../visitor";
|
|
21
|
-
import {J, singleSpace} from "../../java";
|
|
21
|
+
import {J, singleSpace, Type} from "../../java";
|
|
22
22
|
import {emptyMarkers} from "../../markers";
|
|
23
23
|
import {randomId} from "../../uuid";
|
|
24
24
|
|
|
@@ -73,7 +73,7 @@ export class AddParseIntRadix extends Recipe {
|
|
|
73
73
|
value: 10,
|
|
74
74
|
valueSource: '10',
|
|
75
75
|
unicodeEscapes: undefined,
|
|
76
|
-
type:
|
|
76
|
+
type: Type.Primitive.Double
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
return {
|
|
@@ -26,6 +26,7 @@ import {TabsAndIndentsVisitor} from "./tabs-and-indents-visitor";
|
|
|
26
26
|
import {NormalizeWhitespaceVisitor} from "./normalize-whitespace-visitor";
|
|
27
27
|
import {MinimumViableSpacingVisitor} from "./minimum-viable-spacing-visitor";
|
|
28
28
|
import {applyPrettierFormatting, getPrettierStyle} from "./prettier-format";
|
|
29
|
+
import {AsyncLocalStorage} from "node:async_hooks";
|
|
29
30
|
|
|
30
31
|
export {TabsAndIndentsVisitor} from "./tabs-and-indents-visitor";
|
|
31
32
|
export {NormalizeWhitespaceVisitor} from "./normalize-whitespace-visitor";
|
|
@@ -56,6 +57,22 @@ export const autoIndent = async <J2 extends J, P>(j: J2, p: P, parent?: Cursor):
|
|
|
56
57
|
return await new TabsAndIndentsVisitor(style).visit(j, p, parent) as J2;
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Hears about each request to auto-format a tree made while it listens, so that a test harness can check that a
|
|
62
|
+
* recipe formats only what it changed.
|
|
63
|
+
*/
|
|
64
|
+
export interface FormattingListener {
|
|
65
|
+
/** AutoformatVisitor calls this before it formats `tree`, stopping after `stopAfter` when it is given. */
|
|
66
|
+
onFormat(tree: Tree, stopAfter: Tree | undefined, cursor: Cursor | undefined): void;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const formattingListener = new AsyncLocalStorage<FormattingListener>();
|
|
70
|
+
|
|
71
|
+
/** Runs `run`, telling `listener` about the formatting it requests. */
|
|
72
|
+
export function listenToFormatting<T>(listener: FormattingListener, run: () => Promise<T>): Promise<T> {
|
|
73
|
+
return formattingListener.run(listener, run);
|
|
74
|
+
}
|
|
75
|
+
|
|
59
76
|
/**
|
|
60
77
|
* Formats JavaScript/TypeScript code using a comprehensive set of formatting rules.
|
|
61
78
|
*
|
|
@@ -77,6 +94,7 @@ export class AutoformatVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
77
94
|
}
|
|
78
95
|
|
|
79
96
|
async visit<R extends J>(tree: Tree, p: P, cursor?: Cursor): Promise<R | undefined> {
|
|
97
|
+
formattingListener.getStore()?.onFormat(tree, this.stopAfter, cursor);
|
|
80
98
|
const prettierStyle = getPrettierStyle(tree, cursor, this.styles);
|
|
81
99
|
if (prettierStyle) {
|
|
82
100
|
const formatted = await applyPrettierFormatting(tree as R, prettierStyle, p, cursor, this.stopAfter);
|
|
@@ -1121,7 +1139,7 @@ export class BlankLinesVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
1121
1139
|
} else if (parent?.kind === J.Kind.Block && grandparent?.kind !== J.Kind.NewClass && grandparent?.kind !== JS.Kind.TypeLiteral ||
|
|
1122
1140
|
(parent?.kind === JS.Kind.CompilationUnit && (parent! as JS.CompilationUnit).statements[0].element.id != draft.id) ||
|
|
1123
1141
|
(parent?.kind === J.Kind.Case && this.isInsideCaseStatements(parent as J.Case, draft))) {
|
|
1124
|
-
if (draft.kind != J.Kind.Case) {
|
|
1142
|
+
if (draft.kind != J.Kind.Case && !this.opensCaseBody(parent, draft)) {
|
|
1125
1143
|
this.ensurePrefixHasNewLine(draft);
|
|
1126
1144
|
}
|
|
1127
1145
|
}
|
|
@@ -1151,6 +1169,12 @@ export class BlankLinesVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
1151
1169
|
* Check if a statement is inside a Case's statements container or body,
|
|
1152
1170
|
* not inside the caseLabels container.
|
|
1153
1171
|
*/
|
|
1172
|
+
/** A block that opens a case's statements stays on the line of its label, as in `case X: {`. */
|
|
1173
|
+
private opensCaseBody(parent: J | undefined, statement: J): boolean {
|
|
1174
|
+
return parent?.kind === J.Kind.Case && statement.kind === J.Kind.Block &&
|
|
1175
|
+
(parent as J.Case).statements.elements[0]?.element.id === statement.id;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1154
1178
|
private isInsideCaseStatements(caseNode: J.Case, statement: J): boolean {
|
|
1155
1179
|
// Check if statement is in the statements container
|
|
1156
1180
|
if (caseNode.statements.elements.some(s => s.element.id === statement.id)) {
|
|
@@ -408,6 +408,10 @@ export class TabsAndIndentsVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
408
408
|
return literal;
|
|
409
409
|
}
|
|
410
410
|
return produce(literal, draft => {
|
|
411
|
+
// JSX text is its own value, as the parser makes it
|
|
412
|
+
if (draft.value === draft.valueSource) {
|
|
413
|
+
draft.value = normalizedValueSource;
|
|
414
|
+
}
|
|
411
415
|
draft.valueSource = normalizedValueSource;
|
|
412
416
|
});
|
|
413
417
|
}
|
|
@@ -416,6 +416,10 @@ export class WhitespaceReconciler {
|
|
|
416
416
|
original: J.Identifier | J.Literal,
|
|
417
417
|
formatted: J.Identifier | J.Literal
|
|
418
418
|
): J.Identifier | J.Literal {
|
|
419
|
+
// A literal's type follows from how it is written, so an identifier's is not the literal's
|
|
420
|
+
if (isLiteral(formatted)) {
|
|
421
|
+
return formatted;
|
|
422
|
+
}
|
|
419
423
|
const result: Record<string, unknown> = { ...formatted };
|
|
420
424
|
|
|
421
425
|
// Preserve type attribution - both Identifier and Literal have `type`
|