@gi-tcg/gts-transpiler 0.6.2 → 0.6.3
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 +60 -4
- package/package.json +1 -1
- package/src/parse/index.ts +5 -0
- package/src/parse/loose_plugin.ts +76 -2
- package/src/transform/volar/printer.ts +40 -7
package/dist/index.js
CHANGED
|
@@ -70,7 +70,7 @@ function loosePlugin() {
|
|
|
70
70
|
if (this.type.label === "name" || this.type.keyword) return super.parseIdent(liberal);
|
|
71
71
|
else return this.createDummyIdentifier();
|
|
72
72
|
};
|
|
73
|
-
#
|
|
73
|
+
#proxiedThisTrapParseIdent = new Proxy(this, { get: (target, prop) => {
|
|
74
74
|
if (prop === "parseIdent") return this._patchedParseIdent;
|
|
75
75
|
const value = Reflect.get(target, prop);
|
|
76
76
|
if (typeof value === "function") return value.bind(target);
|
|
@@ -83,7 +83,38 @@ function loosePlugin() {
|
|
|
83
83
|
return this.finishNode(dummy, "Identifier");
|
|
84
84
|
}
|
|
85
85
|
parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) {
|
|
86
|
-
return super.parseSubscript.call(this.#
|
|
86
|
+
return super.parseSubscript.call(this.#proxiedThisTrapParseIdent, base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit);
|
|
87
|
+
}
|
|
88
|
+
#proxiedThisTrapEofToRbrace = new Proxy(this, { get: (target, prop) => {
|
|
89
|
+
if (prop === "type" && target.type === tokTypes.eof) return tokTypes.braceR;
|
|
90
|
+
const value = Reflect.get(target, prop);
|
|
91
|
+
if (typeof value === "function") return value.bind(target);
|
|
92
|
+
return value;
|
|
93
|
+
} });
|
|
94
|
+
parseBlock(createNewLexicalScope, node, exitStrict) {
|
|
95
|
+
return super.parseBlock.call(this.#proxiedThisTrapEofToRbrace, createNewLexicalScope, node, exitStrict);
|
|
96
|
+
}
|
|
97
|
+
parseClassStaticBlock(node) {
|
|
98
|
+
return super.parseClassStaticBlock.call(this.#proxiedThisTrapEofToRbrace, node);
|
|
99
|
+
}
|
|
100
|
+
parseSwitchStatement(node) {
|
|
101
|
+
return super.parseSwitchStatement.call(this.#proxiedThisTrapEofToRbrace, node);
|
|
102
|
+
}
|
|
103
|
+
parseStatement(context, topLevel, exports) {
|
|
104
|
+
const { start, startLoc, lastTokEnd, lastTokEndLoc } = this;
|
|
105
|
+
if (topLevel && this.eat(tokTypes.braceR)) {
|
|
106
|
+
const errorNode = this.startNodeAt(start, startLoc);
|
|
107
|
+
errorNode.error = "Unexpected token }";
|
|
108
|
+
return this.finishNode(errorNode, "ErrorStatement");
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
return super.parseStatement(context, topLevel, exports);
|
|
112
|
+
} catch (e) {
|
|
113
|
+
const errorNode = this.startNodeAt(lastTokEnd, lastTokEndLoc);
|
|
114
|
+
errorNode.error = e?.message;
|
|
115
|
+
while (this.type !== tokTypes.eof && this.type !== tokTypes.semi && this.type !== tokTypes.braceR) this.next();
|
|
116
|
+
return this.finishNode(errorNode, "ErrorStatement");
|
|
117
|
+
}
|
|
87
118
|
}
|
|
88
119
|
};
|
|
89
120
|
};
|
|
@@ -537,6 +568,11 @@ function parseLoose(input, options) {
|
|
|
537
568
|
const ast = GtsParser.parse(input, {
|
|
538
569
|
ecmaVersion: "latest",
|
|
539
570
|
sourceType: "module",
|
|
571
|
+
allowImportExportEverywhere: true,
|
|
572
|
+
allowReturnOutsideFunction: true,
|
|
573
|
+
allowAwaitOutsideFunction: true,
|
|
574
|
+
allowSuperOutsideMethod: true,
|
|
575
|
+
checkPrivateFields: false,
|
|
540
576
|
locations: true,
|
|
541
577
|
ranges: true,
|
|
542
578
|
onComment
|
|
@@ -1659,6 +1695,7 @@ function getPrintOptions(source, state) {
|
|
|
1659
1695
|
source,
|
|
1660
1696
|
isUntouched: (node) => {
|
|
1661
1697
|
if (node.type === "Identifier" && node.isDummy) return false;
|
|
1698
|
+
if (node.type === "ErrorStatement") return false;
|
|
1662
1699
|
if (state.attributeNameNodes.has(node)) return false;
|
|
1663
1700
|
return state.sourceNodes.has(node);
|
|
1664
1701
|
},
|
|
@@ -1689,8 +1726,17 @@ function getPrintOptions(source, state) {
|
|
|
1689
1726
|
if (identifier.isDummy && identifier.range) {
|
|
1690
1727
|
const text = state.lastArgNodes.has(identifier) ? "," : "";
|
|
1691
1728
|
let firstNonWhiteSpaceIndex = context.source.slice(identifier.range[1]).search(/\S/);
|
|
1692
|
-
|
|
1693
|
-
|
|
1729
|
+
if (firstNonWhiteSpaceIndex !== 0) {
|
|
1730
|
+
const rangeEnd = firstNonWhiteSpaceIndex === -1 ? context.source.length : identifier.range[1] + firstNonWhiteSpaceIndex;
|
|
1731
|
+
context.writeMapped(text, identifier.range[0], rangeEnd);
|
|
1732
|
+
} else {
|
|
1733
|
+
const rangeEnd = Math.min(node.range[0] + 1, context.source.length);
|
|
1734
|
+
context.createExtraMapping({
|
|
1735
|
+
start: identifier.range[0],
|
|
1736
|
+
end: rangeEnd
|
|
1737
|
+
}, context.generatedOffset, context.generatedOffset + 1, DEFAULT_VOLAR_MAPPING_DATA);
|
|
1738
|
+
context.write(text);
|
|
1739
|
+
}
|
|
1694
1740
|
} else if (identifier.range && state.attributeNameNodes.has(identifier)) context.writeMapped(identifier.name, identifier.range[0], identifier.range[1], ATTRIBUTE_NAME_MAPPING_DATA);
|
|
1695
1741
|
else defaultPrinters.Identifier(node, context);
|
|
1696
1742
|
},
|
|
@@ -1740,6 +1786,16 @@ function getPrintOptions(source, state) {
|
|
|
1740
1786
|
context.write(".");
|
|
1741
1787
|
context.writeSource(node.whiteSpaceStart, node.whiteSpaceEnd);
|
|
1742
1788
|
context.write(";");
|
|
1789
|
+
},
|
|
1790
|
+
ErrorStatement(node, context) {
|
|
1791
|
+
if (node.range) {
|
|
1792
|
+
context.writePreservedNode(node);
|
|
1793
|
+
const rangeEnd = Math.min(node.range[1] + 1, context.source.length);
|
|
1794
|
+
context.createExtraMapping({
|
|
1795
|
+
start: node.range[1],
|
|
1796
|
+
end: rangeEnd
|
|
1797
|
+
}, context.generatedOffset, context.generatedOffset + 1, VERIFICATION_ONLY_MAPPING_DATA);
|
|
1798
|
+
} else context.write(`((_: never) => 0)(${JSON.stringify(node.error ?? "Unknown error")});`);
|
|
1743
1799
|
}
|
|
1744
1800
|
},
|
|
1745
1801
|
experimentalGetLeftParenSourceRange: (node) => {
|
package/package.json
CHANGED
package/src/parse/index.ts
CHANGED
|
@@ -59,6 +59,11 @@ export function parseLoose(
|
|
|
59
59
|
const ast = GtsParser.parse(input, {
|
|
60
60
|
ecmaVersion: "latest",
|
|
61
61
|
sourceType: "module",
|
|
62
|
+
allowImportExportEverywhere: true,
|
|
63
|
+
allowReturnOutsideFunction: true,
|
|
64
|
+
allowAwaitOutsideFunction: true,
|
|
65
|
+
allowSuperOutsideMethod: true,
|
|
66
|
+
checkPrivateFields: false,
|
|
62
67
|
locations: true,
|
|
63
68
|
ranges: true,
|
|
64
69
|
onComment,
|
|
@@ -15,7 +15,7 @@ export function loosePlugin() {
|
|
|
15
15
|
return this.createDummyIdentifier();
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
|
-
readonly #
|
|
18
|
+
readonly #proxiedThisTrapParseIdent = new Proxy(this, {
|
|
19
19
|
get: (target, prop) => {
|
|
20
20
|
if (prop === "parseIdent") {
|
|
21
21
|
return this._patchedParseIdent;
|
|
@@ -48,7 +48,7 @@ export function loosePlugin() {
|
|
|
48
48
|
forInit?: boolean | "await",
|
|
49
49
|
): AST.Expression {
|
|
50
50
|
return super.parseSubscript.call(
|
|
51
|
-
this.#
|
|
51
|
+
this.#proxiedThisTrapParseIdent,
|
|
52
52
|
base,
|
|
53
53
|
startPos,
|
|
54
54
|
startLoc,
|
|
@@ -58,6 +58,80 @@ export function loosePlugin() {
|
|
|
58
58
|
forInit,
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
|
+
|
|
62
|
+
// Parsing block statements typically has:
|
|
63
|
+
// ```js
|
|
64
|
+
// while (this.type !== tokTypes.braceR) {
|
|
65
|
+
// this.parseStatement();
|
|
66
|
+
// }
|
|
67
|
+
// ```
|
|
68
|
+
// But what happens if the next token is EOF? Since we tolerate errors inside `parseStatement`,
|
|
69
|
+
// it can fall into an infinite loop. To avoid this, we use a proxy to trap `this.type`
|
|
70
|
+
// access and return a fake `braceR` when the current token is EOF.
|
|
71
|
+
readonly #proxiedThisTrapEofToRbrace = new Proxy(this, {
|
|
72
|
+
get: (target, prop) => {
|
|
73
|
+
if (prop === "type" && target.type === tokTypes.eof) {
|
|
74
|
+
return tokTypes.braceR;
|
|
75
|
+
}
|
|
76
|
+
const value = Reflect.get(target, prop);
|
|
77
|
+
if (typeof value === "function") {
|
|
78
|
+
return value.bind(target);
|
|
79
|
+
}
|
|
80
|
+
return value;
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
override parseBlock(
|
|
85
|
+
createNewLexicalScope?: boolean,
|
|
86
|
+
node?: AST.BlockStatement,
|
|
87
|
+
exitStrict?: boolean,
|
|
88
|
+
): AST.BlockStatement {
|
|
89
|
+
return super.parseBlock.call(
|
|
90
|
+
this.#proxiedThisTrapEofToRbrace,
|
|
91
|
+
createNewLexicalScope,
|
|
92
|
+
node,
|
|
93
|
+
exitStrict,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
override parseClassStaticBlock(node: AST.Node): AST.StaticBlock {
|
|
97
|
+
return super.parseClassStaticBlock.call(
|
|
98
|
+
this.#proxiedThisTrapEofToRbrace,
|
|
99
|
+
node,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
override parseSwitchStatement(node: AST.Node): AST.SwitchStatement {
|
|
103
|
+
return super.parseSwitchStatement.call(
|
|
104
|
+
this.#proxiedThisTrapEofToRbrace,
|
|
105
|
+
node,
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
override parseStatement(
|
|
110
|
+
context?: string | null,
|
|
111
|
+
topLevel?: boolean,
|
|
112
|
+
exports?: AST.ExportSpecifier,
|
|
113
|
+
): AST.ExpressionStatement | AST.Statement | AST.GTSDefineStatement {
|
|
114
|
+
const { start, startLoc, lastTokEnd, lastTokEndLoc } = this;
|
|
115
|
+
if (topLevel && this.eat(tokTypes.braceR)) {
|
|
116
|
+
const errorNode: any = this.startNodeAt(start, startLoc);
|
|
117
|
+
errorNode.error = "Unexpected token }";
|
|
118
|
+
return this.finishNode(errorNode, "ErrorStatement");
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
return super.parseStatement(context, topLevel, exports);
|
|
122
|
+
} catch (e) {
|
|
123
|
+
const errorNode: any = this.startNodeAt(lastTokEnd, lastTokEndLoc);
|
|
124
|
+
errorNode.error = (e as Error)?.message;
|
|
125
|
+
while (
|
|
126
|
+
this.type !== tokTypes.eof &&
|
|
127
|
+
this.type !== tokTypes.semi &&
|
|
128
|
+
this.type !== tokTypes.braceR
|
|
129
|
+
) {
|
|
130
|
+
this.next();
|
|
131
|
+
}
|
|
132
|
+
return this.finishNode(errorNode, "ErrorStatement");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
61
135
|
};
|
|
62
136
|
};
|
|
63
137
|
}
|
|
@@ -35,12 +35,15 @@ export function getPrintOptions(
|
|
|
35
35
|
if (node.type === "Identifier" && (node as Identifier).isDummy) {
|
|
36
36
|
return false;
|
|
37
37
|
}
|
|
38
|
+
if ((node.type as string) === "ErrorStatement") {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
38
41
|
if (state.attributeNameNodes.has(node as Identifier | Literal)) {
|
|
39
42
|
return false;
|
|
40
43
|
}
|
|
41
44
|
return state.sourceNodes.has(node as Node);
|
|
42
45
|
},
|
|
43
|
-
|
|
46
|
+
|
|
44
47
|
printCommentsOnUntouchedNodes: true,
|
|
45
48
|
getLeadingComments: (node) => (node as Node).leadingComments,
|
|
46
49
|
getTrailingComments: (node) => (node as Node).trailingComments,
|
|
@@ -111,15 +114,28 @@ export function getPrintOptions(
|
|
|
111
114
|
const identifier = node as Identifier;
|
|
112
115
|
if (identifier.isDummy && identifier.range) {
|
|
113
116
|
const text = state.lastArgNodes.has(identifier) ? "," : "";
|
|
114
|
-
// extend the source mapping of dummy id
|
|
117
|
+
// extend the source mapping of dummy id.
|
|
115
118
|
let firstNonWhiteSpaceIndex = context.source
|
|
116
119
|
.slice(identifier.range[1])
|
|
117
120
|
.search(/\S/);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
if (firstNonWhiteSpaceIndex !== 0) {
|
|
122
|
+
// a) if next char-seq is whitespaces, write them as mapped
|
|
123
|
+
const rangeEnd =
|
|
124
|
+
firstNonWhiteSpaceIndex === -1
|
|
125
|
+
? context.source.length
|
|
126
|
+
: identifier.range[1] + firstNonWhiteSpaceIndex;
|
|
127
|
+
context.writeMapped(text, identifier.range[0], rangeEnd);
|
|
128
|
+
} else {
|
|
129
|
+
// b) otherwise create extra mapping directly for next character
|
|
130
|
+
const rangeEnd = Math.min(node.range[0] + 1, context.source.length);
|
|
131
|
+
context.createExtraMapping(
|
|
132
|
+
{ start: identifier.range[0], end: rangeEnd },
|
|
133
|
+
context.generatedOffset,
|
|
134
|
+
context.generatedOffset + 1,
|
|
135
|
+
DEFAULT_VOLAR_MAPPING_DATA,
|
|
136
|
+
);
|
|
137
|
+
context.write(text);
|
|
138
|
+
}
|
|
123
139
|
} else if (
|
|
124
140
|
identifier.range &&
|
|
125
141
|
state.attributeNameNodes.has(identifier)
|
|
@@ -222,6 +238,23 @@ export function getPrintOptions(
|
|
|
222
238
|
context.writeSource(node.whiteSpaceStart, node.whiteSpaceEnd);
|
|
223
239
|
context.write(";");
|
|
224
240
|
},
|
|
241
|
+
ErrorStatement(node: any, context: PrinterContext<CodeInformation>) {
|
|
242
|
+
if (node.range) {
|
|
243
|
+
context.writePreservedNode(node);
|
|
244
|
+
const rangeEnd = Math.min(node.range[1] + 1, context.source.length);
|
|
245
|
+
context.createExtraMapping(
|
|
246
|
+
{ start: node.range[1], end: rangeEnd },
|
|
247
|
+
context.generatedOffset,
|
|
248
|
+
context.generatedOffset + 1,
|
|
249
|
+
VERIFICATION_ONLY_MAPPING_DATA,
|
|
250
|
+
);
|
|
251
|
+
} else {
|
|
252
|
+
// Emit a TS error indicate the error. This should not happen.
|
|
253
|
+
context.write(
|
|
254
|
+
`((_: never) => 0)(${JSON.stringify(node.error ?? "Unknown error")});`,
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
},
|
|
225
258
|
},
|
|
226
259
|
// Enable triggering signature completion
|
|
227
260
|
experimentalGetLeftParenSourceRange: (node) => {
|