Skip to content

Commit 5ada37d

Browse files
Merge pull request #1 from uniqueiniquity/buildRealProgram
Offer semantic services alongside AST
2 parents c3ea1d2 + d5e69af commit 5ada37d

16 files changed

+1766
-100
lines changed

lib/ast-converter.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,8 @@ module.exports = (ast, extra) => {
7373
estree.comments = convertComments(ast, extra.code);
7474
}
7575

76-
return estree;
76+
const astMaps = convert.getASTMaps();
77+
convert.resetASTMaps();
78+
79+
return { estree, astMaps };
7780
};

lib/convert.js

+74-28
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ const SyntaxKind = nodeUtils.SyntaxKind;
2525
// Public
2626
//------------------------------------------------------------------------------
2727

28+
let esTreeNodeToTSNodeMap = new WeakMap();
29+
let tsNodeToESTreeNodeMap = new WeakMap();
30+
31+
function resetASTMaps() {
32+
esTreeNodeToTSNodeMap = new WeakMap();
33+
tsNodeToESTreeNodeMap = new WeakMap();
34+
}
35+
36+
function getASTMaps() {
37+
return { esTreeNodeToTSNodeMap, tsNodeToESTreeNodeMap };
38+
}
39+
2840
/**
2941
* Converts a TypeScript node into an ESTree node
3042
* @param {Object} config configuration options for the conversion
@@ -53,7 +65,7 @@ module.exports = function convert(config) {
5365
*/
5466
let result = {
5567
type: '',
56-
range: [node.getStart(), node.end],
68+
range: [node.getStart(ast), node.end],
5769
loc: nodeUtils.getLoc(node, ast)
5870
};
5971

