@gi-tcg/gts-transpiler 0.3.2 → 0.3.4
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.d.ts +1 -1
- package/dist/index.js +351 -458
- package/package.json +6 -4
- package/src/parse/gts_plugin.ts +2 -2
- package/src/parse/index.ts +2 -0
- package/src/parse/loose_plugin.ts +1 -1
- package/src/parse/record_call_lparen_plugin.ts +17 -20
- package/src/transform/gts.ts +26 -71
- package/src/transform/index.ts +3 -3
- package/src/transform/volar/collect_tokens.ts +28 -34
- package/src/transform/volar/content_start.ts +69 -0
- package/src/transform/volar/index.ts +70 -45
- package/src/transform/volar/mappings.ts +5 -352
- package/src/transform/volar/printer.ts +139 -117
- package/src/transform/volar/replacements.ts +75 -47
- package/src/transform/volar/walker.ts +123 -81
- package/src/types.ts +3 -9
package/dist/index.js
CHANGED
|
@@ -3,7 +3,8 @@ import { tsPlugin } from "@sveltejs/acorn-typescript";
|
|
|
3
3
|
import { walk } from "zimmerframe";
|
|
4
4
|
import { print } from "esrap";
|
|
5
5
|
import jsPrinter from "esrap/languages/ts";
|
|
6
|
-
import {
|
|
6
|
+
import { defaultPrinters, print as print$1 } from "espolar";
|
|
7
|
+
import dedent from "dedent";
|
|
7
8
|
import path from "path-browserify-esm";
|
|
8
9
|
//#region src/keywords.ts
|
|
9
10
|
const specialIdentifiers = [
|
|
@@ -77,7 +78,7 @@ function loosePlugin() {
|
|
|
77
78
|
return value;
|
|
78
79
|
} });
|
|
79
80
|
createDummyIdentifier() {
|
|
80
|
-
const dummy = this.
|
|
81
|
+
const dummy = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc);
|
|
81
82
|
dummy.name = "✖";
|
|
82
83
|
dummy.isDummy = true;
|
|
83
84
|
return this.finishNode(dummy, "Identifier");
|
|
@@ -197,7 +198,7 @@ function gtsPlugin(options = {}) {
|
|
|
197
198
|
return this.gts_parseShortcutFunction();
|
|
198
199
|
}
|
|
199
200
|
if (this.gtsOptions.allowEmptyPositionalAttribute && (this.type === tokTypes.comma || this.type === tokTypes.braceR || this.type === tokTypes.semi || this.canInsertSemicolon() || this.isContextual("as"))) {
|
|
200
|
-
const dummy = this.
|
|
201
|
+
const dummy = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc);
|
|
201
202
|
dummy.name = "✖";
|
|
202
203
|
dummy.isDummy = true;
|
|
203
204
|
return this.finishNode(dummy, "Identifier");
|
|
@@ -228,7 +229,7 @@ function gtsPlugin(options = {}) {
|
|
|
228
229
|
const node = this.startNode();
|
|
229
230
|
this.next();
|
|
230
231
|
if (this.gtsOptions.allowEmptyShortcutMember && this.type !== tokTypes.name) {
|
|
231
|
-
const dummy = this.
|
|
232
|
+
const dummy = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc);
|
|
232
233
|
dummy.name = "✖";
|
|
233
234
|
dummy.isDummy = true;
|
|
234
235
|
node.property = this.finishNode(dummy, "Identifier");
|
|
@@ -475,35 +476,29 @@ var GtsTranspilerError = class extends Error {
|
|
|
475
476
|
//#endregion
|
|
476
477
|
//#region src/parse/record_call_lparen_plugin.ts
|
|
477
478
|
/**
|
|
478
|
-
* A plugin that records the location of the left parenthesis in CallExpression and
|
|
479
|
+
* A plugin that records the location of the left parenthesis in CallExpression and
|
|
479
480
|
* NewExpression.
|
|
480
|
-
*
|
|
481
|
-
* This is useful for Language tooling, that we can maps the '(' token from its location,
|
|
482
|
-
* to provide * a signature help for user when they press `(` after a function name.
|
|
483
481
|
*
|
|
484
|
-
*
|
|
482
|
+
* This is useful for Language tooling, that we can maps the '(' token from its location,
|
|
483
|
+
* to provide a signature help for user when they press `(` after a function name.
|
|
484
|
+
*
|
|
485
|
+
* The recorded location will be stored in `lParenLoc` property of the
|
|
485
486
|
* CallExpression/NewExpression node.
|
|
486
|
-
* @returns
|
|
487
|
+
* @returns the plugin function
|
|
487
488
|
*/
|
|
488
489
|
function recordCallLParenPlugin() {
|
|
489
490
|
return function recordCallLParenPluginTransformer(parser) {
|
|
490
491
|
return class RecordCallLParenParser extends parser {
|
|
491
492
|
parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) {
|
|
492
493
|
let recordedLParenLoc = null;
|
|
493
|
-
if (!noCalls && this.type === tokTypes.parenL) recordedLParenLoc =
|
|
494
|
-
start: this.startLoc,
|
|
495
|
-
end: this.endLoc
|
|
496
|
-
};
|
|
494
|
+
if (!noCalls && this.type === tokTypes.parenL) recordedLParenLoc = [this.start, this.end];
|
|
497
495
|
const result = super.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit);
|
|
498
|
-
if (recordedLParenLoc && result.type === "CallExpression") result.
|
|
496
|
+
if (recordedLParenLoc && result.type === "CallExpression") result.lParenRange = recordedLParenLoc;
|
|
499
497
|
return result;
|
|
500
498
|
}
|
|
501
|
-
|
|
499
|
+
_capturedLParenRangeFromNew = null;
|
|
502
500
|
_patchedEat = (type) => {
|
|
503
|
-
if (type === tokTypes.parenL) this.
|
|
504
|
-
start: this.startLoc,
|
|
505
|
-
end: this.endLoc
|
|
506
|
-
};
|
|
501
|
+
if (type === tokTypes.parenL) this._capturedLParenRangeFromNew = [this.start, this.end];
|
|
507
502
|
return this.eat(type);
|
|
508
503
|
};
|
|
509
504
|
#proxiedThis = new Proxy(this, { get: (target, prop) => {
|
|
@@ -514,9 +509,9 @@ function recordCallLParenPlugin() {
|
|
|
514
509
|
} });
|
|
515
510
|
parseNew() {
|
|
516
511
|
const result = super.parseNew.apply(this.#proxiedThis);
|
|
517
|
-
if (this.
|
|
518
|
-
result.
|
|
519
|
-
this.
|
|
512
|
+
if (this._capturedLParenRangeFromNew && result.type === "NewExpression") {
|
|
513
|
+
result.lParenRange = this._capturedLParenRangeFromNew;
|
|
514
|
+
this._capturedLParenRangeFromNew = null;
|
|
520
515
|
}
|
|
521
516
|
return result;
|
|
522
517
|
}
|
|
@@ -531,7 +526,8 @@ function parse(input, options) {
|
|
|
531
526
|
return TsParser.extend(gtsPlugin(options)).parse(input, {
|
|
532
527
|
ecmaVersion: "latest",
|
|
533
528
|
sourceType: "module",
|
|
534
|
-
locations: true
|
|
529
|
+
locations: true,
|
|
530
|
+
ranges: true
|
|
535
531
|
});
|
|
536
532
|
} catch (e) {
|
|
537
533
|
if (e instanceof SyntaxError && "loc" in e) {
|
|
@@ -557,6 +553,7 @@ function parseLoose(input, options) {
|
|
|
557
553
|
ecmaVersion: "latest",
|
|
558
554
|
sourceType: "module",
|
|
559
555
|
locations: true,
|
|
556
|
+
ranges: true,
|
|
560
557
|
onComment
|
|
561
558
|
});
|
|
562
559
|
addComments(ast);
|
|
@@ -744,7 +741,8 @@ const commonGtsVisitor = {
|
|
|
744
741
|
method: false,
|
|
745
742
|
shorthand: false,
|
|
746
743
|
value: state.ActionLit,
|
|
747
|
-
loc: node.loc
|
|
744
|
+
loc: node.loc,
|
|
745
|
+
range: node.range
|
|
748
746
|
},
|
|
749
747
|
{
|
|
750
748
|
type: "Property",
|
|
@@ -790,7 +788,8 @@ const commonGtsVisitor = {
|
|
|
790
788
|
}
|
|
791
789
|
}
|
|
792
790
|
],
|
|
793
|
-
loc: node.loc
|
|
791
|
+
loc: node.loc,
|
|
792
|
+
range: node.range
|
|
794
793
|
};
|
|
795
794
|
},
|
|
796
795
|
GTSShortcutFunctionExpression(node, { visit, state }) {
|
|
@@ -799,7 +798,8 @@ const commonGtsVisitor = {
|
|
|
799
798
|
params: state.shortcutFunctionParameters,
|
|
800
799
|
body: visit(node.body),
|
|
801
800
|
expression: node.expression,
|
|
802
|
-
loc: node.loc
|
|
801
|
+
loc: node.loc,
|
|
802
|
+
range: node.range
|
|
803
803
|
};
|
|
804
804
|
},
|
|
805
805
|
GTSShortcutArgumentExpression(node, { state, visit }) {
|
|
@@ -809,50 +809,29 @@ const commonGtsVisitor = {
|
|
|
809
809
|
computed: false,
|
|
810
810
|
optional: false,
|
|
811
811
|
property: visit(node.property),
|
|
812
|
-
loc: node.loc
|
|
812
|
+
loc: node.loc,
|
|
813
|
+
range: node.range
|
|
813
814
|
};
|
|
814
815
|
},
|
|
815
816
|
GTSQueryExpression(node, { state, visit }) {
|
|
816
|
-
state.hasQueryExpressions = true;
|
|
817
817
|
return {
|
|
818
818
|
...node,
|
|
819
819
|
type: "CallExpression",
|
|
820
820
|
optional: false,
|
|
821
|
-
callee:
|
|
821
|
+
callee: {
|
|
822
|
+
type: "MemberExpression",
|
|
823
|
+
object: state.fnArgId,
|
|
824
|
+
property: node.star ? state.QueryAllLit : state.QueryLit,
|
|
825
|
+
computed: true,
|
|
826
|
+
optional: false
|
|
827
|
+
},
|
|
822
828
|
arguments: [{
|
|
823
829
|
type: "ArrowFunctionExpression",
|
|
824
830
|
body: visit(node.argument),
|
|
825
831
|
params: state.queryParameters,
|
|
826
832
|
expression: true,
|
|
827
|
-
loc: node.argument.loc
|
|
828
|
-
|
|
829
|
-
type: "ObjectExpression",
|
|
830
|
-
properties: [{
|
|
831
|
-
type: "Property",
|
|
832
|
-
key: {
|
|
833
|
-
type: "Identifier",
|
|
834
|
-
name: "star"
|
|
835
|
-
},
|
|
836
|
-
computed: false,
|
|
837
|
-
kind: "init",
|
|
838
|
-
method: false,
|
|
839
|
-
shorthand: false,
|
|
840
|
-
value: {
|
|
841
|
-
type: "Literal",
|
|
842
|
-
value: !!node.star
|
|
843
|
-
}
|
|
844
|
-
}, {
|
|
845
|
-
type: "Property",
|
|
846
|
-
key: {
|
|
847
|
-
type: "Identifier",
|
|
848
|
-
name: "context"
|
|
849
|
-
},
|
|
850
|
-
computed: false,
|
|
851
|
-
kind: "init",
|
|
852
|
-
method: false,
|
|
853
|
-
shorthand: false,
|
|
854
|
-
value: state.fnArgId
|
|
855
|
-
}]
|
|
833
|
+
loc: node.argument.loc,
|
|
834
|
+
range: node.argument.range
|
|
856
835
|
}]
|
|
857
836
|
};
|
|
858
837
|
}
|
|
@@ -866,18 +845,6 @@ const gtsVisitor = {
|
|
|
866
845
|
}
|
|
867
846
|
body.unshift(...state.bindingStatements);
|
|
868
847
|
state.bindingStatements = [];
|
|
869
|
-
if (state.hasQueryExpressions) body.unshift({
|
|
870
|
-
type: "ImportDeclaration",
|
|
871
|
-
specifiers: [{
|
|
872
|
-
type: "ImportDefaultSpecifier",
|
|
873
|
-
local: state.queryFnId
|
|
874
|
-
}],
|
|
875
|
-
source: {
|
|
876
|
-
type: "Literal",
|
|
877
|
-
value: `${state.providerImportSource}/query`
|
|
878
|
-
},
|
|
879
|
-
attributes: []
|
|
880
|
-
});
|
|
881
848
|
body.unshift({
|
|
882
849
|
type: "ImportDeclaration",
|
|
883
850
|
specifiers: [{
|
|
@@ -938,7 +905,8 @@ const gtsVisitor = {
|
|
|
938
905
|
id: nodeVarId,
|
|
939
906
|
init: rootAttr
|
|
940
907
|
}],
|
|
941
|
-
loc: node.loc
|
|
908
|
+
loc: node.loc,
|
|
909
|
+
range: node.range
|
|
942
910
|
});
|
|
943
911
|
state.bindingStatements.push({
|
|
944
912
|
type: "VariableDeclaration",
|
|
@@ -953,7 +921,8 @@ const gtsVisitor = {
|
|
|
953
921
|
arguments: [state.rootVmId, nodeVarId]
|
|
954
922
|
}
|
|
955
923
|
}],
|
|
956
|
-
loc: node.loc
|
|
924
|
+
loc: node.loc,
|
|
925
|
+
range: node.range
|
|
957
926
|
});
|
|
958
927
|
for (let i = 0; i < newBindings.length; i++) {
|
|
959
928
|
const binding = newBindings[i];
|
|
@@ -991,7 +960,8 @@ const gtsVisitor = {
|
|
|
991
960
|
callee: state.createDefineFnId,
|
|
992
961
|
arguments: [state.rootVmId, nodeVarId]
|
|
993
962
|
},
|
|
994
|
-
loc: node.loc
|
|
963
|
+
loc: node.loc,
|
|
964
|
+
range: node.range
|
|
995
965
|
};
|
|
996
966
|
},
|
|
997
967
|
GTSNamedAttributeDefinition(node, { visit, state }) {
|
|
@@ -1013,7 +983,8 @@ const gtsVisitor = {
|
|
|
1013
983
|
method: false,
|
|
1014
984
|
shorthand: false,
|
|
1015
985
|
value: nameValue,
|
|
1016
|
-
loc: node.loc
|
|
986
|
+
loc: node.loc,
|
|
987
|
+
range: node.range
|
|
1017
988
|
});
|
|
1018
989
|
const body = {
|
|
1019
990
|
...namedBody,
|
|
@@ -1067,9 +1038,11 @@ const gtsVisitor = {
|
|
|
1067
1038
|
params: [],
|
|
1068
1039
|
body: positionals,
|
|
1069
1040
|
expression: true,
|
|
1070
|
-
loc: positionals.loc
|
|
1041
|
+
loc: positionals.loc,
|
|
1042
|
+
range: positionals.range
|
|
1071
1043
|
},
|
|
1072
|
-
loc: positionals.loc
|
|
1044
|
+
loc: positionals.loc,
|
|
1045
|
+
range: positionals.range
|
|
1073
1046
|
}, {
|
|
1074
1047
|
type: "Property",
|
|
1075
1048
|
key: {
|
|
@@ -1081,9 +1054,11 @@ const gtsVisitor = {
|
|
|
1081
1054
|
method: false,
|
|
1082
1055
|
shorthand: false,
|
|
1083
1056
|
value: named,
|
|
1084
|
-
loc: named.loc
|
|
1057
|
+
loc: named.loc,
|
|
1058
|
+
range: named.range
|
|
1085
1059
|
}],
|
|
1086
|
-
loc: node.loc
|
|
1060
|
+
loc: node.loc,
|
|
1061
|
+
range: node.range
|
|
1087
1062
|
};
|
|
1088
1063
|
},
|
|
1089
1064
|
GTSPositionalAttributeList(node, { visit }) {
|
|
@@ -1097,7 +1072,8 @@ const gtsVisitor = {
|
|
|
1097
1072
|
};
|
|
1098
1073
|
else return visit(attr);
|
|
1099
1074
|
}),
|
|
1100
|
-
loc: node.loc
|
|
1075
|
+
loc: node.loc,
|
|
1076
|
+
range: node.range
|
|
1101
1077
|
};
|
|
1102
1078
|
},
|
|
1103
1079
|
GTSNamedAttributeBlock(node, { visit }) {
|
|
@@ -1120,7 +1096,8 @@ const gtsVisitor = {
|
|
|
1120
1096
|
elements: attributes
|
|
1121
1097
|
}
|
|
1122
1098
|
}],
|
|
1123
|
-
loc: node.loc
|
|
1099
|
+
loc: node.loc,
|
|
1100
|
+
range: node.range
|
|
1124
1101
|
};
|
|
1125
1102
|
},
|
|
1126
1103
|
...commonGtsVisitor
|
|
@@ -1183,10 +1160,6 @@ const initialTranspileState = (option = {}) => {
|
|
|
1183
1160
|
type: "Identifier",
|
|
1184
1161
|
name: "__gts_rootVm"
|
|
1185
1162
|
},
|
|
1186
|
-
queryFnId: {
|
|
1187
|
-
type: "Identifier",
|
|
1188
|
-
name: "__gts_query"
|
|
1189
|
-
},
|
|
1190
1163
|
queryParameters: [{
|
|
1191
1164
|
type: "ObjectPattern",
|
|
1192
1165
|
properties: queryBindings.map((name) => ({
|
|
@@ -1205,28 +1178,17 @@ const initialTranspileState = (option = {}) => {
|
|
|
1205
1178
|
shorthand: true
|
|
1206
1179
|
}))
|
|
1207
1180
|
}],
|
|
1181
|
+
QueryLit: {
|
|
1182
|
+
type: "Literal",
|
|
1183
|
+
value: "~query"
|
|
1184
|
+
},
|
|
1185
|
+
QueryAllLit: {
|
|
1186
|
+
type: "Literal",
|
|
1187
|
+
value: "~queryAll"
|
|
1188
|
+
},
|
|
1208
1189
|
runtimeImportSource: option.runtimeImportSource ?? "@gi-tcg/gts-runtime",
|
|
1209
1190
|
providerImportSource: option.providerImportSource ?? "@gi-tcg/core/gts",
|
|
1210
|
-
queryArg: {
|
|
1211
|
-
type: "ObjectPattern",
|
|
1212
|
-
properties: (option.queryBindings ?? []).map((name) => ({
|
|
1213
|
-
type: "Property",
|
|
1214
|
-
key: {
|
|
1215
|
-
type: "Identifier",
|
|
1216
|
-
name
|
|
1217
|
-
},
|
|
1218
|
-
computed: false,
|
|
1219
|
-
kind: "init",
|
|
1220
|
-
method: false,
|
|
1221
|
-
shorthand: true,
|
|
1222
|
-
value: {
|
|
1223
|
-
type: "Identifier",
|
|
1224
|
-
name
|
|
1225
|
-
}
|
|
1226
|
-
}))
|
|
1227
|
-
},
|
|
1228
1191
|
externalizedBindings: [],
|
|
1229
|
-
hasQueryExpressions: false,
|
|
1230
1192
|
defineIdCounter: 0,
|
|
1231
1193
|
bindingStatements: []
|
|
1232
1194
|
};
|
|
@@ -1255,25 +1217,26 @@ const createReplacementHolder = (state, value) => {
|
|
|
1255
1217
|
}
|
|
1256
1218
|
};
|
|
1257
1219
|
};
|
|
1258
|
-
function applyReplacements(state, code) {
|
|
1259
|
-
const replacementRegex = new RegExp("\\b" + state.replacementTag.name + "`(.*?)`", "gm");
|
|
1220
|
+
function applyReplacements(state, code, mappings) {
|
|
1221
|
+
const replacementRegex = new RegExp("\\b" + state.replacementTag.name + "`(.*?)(?<!\\\\)`", "gm");
|
|
1260
1222
|
const { NamedDefinitionLit, MetaLit } = state;
|
|
1261
1223
|
const NamedDefinition = JSON.stringify(NamedDefinitionLit.value);
|
|
1262
1224
|
const Meta = JSON.stringify(MetaLit.value);
|
|
1263
|
-
const
|
|
1264
|
-
|
|
1265
|
-
const payload = JSON.parse(rawPayload);
|
|
1266
|
-
|
|
1225
|
+
const matchInfos = [];
|
|
1226
|
+
const result = code.replace(replacementRegex, (match, rawPayload, offset) => {
|
|
1227
|
+
const payload = JSON.parse(rawPayload.replace(/\\`/g, "`"));
|
|
1228
|
+
let replacement;
|
|
1229
|
+
if (payload.type === "preface") replacement = dedent`
|
|
1267
1230
|
namespace ${state.utilNsId.name} {
|
|
1268
1231
|
export type UniqueKeyProbSegment = "__gts_unique_prob_seg__";
|
|
1269
1232
|
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
1270
1233
|
}
|
|
1271
1234
|
`;
|
|
1272
|
-
else if (payload.type === "enterVMFromRoot")
|
|
1235
|
+
else if (payload.type === "enterVMFromRoot") replacement = dedent`
|
|
1273
1236
|
type ${payload.defType} = (typeof ${payload.vm})[${NamedDefinition}];
|
|
1274
1237
|
type ${payload.metaType} = ${payload.defType}[${Meta}];
|
|
1275
1238
|
`;
|
|
1276
|
-
else if (payload.type === "enterVMFromAttr")
|
|
1239
|
+
else if (payload.type === "enterVMFromAttr") replacement = dedent`
|
|
1277
1240
|
type ${payload.defType} = ${payload.returnType} extends { namedDefinition: infer Def } ? Def : { ${Meta}: unknown };
|
|
1278
1241
|
type ${payload.metaType} = ${payload.defType}[${Meta}];
|
|
1279
1242
|
`;
|
|
@@ -1282,8 +1245,12 @@ function applyReplacements(state, code) {
|
|
|
1282
1245
|
const requiredAttrsNs = `${payload.finalMetaType}_rans`;
|
|
1283
1246
|
const collectedAttrsExpr = `${payload.collectedAttrs.join(" | ")}`;
|
|
1284
1247
|
const needleString = `"${requiredAttrsNs}_NeedleString" as any as "required attributes are missing"`;
|
|
1285
|
-
if (payload.
|
|
1286
|
-
|
|
1248
|
+
if (payload.errorRange) state.extraMappings.push({
|
|
1249
|
+
sourceOffset: payload.errorRange[0],
|
|
1250
|
+
length: payload.errorRange[1] - payload.errorRange[0],
|
|
1251
|
+
generatedNeedle: needleString
|
|
1252
|
+
});
|
|
1253
|
+
replacement = dedent`
|
|
1287
1254
|
type ${payload.finalMetaType} = ${payload.metaType};
|
|
1288
1255
|
let ${lhs}!: { ${Meta}: ${payload.metaType} } & Omit<${payload.defType}, ${Meta}>;
|
|
1289
1256
|
type ${lhs} = typeof ${lhs};
|
|
@@ -1299,10 +1266,11 @@ function applyReplacements(state, code) {
|
|
|
1299
1266
|
const uniqueKeyForThis = `${payload.lhs}_uniqueKeyFor_${payload.lhs}`;
|
|
1300
1267
|
const uniqueKeyHelperIntf = `${payload.defType}_uniqueKeyProbeHelper`;
|
|
1301
1268
|
const omittedKeys = `${payload.lhs}_omittedKeys`;
|
|
1302
|
-
|
|
1269
|
+
replacement = dedent`
|
|
1303
1270
|
type ${uniqueKeyLhs} = {
|
|
1304
1271
|
${Meta}: ${payload.metaType};
|
|
1305
1272
|
uniqueKey: ${payload.defType} extends { [${payload.attrName}]: { uniqueKey: infer UniqueKey } } ? UniqueKey : () => 0;
|
|
1273
|
+
};
|
|
1306
1274
|
|
|
1307
1275
|
let ${uniqueKeyLhs}!: ${uniqueKeyLhs};
|
|
1308
1276
|
let ${uniqueKey} = ${uniqueKeyLhs}.uniqueKey();
|
|
@@ -1326,7 +1294,7 @@ function applyReplacements(state, code) {
|
|
|
1326
1294
|
`;
|
|
1327
1295
|
} else if (payload.type === "createBindingTyping") {
|
|
1328
1296
|
const typingIdLhs = `${payload.typingId}_lhs`;
|
|
1329
|
-
|
|
1297
|
+
replacement = dedent`
|
|
1330
1298
|
type ${typingIdLhs} = {
|
|
1331
1299
|
${Meta}: ${payload.finalMetaType};
|
|
1332
1300
|
as: ${payload.defType} extends { [${payload.attrName}]: { as: infer As } } ? As : unknown;
|
|
@@ -1335,24 +1303,28 @@ function applyReplacements(state, code) {
|
|
|
1335
1303
|
let ${payload.typingId} = ${typingIdLhs}.as();
|
|
1336
1304
|
type ${payload.typingId} = typeof ${payload.typingId};
|
|
1337
1305
|
`;
|
|
1338
|
-
} else if (payload.type === "exitAttr")
|
|
1306
|
+
} else if (payload.type === "exitAttr") replacement = dedent`
|
|
1339
1307
|
type ${payload.returnType} = typeof ${payload.returnType};
|
|
1340
1308
|
type ${payload.newMetaType} = ${payload.returnType} extends { rewriteMeta: infer NewMeta extends {} } ? NewMeta : ${payload.oldMetaType}
|
|
1341
1309
|
`;
|
|
1342
|
-
else
|
|
1310
|
+
else replacement = "";
|
|
1311
|
+
matchInfos.push({
|
|
1312
|
+
sourceEnd: offset + match.length,
|
|
1313
|
+
lengthOffset: replacement.length - match.length
|
|
1314
|
+
});
|
|
1315
|
+
return replacement;
|
|
1343
1316
|
});
|
|
1317
|
+
for (const mapping of mappings) for (let i = 0; i < mapping.generatedOffsets.length; i++) {
|
|
1318
|
+
const orig = mapping.generatedOffsets[i];
|
|
1319
|
+
let shift = 0;
|
|
1320
|
+
for (const info of matchInfos) if (orig >= info.sourceEnd) shift += info.lengthOffset;
|
|
1321
|
+
mapping.generatedOffsets[i] = orig + shift;
|
|
1322
|
+
}
|
|
1323
|
+
return result;
|
|
1344
1324
|
}
|
|
1345
1325
|
//#endregion
|
|
1346
1326
|
//#region src/transform/volar/walker.ts
|
|
1347
1327
|
const EMPTY = { type: "EmptyStatement" };
|
|
1348
|
-
const ANY_INIT = {
|
|
1349
|
-
type: "TSAsExpression",
|
|
1350
|
-
expression: {
|
|
1351
|
-
type: "Literal",
|
|
1352
|
-
value: 0
|
|
1353
|
-
},
|
|
1354
|
-
typeAnnotation: { type: "TSAnyKeyword" }
|
|
1355
|
-
};
|
|
1356
1328
|
const enterVMFromRoot = (state) => {
|
|
1357
1329
|
let defTypeId = {
|
|
1358
1330
|
type: "Identifier",
|
|
@@ -1401,7 +1373,7 @@ const enterVMFromAttr = (state, returningId) => {
|
|
|
1401
1373
|
state.finalMetaTypeIdStack.push(finalMetaTypeId);
|
|
1402
1374
|
state.attrsOfCurrentVm.push([]);
|
|
1403
1375
|
};
|
|
1404
|
-
const exitVM = (state,
|
|
1376
|
+
const exitVM = (state, errorRange) => {
|
|
1405
1377
|
const currentDefTypeId = state.vmDefTypeIdStack.pop();
|
|
1406
1378
|
const currentMetaId = state.metaTypeIdStack.pop();
|
|
1407
1379
|
const finalMetaId = state.finalMetaTypeIdStack.pop();
|
|
@@ -1412,7 +1384,7 @@ const exitVM = (state, errorLoc) => {
|
|
|
1412
1384
|
defType: currentDefTypeId.name,
|
|
1413
1385
|
finalMetaType: finalMetaId.name,
|
|
1414
1386
|
collectedAttrs: collectedAttrNames,
|
|
1415
|
-
|
|
1387
|
+
errorRange
|
|
1416
1388
|
}));
|
|
1417
1389
|
};
|
|
1418
1390
|
const enterAttr = (state, attrName) => {
|
|
@@ -1420,7 +1392,7 @@ const enterAttr = (state, attrName) => {
|
|
|
1420
1392
|
const metaTypeId = state.metaTypeIdStack.at(-1);
|
|
1421
1393
|
if (!defTypeId || !metaTypeId) return { lhsId: {
|
|
1422
1394
|
type: "Identifier",
|
|
1423
|
-
name: "
|
|
1395
|
+
name: "__gts_invalid_attr_obj"
|
|
1424
1396
|
} };
|
|
1425
1397
|
state.attrsOfCurrentVm.at(-1).push(attrName);
|
|
1426
1398
|
const lhsId = {
|
|
@@ -1480,13 +1452,19 @@ const gtsToTypingsWalker = {
|
|
|
1480
1452
|
declarations: [{
|
|
1481
1453
|
type: "VariableDeclarator",
|
|
1482
1454
|
id: extBinding.bindingName,
|
|
1483
|
-
init: ANY_INIT,
|
|
1484
1455
|
typeAnnotation: {
|
|
1485
1456
|
type: "TSTypeAnnotation",
|
|
1486
1457
|
typeAnnotation: {
|
|
1487
1458
|
type: "TSTypeReference",
|
|
1488
1459
|
typeName: extBinding.typingId
|
|
1489
1460
|
}
|
|
1461
|
+
},
|
|
1462
|
+
init: {
|
|
1463
|
+
type: "TSNonNullExpression",
|
|
1464
|
+
expression: {
|
|
1465
|
+
type: "Literal",
|
|
1466
|
+
value: null
|
|
1467
|
+
}
|
|
1490
1468
|
}
|
|
1491
1469
|
}]
|
|
1492
1470
|
};
|
|
@@ -1503,32 +1481,61 @@ const gtsToTypingsWalker = {
|
|
|
1503
1481
|
body.unshift(varDecl);
|
|
1504
1482
|
}
|
|
1505
1483
|
}
|
|
1506
|
-
|
|
1484
|
+
const importDecls = [];
|
|
1485
|
+
importDecls.push({
|
|
1507
1486
|
type: "ImportDeclaration",
|
|
1508
|
-
diagnosticsOnTop: true,
|
|
1509
1487
|
specifiers: [{
|
|
1510
1488
|
type: "ImportDefaultSpecifier",
|
|
1511
|
-
local: state.
|
|
1489
|
+
local: state.rootVmId
|
|
1512
1490
|
}],
|
|
1513
1491
|
source: {
|
|
1514
1492
|
type: "Literal",
|
|
1515
|
-
value: `${state.providerImportSource}/
|
|
1493
|
+
value: `${state.providerImportSource}/vm`
|
|
1516
1494
|
},
|
|
1517
1495
|
attributes: []
|
|
1518
|
-
}
|
|
1519
|
-
body.unshift({
|
|
1496
|
+
}, {
|
|
1520
1497
|
type: "ImportDeclaration",
|
|
1521
|
-
diagnosticsOnTop: true,
|
|
1522
1498
|
specifiers: [{
|
|
1523
|
-
type: "
|
|
1524
|
-
|
|
1499
|
+
type: "ImportSpecifier",
|
|
1500
|
+
imported: {
|
|
1501
|
+
type: "Identifier",
|
|
1502
|
+
name: "createDefine"
|
|
1503
|
+
},
|
|
1504
|
+
local: state.createDefineFnId
|
|
1505
|
+
}, {
|
|
1506
|
+
type: "ImportSpecifier",
|
|
1507
|
+
imported: {
|
|
1508
|
+
type: "Identifier",
|
|
1509
|
+
name: "createBinding"
|
|
1510
|
+
},
|
|
1511
|
+
local: state.createBindingFnId
|
|
1525
1512
|
}],
|
|
1526
1513
|
source: {
|
|
1527
1514
|
type: "Literal",
|
|
1528
|
-
value:
|
|
1515
|
+
value: state.runtimeImportSource
|
|
1516
|
+
},
|
|
1517
|
+
attributes: []
|
|
1518
|
+
});
|
|
1519
|
+
for (const importDecl of importDecls) {
|
|
1520
|
+
state.diagnosticsOnTopNodes.add(importDecl.source);
|
|
1521
|
+
for (const specifier of importDecl.specifiers) state.diagnosticsOnTopNodes.add(specifier);
|
|
1522
|
+
}
|
|
1523
|
+
const lastImportDecl = importDecls.pop() ?? {
|
|
1524
|
+
type: "ImportDeclaration",
|
|
1525
|
+
specifiers: [],
|
|
1526
|
+
source: {
|
|
1527
|
+
type: "Literal",
|
|
1528
|
+
value: ""
|
|
1529
1529
|
},
|
|
1530
1530
|
attributes: []
|
|
1531
|
-
}
|
|
1531
|
+
};
|
|
1532
|
+
body.unshift(...importDecls, {
|
|
1533
|
+
type: "ExpressionStatement",
|
|
1534
|
+
expression: {
|
|
1535
|
+
type: "Literal",
|
|
1536
|
+
value: 0
|
|
1537
|
+
}
|
|
1538
|
+
}, lastImportDecl, createReplacementHolder(state, { type: "preface" }));
|
|
1532
1539
|
return {
|
|
1533
1540
|
...node,
|
|
1534
1541
|
body
|
|
@@ -1543,28 +1550,41 @@ const gtsToTypingsWalker = {
|
|
|
1543
1550
|
GTSNamedAttributeDefinition(node, { visit, state }) {
|
|
1544
1551
|
const { name, body, bindingName } = node;
|
|
1545
1552
|
const attrName = JSON.stringify(name.type === "Literal" ? String(name.value) : name.name);
|
|
1546
|
-
const attributeNameToken = state.leafTokens.find((t) => t.loc === name.loc);
|
|
1547
|
-
if (attributeNameToken) attributeNameToken.sourceLengthOffset = 1;
|
|
1548
1553
|
const { lhsId } = enterAttr(state, attrName);
|
|
1549
|
-
state.extraMappings.set(`${name.loc?.start.line}:${name.loc?.start.column}`, `${lhsId.name}${name.type === "Literal" ? `[` : `.`}`);
|
|
1550
1554
|
const positionals = body.positionalAttributes.attributes.map((attr) => {
|
|
1551
1555
|
if (attr.type === "Identifier" && /^[a-z_]/.test(attr.name)) {
|
|
1552
|
-
const
|
|
1553
|
-
if (token) {
|
|
1554
|
-
token.generatedStartOffset = 1;
|
|
1555
|
-
token.generatedLength = attr.name.length + 2;
|
|
1556
|
-
}
|
|
1557
|
-
return {
|
|
1556
|
+
const lit = {
|
|
1558
1557
|
type: "Literal",
|
|
1559
1558
|
value: attr.name,
|
|
1560
|
-
loc: attr.loc
|
|
1559
|
+
loc: attr.loc,
|
|
1560
|
+
range: attr.range
|
|
1561
1561
|
};
|
|
1562
|
-
|
|
1562
|
+
state.literalFromIdentifier.add(lit);
|
|
1563
|
+
return lit;
|
|
1564
|
+
} else return { ...visit(attr) };
|
|
1563
1565
|
});
|
|
1564
1566
|
const returnValue = {
|
|
1565
1567
|
type: "Identifier",
|
|
1566
1568
|
name: `__gts_attrRet_${state.idCounter++}`
|
|
1567
1569
|
};
|
|
1570
|
+
const callee = {
|
|
1571
|
+
type: "MemberExpression",
|
|
1572
|
+
object: lhsId,
|
|
1573
|
+
property: name,
|
|
1574
|
+
computed: name.type === "Literal",
|
|
1575
|
+
optional: false
|
|
1576
|
+
};
|
|
1577
|
+
if (name.range) {
|
|
1578
|
+
state.extraMappings.push({
|
|
1579
|
+
sourceOffset: name.range[0],
|
|
1580
|
+
length: name.range[1] - name.range[0],
|
|
1581
|
+
generatedNeedle: `${lhsId.name}${name.type === "Literal" ? `[` : `.`}`
|
|
1582
|
+
});
|
|
1583
|
+
state.namedAttributeCalleeLParenRange.set(callee, {
|
|
1584
|
+
start: name.range[1],
|
|
1585
|
+
end: name.range[1] + 1
|
|
1586
|
+
});
|
|
1587
|
+
}
|
|
1568
1588
|
state.typingPendingStatements.push({
|
|
1569
1589
|
type: "VariableDeclaration",
|
|
1570
1590
|
kind: "const",
|
|
@@ -1574,13 +1594,7 @@ const gtsToTypingsWalker = {
|
|
|
1574
1594
|
init: {
|
|
1575
1595
|
type: "CallExpression",
|
|
1576
1596
|
optional: false,
|
|
1577
|
-
callee
|
|
1578
|
-
type: "MemberExpression",
|
|
1579
|
-
object: lhsId,
|
|
1580
|
-
property: name,
|
|
1581
|
-
computed: name.type === "Literal",
|
|
1582
|
-
optional: false
|
|
1583
|
-
},
|
|
1597
|
+
callee,
|
|
1584
1598
|
arguments: positionals
|
|
1585
1599
|
}
|
|
1586
1600
|
}]
|
|
@@ -1588,13 +1602,13 @@ const gtsToTypingsWalker = {
|
|
|
1588
1602
|
if (body.namedAttributes) {
|
|
1589
1603
|
enterVMFromAttr(state, returnValue);
|
|
1590
1604
|
visit(body.namedAttributes);
|
|
1591
|
-
exitVM(state,
|
|
1605
|
+
exitVM(state, body.namedAttributes.range);
|
|
1592
1606
|
}
|
|
1593
1607
|
if (bindingName) {
|
|
1594
1608
|
const export_ = node.bindingAccessModifier !== "private";
|
|
1595
1609
|
const typingId = {
|
|
1596
1610
|
type: "Identifier",
|
|
1597
|
-
name: `
|
|
1611
|
+
name: `__gts_binding_type_${state.externalizedBindings.length}`
|
|
1598
1612
|
};
|
|
1599
1613
|
genBindingTyping(state, {
|
|
1600
1614
|
attrName,
|
|
@@ -1625,8 +1639,11 @@ const gtsToTypingsWalker = {
|
|
|
1625
1639
|
const attrName = JSON.stringify(state.ActionLit.value);
|
|
1626
1640
|
const { lhsId } = enterAttr(state, attrName);
|
|
1627
1641
|
const actionNotExistsReplacementStr = `${lhsId.name}[${attrName}]`;
|
|
1628
|
-
|
|
1629
|
-
|
|
1642
|
+
if (node.directAction.range) state.extraMappings.push({
|
|
1643
|
+
sourceOffset: node.directAction.range[0],
|
|
1644
|
+
length: node.directAction.range[1] - node.directAction.range[0],
|
|
1645
|
+
generatedNeedle: actionNotExistsReplacementStr
|
|
1646
|
+
});
|
|
1630
1647
|
const fn = {
|
|
1631
1648
|
type: "ArrowFunctionExpression",
|
|
1632
1649
|
params: state.shortcutFunctionParameters,
|
|
@@ -1663,16 +1680,7 @@ const gtsToTypingsWalker = {
|
|
|
1663
1680
|
}
|
|
1664
1681
|
return EMPTY;
|
|
1665
1682
|
},
|
|
1666
|
-
...commonGtsVisitor
|
|
1667
|
-
GTSShortcutArgumentExpression(node, { state, visit }) {
|
|
1668
|
-
return {
|
|
1669
|
-
type: "MemberExpression",
|
|
1670
|
-
object: { ...state.fnArgId },
|
|
1671
|
-
computed: false,
|
|
1672
|
-
optional: false,
|
|
1673
|
-
property: visit(node.property)
|
|
1674
|
-
};
|
|
1675
|
-
}
|
|
1683
|
+
...commonGtsVisitor
|
|
1676
1684
|
};
|
|
1677
1685
|
//#endregion
|
|
1678
1686
|
//#region src/transform/volar/mappings.ts
|
|
@@ -1684,291 +1692,151 @@ const DEFAULT_VOLAR_MAPPING_DATA = {
|
|
|
1684
1692
|
structure: true,
|
|
1685
1693
|
verification: true
|
|
1686
1694
|
};
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1695
|
+
const VERIFICATION_ONLY_MAPPING_DATA = { verification: true };
|
|
1696
|
+
Object.freeze(DEFAULT_VOLAR_MAPPING_DATA);
|
|
1697
|
+
Object.freeze(VERIFICATION_ONLY_MAPPING_DATA);
|
|
1698
|
+
//#endregion
|
|
1699
|
+
//#region src/transform/volar/printer.ts
|
|
1700
|
+
function getPrintOptions(source, state) {
|
|
1701
|
+
return {
|
|
1702
|
+
source,
|
|
1703
|
+
isUntouched: (node) => {
|
|
1704
|
+
if (node.type === "Identifier" && node.isDummy) return false;
|
|
1705
|
+
return state.sourceNodes.has(node);
|
|
1706
|
+
},
|
|
1707
|
+
getLeadingComments: (node) => node.leadingComments,
|
|
1708
|
+
getTrailingComments: (node) => node.trailingComments,
|
|
1709
|
+
getMappingData: () => DEFAULT_VOLAR_MAPPING_DATA,
|
|
1710
|
+
printers: {
|
|
1711
|
+
Identifier(node, context) {
|
|
1712
|
+
const identifier = node;
|
|
1713
|
+
if (identifier.isDummy && identifier.range) {
|
|
1714
|
+
const text = state.lastArgNodes.has(identifier) ? "," : "";
|
|
1715
|
+
let firstNonWhiteSpaceIndex = context.source.slice(identifier.range[1]).search(/\S/);
|
|
1716
|
+
const rangeEnd = firstNonWhiteSpaceIndex === -1 ? context.source.length : identifier.range[1] + firstNonWhiteSpaceIndex;
|
|
1717
|
+
context.writeMapped(text, identifier.range[0], rangeEnd);
|
|
1718
|
+
} else return defaultPrinters.Identifier(node, context);
|
|
1719
|
+
},
|
|
1720
|
+
Literal(node, context) {
|
|
1721
|
+
const generatedStart = context.generatedOffset;
|
|
1722
|
+
if (state.literalFromIdentifier.has(node) && node.range) {
|
|
1723
|
+
const text = JSON.stringify(node.value);
|
|
1724
|
+
context.write("\"");
|
|
1725
|
+
context.writeMapped(text.slice(1, -1), node.range[0], node.range[1]);
|
|
1726
|
+
context.write("\"");
|
|
1727
|
+
} else defaultPrinters.Literal(node, context);
|
|
1728
|
+
if (state.diagnosticsOnTopNodes.has(node)) {
|
|
1729
|
+
const generatedEnd = context.generatedOffset;
|
|
1730
|
+
context.createExtraMapping({
|
|
1731
|
+
start: 0,
|
|
1732
|
+
end: 1
|
|
1733
|
+
}, generatedStart, generatedEnd, VERIFICATION_ONLY_MAPPING_DATA);
|
|
1734
|
+
}
|
|
1735
|
+
},
|
|
1736
|
+
ImportDefaultSpecifier(node, context) {
|
|
1737
|
+
const generatedStart = context.generatedOffset;
|
|
1738
|
+
defaultPrinters.ImportDefaultSpecifier(node, context);
|
|
1739
|
+
if (state.diagnosticsOnTopNodes.has(node)) {
|
|
1740
|
+
const generatedEnd = context.generatedOffset;
|
|
1741
|
+
context.createExtraMapping({
|
|
1742
|
+
start: 0,
|
|
1743
|
+
end: 1
|
|
1744
|
+
}, generatedStart, generatedEnd, VERIFICATION_ONLY_MAPPING_DATA);
|
|
1745
|
+
}
|
|
1746
|
+
},
|
|
1747
|
+
ImportSpecifier(node, context) {
|
|
1748
|
+
const generatedStart = context.generatedOffset;
|
|
1749
|
+
defaultPrinters.ImportSpecifier(node, context);
|
|
1750
|
+
if (state.diagnosticsOnTopNodes.has(node)) {
|
|
1751
|
+
const generatedEnd = context.generatedOffset;
|
|
1752
|
+
context.createExtraMapping({
|
|
1753
|
+
start: 0,
|
|
1754
|
+
end: 1
|
|
1755
|
+
}, generatedStart, generatedEnd, VERIFICATION_ONLY_MAPPING_DATA);
|
|
1756
|
+
}
|
|
1757
|
+
},
|
|
1758
|
+
ImportDeclaration(node, context) {
|
|
1759
|
+
defaultPrinters.ImportDeclaration(node, context);
|
|
1760
|
+
if (state.lastImportDeclarationIfGen === node) {
|
|
1761
|
+
context.write("\n");
|
|
1762
|
+
context.createExtraMapping({
|
|
1763
|
+
start: state.contentStartOffset,
|
|
1764
|
+
end: state.contentStartOffset + 1
|
|
1765
|
+
}, context.generatedOffset, context.generatedOffset + 1, DEFAULT_VOLAR_MAPPING_DATA);
|
|
1766
|
+
}
|
|
1738
1767
|
}
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
const
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
line,
|
|
1746
|
-
column,
|
|
1747
|
-
end_line,
|
|
1748
|
-
end_column,
|
|
1749
|
-
code: code_snippet,
|
|
1750
|
-
metadata: {}
|
|
1768
|
+
},
|
|
1769
|
+
experimentalGetLeftParenSourceRange: (node) => {
|
|
1770
|
+
const callLike = node;
|
|
1771
|
+
if (callLike.lParenRange) return {
|
|
1772
|
+
start: callLike.lParenRange[0],
|
|
1773
|
+
end: callLike.lParenRange[1]
|
|
1751
1774
|
};
|
|
1752
|
-
|
|
1753
|
-
map.get(key).push(gen_pos);
|
|
1775
|
+
return state.namedAttributeCalleeLParenRange.get(callLike.callee);
|
|
1754
1776
|
}
|
|
1755
|
-
}
|
|
1756
|
-
return map;
|
|
1757
|
-
}
|
|
1758
|
-
/**
|
|
1759
|
-
* Look up generated position for a given source position
|
|
1760
|
-
* @param src_line - 1-based line number in source
|
|
1761
|
-
* @param src_column - 0-based column number in source
|
|
1762
|
-
* @param srcToGenMap - Lookup map
|
|
1763
|
-
* @returns Generated position
|
|
1764
|
-
*/
|
|
1765
|
-
function getGeneratedPosition(src_line, src_column, srcToGenMap) {
|
|
1766
|
-
const key = `${src_line}:${src_column}`;
|
|
1767
|
-
return srcToGenMap.get(key) || [];
|
|
1768
|
-
}
|
|
1769
|
-
function createLineOffsets(content) {
|
|
1770
|
-
const lines = content.split("\n");
|
|
1771
|
-
const offsets = [];
|
|
1772
|
-
let currentOffset = 0;
|
|
1773
|
-
for (const line of lines) {
|
|
1774
|
-
offsets.push(currentOffset);
|
|
1775
|
-
currentOffset += line.length + 1;
|
|
1776
|
-
}
|
|
1777
|
-
return offsets;
|
|
1777
|
+
};
|
|
1778
1778
|
}
|
|
1779
|
+
//#endregion
|
|
1780
|
+
//#region src/transform/volar/content_start.ts
|
|
1779
1781
|
/**
|
|
1780
|
-
*
|
|
1781
|
-
*
|
|
1782
|
-
*
|
|
1783
|
-
* @param
|
|
1784
|
-
* @returns
|
|
1782
|
+
* Get the character offset after hashbang and file-scope leading comments.
|
|
1783
|
+
* This is for simulating the behavior of TSServer insert auto-imports if no
|
|
1784
|
+
* imports are present.
|
|
1785
|
+
* @param source
|
|
1786
|
+
* @returns
|
|
1785
1787
|
*/
|
|
1786
|
-
function
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
const mappings = [];
|
|
1795
|
-
for (const token of tokens) {
|
|
1796
|
-
let sourceStart = locToOffset(token.loc.start.line, token.loc.start.column, sourceLineOffsets);
|
|
1797
|
-
sourceStart += token.sourceStartOffset ?? 0;
|
|
1798
|
-
const sourceEnd = locToOffset(token.loc.end.line, token.loc.end.column, sourceLineOffsets);
|
|
1799
|
-
let sourceLength = token.sourceLength ?? sourceEnd - sourceStart;
|
|
1800
|
-
sourceLength += token.sourceLengthOffset ?? 0;
|
|
1801
|
-
const [genLineCol] = getGeneratedPosition(token.loc.start.line, token.loc.start.column, srcToGenMap);
|
|
1802
|
-
if (!genLineCol) continue;
|
|
1803
|
-
let genStart = locToOffset(genLineCol.line, genLineCol.column, generatedLineOffsets);
|
|
1804
|
-
if (token.isDummy) while (sourceStart > 0 && /\s/.test(source[sourceStart - 1])) {
|
|
1805
|
-
sourceStart--;
|
|
1806
|
-
sourceLength++;
|
|
1807
|
-
}
|
|
1808
|
-
const generatedLength = token.generatedLength ?? sourceLength;
|
|
1809
|
-
if (typeof token.generatedStartOffset === "number" && token.generatedStartOffset > 0) {
|
|
1810
|
-
mappings.push({
|
|
1811
|
-
sourceOffsets: [sourceStart],
|
|
1812
|
-
generatedOffsets: [genStart],
|
|
1813
|
-
lengths: [0],
|
|
1814
|
-
generatedLengths: [generatedLength],
|
|
1815
|
-
data: { verification: true }
|
|
1816
|
-
});
|
|
1817
|
-
genStart += token.generatedStartOffset;
|
|
1818
|
-
}
|
|
1819
|
-
mappings.push({
|
|
1820
|
-
sourceOffsets: [sourceStart],
|
|
1821
|
-
generatedOffsets: [genStart],
|
|
1822
|
-
lengths: [sourceLength],
|
|
1823
|
-
generatedLengths: [generatedLength],
|
|
1824
|
-
data: DEFAULT_VOLAR_MAPPING_DATA
|
|
1825
|
-
});
|
|
1826
|
-
}
|
|
1827
|
-
const locMapsToTop = getGeneratedPosition(1, 0, srcToGenMap);
|
|
1828
|
-
for (const loc of locMapsToTop) {
|
|
1829
|
-
const offset = locToOffset(loc.line, loc.column, generatedLineOffsets);
|
|
1830
|
-
mappings.push({
|
|
1831
|
-
sourceOffsets: [0],
|
|
1832
|
-
generatedOffsets: [offset],
|
|
1833
|
-
lengths: [0],
|
|
1834
|
-
generatedLengths: [0],
|
|
1835
|
-
data: { verification: true }
|
|
1836
|
-
});
|
|
1837
|
-
}
|
|
1838
|
-
for (const [loc, codeSnippet] of extraMappings) {
|
|
1839
|
-
const generatedStart = generated.indexOf(codeSnippet);
|
|
1840
|
-
if (generatedStart === -1) continue;
|
|
1841
|
-
const [lineStr, columnStr] = loc.split(":");
|
|
1842
|
-
const sourceStart = locToOffset(Number(lineStr), Number(columnStr), sourceLineOffsets);
|
|
1843
|
-
const sourceLength = 1;
|
|
1844
|
-
const generatedLength = codeSnippet.length;
|
|
1845
|
-
mappings.push({
|
|
1846
|
-
sourceOffsets: [sourceStart],
|
|
1847
|
-
generatedOffsets: [generatedStart],
|
|
1848
|
-
lengths: [sourceLength],
|
|
1849
|
-
generatedLengths: [generatedLength],
|
|
1850
|
-
data: { verification: true }
|
|
1851
|
-
});
|
|
1788
|
+
function getContentStartOffset(source) {
|
|
1789
|
+
let result = 0;
|
|
1790
|
+
/** Current visiting character */
|
|
1791
|
+
let pos = 0;
|
|
1792
|
+
if (source.startsWith("#!")) {
|
|
1793
|
+
const nl = source.indexOf("\n", pos);
|
|
1794
|
+
if (nl === -1) return source.length;
|
|
1795
|
+
pos = nl + 1;
|
|
1852
1796
|
}
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
if (key === "loc" || key === "start" || key === "end" || key === "range") continue;
|
|
1862
|
-
if (val && typeof val === "object" && typeof val.type === "string") return false;
|
|
1863
|
-
if (Array.isArray(val) && val.length > 0 && typeof val[0].type === "string") return false;
|
|
1864
|
-
}
|
|
1865
|
-
return true;
|
|
1866
|
-
}
|
|
1867
|
-
function collectLeafTokens(ast) {
|
|
1868
|
-
const state = { tokens: [] };
|
|
1869
|
-
walk(ast, state, {
|
|
1870
|
-
_(node, { state, next }) {
|
|
1871
|
-
if (isLeafNode(node) && node.loc) {
|
|
1872
|
-
const token = { loc: node.loc };
|
|
1873
|
-
if ("isDummy" in node && node.isDummy) {
|
|
1874
|
-
token.isDummy = true;
|
|
1875
|
-
token.sourceLength = 0;
|
|
1876
|
-
token.generatedLength = 1;
|
|
1877
|
-
}
|
|
1878
|
-
state.tokens.push(token);
|
|
1797
|
+
const skipWhitespaces = () => {
|
|
1798
|
+
let newlineCount = 0;
|
|
1799
|
+
for (; pos < source.length; pos++) {
|
|
1800
|
+
const ch = source[pos];
|
|
1801
|
+
if (ch === " " || ch === " " || ch === "\r") continue;
|
|
1802
|
+
if (ch === "\n") {
|
|
1803
|
+
newlineCount++;
|
|
1804
|
+
continue;
|
|
1879
1805
|
}
|
|
1880
|
-
|
|
1881
|
-
},
|
|
1882
|
-
NewExpression(node, { state, next }) {
|
|
1883
|
-
const lParenLoc = node.lParenLoc;
|
|
1884
|
-
if (lParenLoc) state.tokens.push({ loc: lParenLoc });
|
|
1885
|
-
next();
|
|
1886
|
-
},
|
|
1887
|
-
CallExpression(node, { state, next }) {
|
|
1888
|
-
const lParenLoc = node.lParenLoc;
|
|
1889
|
-
if (lParenLoc) state.tokens.push({ loc: lParenLoc });
|
|
1890
|
-
next();
|
|
1891
|
-
}
|
|
1892
|
-
});
|
|
1893
|
-
return state.tokens;
|
|
1894
|
-
}
|
|
1895
|
-
//#endregion
|
|
1896
|
-
//#region src/transform/volar/printer.ts
|
|
1897
|
-
const printer = jsPrinter({
|
|
1898
|
-
getLeadingComments: (node) => node.leadingComments,
|
|
1899
|
-
getTrailingComments: (node) => node.trailingComments
|
|
1900
|
-
});
|
|
1901
|
-
const prevIdentifier = printer.Identifier;
|
|
1902
|
-
printer.Identifier = function(node, context) {
|
|
1903
|
-
if (node.isDummy) {
|
|
1904
|
-
const text = Reflect.get(node, "lastArg") ? "," : "";
|
|
1905
|
-
context.write(text, node);
|
|
1906
|
-
} else prevIdentifier(node, context);
|
|
1907
|
-
};
|
|
1908
|
-
const prevCallNewExpression = printer.CallExpression;
|
|
1909
|
-
const newCallNewExpression = function(node, context) {
|
|
1910
|
-
const lastArg = node.arguments.at(-1);
|
|
1911
|
-
if (lastArg) Reflect.set(lastArg, "lastArg", true);
|
|
1912
|
-
if (!node.lParenLoc) return prevCallNewExpression(node, context);
|
|
1913
|
-
let hasDeferredWrite = false;
|
|
1914
|
-
let interceptionDone = false;
|
|
1915
|
-
const lParenFakeNode = { loc: node.lParenLoc };
|
|
1916
|
-
const patchedWrite = (text, node) => {
|
|
1917
|
-
if (text === "(") hasDeferredWrite = true;
|
|
1918
|
-
else context.write(text, node);
|
|
1919
|
-
};
|
|
1920
|
-
const patchedVisit = (node) => {
|
|
1921
|
-
if (hasDeferredWrite) context.write("(");
|
|
1922
|
-
return context.visit(node);
|
|
1923
|
-
};
|
|
1924
|
-
const patchedAppend = (subcontext) => {
|
|
1925
|
-
if (hasDeferredWrite) {
|
|
1926
|
-
context.write("(", lParenFakeNode);
|
|
1927
|
-
interceptionDone = true;
|
|
1806
|
+
break;
|
|
1928
1807
|
}
|
|
1929
|
-
return
|
|
1808
|
+
return newlineCount;
|
|
1930
1809
|
};
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
if (
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
if ("diagnosticsOnTop" in node && node.diagnosticsOnTop) contextProto.write = function(text, node) {
|
|
1949
|
-
node ??= {};
|
|
1950
|
-
node.loc ??= {
|
|
1951
|
-
start: {
|
|
1952
|
-
line: 1,
|
|
1953
|
-
column: 0
|
|
1954
|
-
},
|
|
1955
|
-
end: {
|
|
1956
|
-
line: 1,
|
|
1957
|
-
column: 0
|
|
1810
|
+
skipWhitespaces();
|
|
1811
|
+
while (pos < source.length) {
|
|
1812
|
+
let newlineCount = 0;
|
|
1813
|
+
if (source[pos] === "/" && pos + 1 < source.length) {
|
|
1814
|
+
if (source[pos + 1] === "/") {
|
|
1815
|
+
const nl = source.indexOf("\n", pos);
|
|
1816
|
+
pos = nl === -1 ? source.length : nl + 1;
|
|
1817
|
+
newlineCount++;
|
|
1818
|
+
} else if (source[pos + 1] === "*") {
|
|
1819
|
+
pos += 2;
|
|
1820
|
+
while (pos < source.length) {
|
|
1821
|
+
if (source[pos] === "*" && pos + 1 < source.length && source[pos + 1] === "/") {
|
|
1822
|
+
pos += 2;
|
|
1823
|
+
break;
|
|
1824
|
+
}
|
|
1825
|
+
pos++;
|
|
1826
|
+
}
|
|
1958
1827
|
}
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1828
|
+
result = pos;
|
|
1829
|
+
newlineCount += skipWhitespaces();
|
|
1830
|
+
if (newlineCount >= 2) break;
|
|
1831
|
+
} else break;
|
|
1832
|
+
}
|
|
1833
|
+
return result;
|
|
1834
|
+
}
|
|
1966
1835
|
//#endregion
|
|
1967
1836
|
//#region src/transform/volar/index.ts
|
|
1968
|
-
function
|
|
1837
|
+
function transformForVolar(ast, option, sourceInfo) {
|
|
1969
1838
|
const state = {
|
|
1970
1839
|
...initialTranspileState(option),
|
|
1971
|
-
leafTokens: option.leafTokens,
|
|
1972
1840
|
idCounter: 0,
|
|
1973
1841
|
typingPendingStatements: [],
|
|
1974
1842
|
rootVmId: {
|
|
@@ -1996,25 +1864,50 @@ function gtsToTypings(ast, option) {
|
|
|
1996
1864
|
metaTypeIdStack: [],
|
|
1997
1865
|
finalMetaTypeIdStack: [],
|
|
1998
1866
|
attrsOfCurrentVm: [],
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
1867
|
+
sourceNodes: /* @__PURE__ */ new WeakSet(),
|
|
1868
|
+
namedAttributeCalleeLParenRange: /* @__PURE__ */ new WeakMap(),
|
|
1869
|
+
literalFromIdentifier: /* @__PURE__ */ new WeakSet(),
|
|
1870
|
+
lastArgNodes: /* @__PURE__ */ new WeakSet(),
|
|
1871
|
+
lastImportDeclarationIfGen: null,
|
|
1872
|
+
diagnosticsOnTopNodes: /* @__PURE__ */ new WeakSet(),
|
|
1873
|
+
extraMappings: [],
|
|
1874
|
+
contentStartOffset: getContentStartOffset(sourceInfo.content)
|
|
2005
1875
|
};
|
|
2006
|
-
}
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
const
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
1876
|
+
walk(ast, state, { _(node, { state, next }) {
|
|
1877
|
+
if (node.range) state.sourceNodes.add(node);
|
|
1878
|
+
next();
|
|
1879
|
+
} });
|
|
1880
|
+
const newAst = walk(ast, state, gtsToTypingsWalker);
|
|
1881
|
+
walk(newAst, state, {
|
|
1882
|
+
CallExpression(node, { state }) {
|
|
1883
|
+
const lastArg = node.arguments.at(-1);
|
|
1884
|
+
if (lastArg) state.lastArgNodes.add(lastArg);
|
|
1885
|
+
},
|
|
1886
|
+
ImportDeclaration(node, { state }) {
|
|
1887
|
+
if (!state.sourceNodes.has(node)) state.lastImportDeclarationIfGen = node;
|
|
1888
|
+
}
|
|
2014
1889
|
});
|
|
1890
|
+
let { code, mappings } = print$1(newAst, getPrintOptions(sourceInfo.content, state));
|
|
1891
|
+
code = applyReplacements(state, code, mappings);
|
|
1892
|
+
for (const extraMapping of state.extraMappings) {
|
|
1893
|
+
const genOffset = code.indexOf(extraMapping.generatedNeedle);
|
|
1894
|
+
mappings.push({
|
|
1895
|
+
sourceOffsets: [extraMapping.sourceOffset],
|
|
1896
|
+
lengths: [extraMapping.length],
|
|
1897
|
+
generatedOffsets: [genOffset],
|
|
1898
|
+
generatedLengths: [extraMapping.generatedNeedle.length],
|
|
1899
|
+
data: VERIFICATION_ONLY_MAPPING_DATA
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
walk(newAst, null, { ImportDeclaration(node) {
|
|
1903
|
+
if (!node.range) return;
|
|
1904
|
+
const endOffset = node.range[1];
|
|
1905
|
+
const mappingEndsWithThisImport = mappings.find((m) => m.sourceOffsets[0] + m.lengths[0] === endOffset);
|
|
1906
|
+
if (mappingEndsWithThisImport?.lengths[0]) mappingEndsWithThisImport.lengths[0] += 1;
|
|
1907
|
+
} });
|
|
2015
1908
|
return {
|
|
2016
1909
|
code,
|
|
2017
|
-
mappings
|
|
1910
|
+
mappings
|
|
2018
1911
|
};
|
|
2019
1912
|
}
|
|
2020
1913
|
//#endregion
|