@@ -120,7 +132,11 @@ module.exports = function convert(config) {
120132
typeArgumentsParent.kind === SyntaxKind.TypeReference)
121133
) {
122134
const lastTypeArgument = typeArguments[typeArguments.length - 1];
123-
const greaterThanToken = nodeUtils.findNextToken(lastTypeArgument, ast);
135+
const greaterThanToken = nodeUtils.findNextToken(
136+
lastTypeArgument,
137+
ast,
138+
ast
139+
);
124140
end = greaterThanToken.end;
125141
}
126142
}
@@ -132,7 +148,7 @@ module.exports = function convert(config) {
132148
if (nodeUtils.isTypeKeyword(typeArgument.kind)) {
133149
return {
134150
type: AST_NODE_TYPES[`TS${SyntaxKind[typeArgument.kind]}`],
135-
range: [typeArgument.getStart(), typeArgument.getEnd()],
151+
range: [typeArgument.getStart(ast), typeArgument.getEnd()],
136152
loc: nodeUtils.getLoc(typeArgument, ast)
137153
};
138154
}
@@ -146,7 +162,7 @@ module.exports = function convert(config) {
146162
}
147163
return {
148164
type: AST_NODE_TYPES.TSTypeReference,
149-
range: [typeArgument.getStart(), typeArgument.getEnd()],
165+
range: [typeArgument.getStart(ast), typeArgument.getEnd()],
150166
loc: nodeUtils.getLoc(typeArgument, ast),
151167
typeName: convertChild(typeArgument.typeName || typeArgument),
152168
typeParameters: typeArgument.typeArguments
@@ -166,7 +182,11 @@ module.exports = function convert(config) {
166182
const firstTypeParameter = typeParameters[0];
167183
const lastTypeParameter = typeParameters[typeParameters.length - 1];
168184

169-
const greaterThanToken = nodeUtils.findNextToken(lastTypeParameter, ast);
185+
const greaterThanToken = nodeUtils.findNextToken(
186+
lastTypeParameter,
187+
ast,
188+
ast
189+
);
170190

171191
return {
172192
type: AST_NODE_TYPES.TSTypeParameterDeclaration,
@@ -199,7 +219,7 @@ module.exports = function convert(config) {
199219

200220
return {
201221
type: AST_NODE_TYPES.TSTypeParameter,
202-
range: [typeParameter.getStart(), typeParameter.getEnd()],
222+
range: [typeParameter.getStart(ast), typeParameter.getEnd()],
203223
loc: nodeUtils.getLoc(typeParameter, ast),
204224
name,
205225
constraint,
@@ -266,7 +286,7 @@ module.exports = function convert(config) {
266286
const expression = convertChild(decorator.expression);
267287
return {
268288
type: AST_NODE_TYPES.Decorator,
269-
range: [decorator.getStart(), decorator.end],
289+
range: [decorator.getStart(ast), decorator.end],
270290
loc: nodeUtils.getLoc(decorator, ast),
271291
expression
272292
};
@@ -477,7 +497,11 @@ module.exports = function convert(config) {
477497
});
478498

479499
result.range[1] = node.endOfFileToken.end;
480-
result.loc = nodeUtils.getLocFor(node.getStart(), result.range[1], ast);
500+
result.loc = nodeUtils.getLocFor(
501+
node.getStart(ast),
502+
result.range[1],
503+
ast
504+
);
481505
break;
482506

483507
case SyntaxKind.Block:
@@ -934,11 +958,12 @@ module.exports = function convert(config) {
934958
return false;
935959
}
936960
return nodeUtils.getTextForTokenKind(token.kind) === '(';
937-
}
961+
},
962+
ast
938963
);
939964

940965
const methodLoc = ast.getLineAndCharacterOfPosition(
941-
openingParen.getStart()
966+
openingParen.getStart(ast)
942967
),
943968
nodeIsMethod = node.kind === SyntaxKind.MethodDeclaration,
944969
method = {
@@ -1045,7 +1070,7 @@ module.exports = function convert(config) {
10451070
node
10461071
),
10471072
firstConstructorToken = constructorIsStatic
1048-
? nodeUtils.findNextToken(node.getFirstToken(), ast)
1073+
? nodeUtils.findNextToken(node.getFirstToken(), ast, ast)
10491074
: node.getFirstToken(),
10501075
constructorLoc = ast.getLineAndCharacterOfPosition(
10511076
node.parameters.pos - 1
@@ -1069,10 +1094,10 @@ module.exports = function convert(config) {
10691094
};
10701095

10711096
const constructorIdentifierLocStart = ast.getLineAndCharacterOfPosition(
1072-
firstConstructorToken.getStart()
1097+
firstConstructorToken.getStart(ast)
10731098
),
10741099
constructorIdentifierLocEnd = ast.getLineAndCharacterOfPosition(
1075-
firstConstructorToken.getEnd()
1100+
firstConstructorToken.getEnd(ast)
10761101
),
10771102
constructorIsComputed =
10781103
!!node.name && nodeUtils.isComputedProperty(node.name);
@@ -1084,7 +1109,10 @@ module.exports = function convert(config) {
10841109
type: AST_NODE_TYPES.Literal,
10851110
value: 'constructor',
10861111
raw: node.name.getText(),
1087-
range: [firstConstructorToken.getStart(), firstConstructorToken.end],
1112+
range: [
1113+
firstConstructorToken.getStart(ast),
1114+
firstConstructorToken.end
1115+
],
10881116
loc: {
10891117
start: {
10901118
line: constructorIdentifierLocStart.line + 1,
@@ -1100,7 +1128,10 @@ module.exports = function convert(config) {
11001128
constructorKey = {
11011129
type: AST_NODE_TYPES.Identifier,
11021130
name: 'constructor',
1103-
range: [firstConstructorToken.getStart(), firstConstructorToken.end],
1131+
range: [
1132+
firstConstructorToken.getStart(ast),
1133+
firstConstructorToken.end
1134+
],
11041135
loc: {
11051136
start: {
11061137
line: constructorIdentifierLocStart.line + 1,
@@ -1233,9 +1264,9 @@ module.exports = function convert(config) {
12331264
type: AST_NODE_TYPES.AssignmentPattern,
12341265
left: convertChild(node.name),
12351266
right: convertChild(node.initializer),
1236-
range: [node.name.getStart(), node.initializer.end],
1267+
range: [node.name.getStart(ast), node.initializer.end],
12371268
loc: nodeUtils.getLocFor(
1238-
node.name.getStart(),
1269+
node.name.getStart(ast),
12391270
node.initializer.end,
12401271
ast
12411272
)
@@ -1292,7 +1323,7 @@ module.exports = function convert(config) {
12921323
{
12931324
type: AST_NODE_TYPES.TemplateElement,
12941325
value: {
1295-
raw: ast.text.slice(node.getStart() + 1, node.end - 1),
1326+
raw: ast.text.slice(node.getStart(ast) + 1, node.end - 1),
12961327
cooked: node.text
12971328
},
12981329
tail: true,
@@ -1335,7 +1366,10 @@ module.exports = function convert(config) {
13351366
Object.assign(result, {
13361367
type: AST_NODE_TYPES.TemplateElement,
13371368
value: {
1338-
raw: ast.text.slice(node.getStart() + 1, node.end - (tail ? 1 : 2)),
1369+
raw: ast.text.slice(
1370+
node.getStart(ast) + 1,
1371+
node.end - (tail ? 1 : 2)
1372+
),
13391373
cooked: node.text
13401374
},
13411375
tail
@@ -1426,7 +1460,7 @@ module.exports = function convert(config) {
14261460
if (node.modifiers) {
14271461
return {
14281462
type: AST_NODE_TYPES.TSParameterProperty,
1429-
range: [node.getStart(), node.end],
1463+
range: [node.getStart(ast), node.end],
14301464
loc: nodeUtils.getLoc(node, ast),
14311465
accessibility: nodeUtils.getTSNodeAccessibility(node) || undefined,
14321466
readonly:
@@ -1459,7 +1493,7 @@ module.exports = function convert(config) {
14591493
node.typeParameters[node.typeParameters.length - 1];
14601494

14611495
if (!lastClassToken || lastTypeParameter.pos > lastClassToken.pos) {
1462-
lastClassToken = nodeUtils.findNextToken(lastTypeParameter, ast);
1496+
lastClassToken = nodeUtils.findNextToken(lastTypeParameter, ast, ast);
14631497
}
14641498
result.typeParameters = convertTSTypeParametersToTypeParametersDeclaration(
14651499
node.typeParameters
@@ -1483,14 +1517,14 @@ module.exports = function convert(config) {
14831517
const lastModifier = node.modifiers[node.modifiers.length - 1];
14841518

14851519
if (!lastClassToken || lastModifier.pos > lastClassToken.pos) {
1486-
lastClassToken = nodeUtils.findNextToken(lastModifier, ast);
1520+
lastClassToken = nodeUtils.findNextToken(lastModifier, ast, ast);
14871521
}
14881522
} else if (!lastClassToken) {
14891523
// no name
14901524
lastClassToken = node.getFirstToken();
14911525
}
14921526

1493-
const openBrace = nodeUtils.findNextToken(lastClassToken, ast);
1527+
const openBrace = nodeUtils.findNextToken(lastClassToken, ast, ast);
14941528
const superClass = heritageClauses.find(
14951529
clause => clause.token === SyntaxKind.ExtendsKeyword
14961530
);
@@ -1523,8 +1557,8 @@ module.exports = function convert(config) {
15231557
body: [],
15241558

15251559
// TODO: Fix location info
1526-
range: [openBrace.getStart(), result.range[1]],
1527-
loc: nodeUtils.getLocFor(openBrace.getStart(), node.end, ast)
1560+
range: [openBrace.getStart(ast), result.range[1]],
1561+
loc: nodeUtils.getLocFor(openBrace.getStart(ast), node.end, ast)
15281562
},
15291563
superClass:
15301564
superClass && superClass.types[0]
@@ -2142,7 +2176,7 @@ module.exports = function convert(config) {
21422176
type: AST_NODE_TYPES.VariableDeclarator,
21432177
id: convertChild(node.name),
21442178
init: convertChild(node.type),
2145-
range: [node.name.getStart(), node.end]
2179+
range: [node.name.getStart(ast), node.end]
21462180
};
21472181

21482182
typeAliasDeclarator.loc = nodeUtils.getLocFor(
@@ -2278,6 +2312,7 @@ module.exports = function convert(config) {
22782312
) {
22792313
interfaceLastClassToken = nodeUtils.findNextToken(
22802314
interfaceLastTypeParameter,
2315+
ast,
22812316
ast
22822317
);
22832318
}
@@ -2293,14 +2328,19 @@ module.exports = function convert(config) {
22932328
);
22942329
const interfaceOpenBrace = nodeUtils.findNextToken(
22952330
interfaceLastClassToken,
2331+
ast,
22962332
ast
22972333
);
22982334

22992335
const interfaceBody = {
23002336
type: AST_NODE_TYPES.TSInterfaceBody,
23012337
body: node.members.map(member => convertChild(member)),
2302-
range: [interfaceOpenBrace.getStart(), result.range[1]],
2303-
loc: nodeUtils.getLocFor(interfaceOpenBrace.getStart(), node.end, ast)
2338+
range: [interfaceOpenBrace.getStart(ast), result.range[1]],
2339+
loc: nodeUtils.getLocFor(
2340+
interfaceOpenBrace.getStart(ast),
2341+
node.end,
2342+
ast
2343+
)
23042344
};
23052345

23062346
Object.assign(result, {
@@ -2411,5 +2451,11 @@ module.exports = function convert(config) {
24112451
deeplyCopy();
24122452
}
24132453

2454+
tsNodeToESTreeNodeMap.set(node, result);
2455+
esTreeNodeToTSNodeMap.set(result, node);
2456+
24142457
return result;
24152458
};
2459+
2460+
module.exports.getASTMaps = getASTMaps;
2461+
module.exports.resetASTMaps = resetASTMaps;

0 commit comments

Comments
 (0)