Skip to content
This repository has been archived by the owner on Jan 14, 2019. It is now read-only.

Offer semantic services alongside AST #24

Merged
merged 33 commits into from
Nov 22, 2018
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3c10816
feat: use cwd to find tsconfig and build program
Sep 26, 2018
1697aed
fix: use text read by eslint
Sep 28, 2018
adc6724
fix: ensure ast maps are unique to each parse result
Oct 3, 2018
459db21
fix: handle files not included in ts project more robustly
Oct 4, 2018
7f1ba19
chore: fix indentation
Oct 4, 2018
b4377a9
fix: remove duplicated code from merge
Oct 4, 2018
d2d6a31
fix: re-add missing argument
Oct 4, 2018
c3cc2da
fix: take tsconfig paths from eslintrc rather than finding one
Oct 8, 2018
4821647
perf: reuse existing programs and supply outdated to create new programs
Oct 9, 2018
9dbd1fb
fix: appropriately handle malformed tsconfigs
Oct 9, 2018
4f9608a
test: add test for semantic info in isolated file
Oct 11, 2018
d2d12b7
test: add bad project input tests
Oct 12, 2018
460953d
test: add test validating cross-file type resolution
Oct 12, 2018
2315459
chore: add comment to test
Oct 12, 2018
ade71f2
chore: limit badtsconfig for readability
Oct 12, 2018
b3c407f
chore: update test header
Oct 12, 2018
47c9b1c
perf: use TS watch API to track changes to programs
Oct 17, 2018
fb5470c
fix: ensure changes to the linted file are detected
Oct 18, 2018
f27a444
fix: improve project option validation
Oct 18, 2018
234fe43
chore: remove unnecessary comments from tsconfig in tests
Oct 18, 2018
01a312b
fix: report config file errors whenever the program updates
Oct 22, 2018
8e60d5f
fix: add sourcefile to more operations
Oct 29, 2018
8a46d08
refactor: only pass projects to project option handling
Oct 29, 2018
285cbd1
refactor: break up program creation for readability
Oct 29, 2018
7e54657
refactor: add comment and use util function
Oct 29, 2018
d4435ea
fix: don't try to convert symbols
Nov 5, 2018
7fd22df
chore: merge branch 'master' into semanticServices
Nov 5, 2018
89787c4
test: update semanticInfo baseline to be path-agnostic
Nov 5, 2018
d23645a
Merge branch 'master' into semanticServices
JamesHenry Nov 8, 2018
5d6708a
refactor: rename tsconfig root directory option and respond to cr
Nov 9, 2018
3982abf
fix: undo resolveJsonModule to avoid changing dist structure
Nov 9, 2018
2f8a07e
Merge branch 'master' into semanticServices
JamesHenry Nov 11, 2018
792ee88
refactor: move generating services to separate top-level function
Nov 14, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@types/jest": "^23.3.9",
"@types/lodash.isplainobject": "^4.0.4",
"@types/lodash.unescape": "^4.0.4",
"@types/node": "^10.12.2",
"@types/semver": "^5.5.0",
"@types/shelljs": "^0.8.0",
"babel-code-frame": "6.26.0",
Expand Down
7 changes: 5 additions & 2 deletions src/ast-converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @copyright jQuery Foundation and other contributors, https://jquery.org/
* MIT License
*/
import { convert } from './convert';
import convert, { getASTMaps, resetASTMaps } from './convert';
import { convertComments } from './convert-comments';
import nodeUtils from './node-utils';
import { Extra } from './temp-types-based-on-js-source';
Expand Down Expand Up @@ -59,5 +59,8 @@ export default (ast: any, extra: Extra) => {
estree.comments = convertComments(ast, extra.code);
}

return estree;
const astMaps = getASTMaps();
resetASTMaps();

return { estree, astMaps };
};
103 changes: 69 additions & 34 deletions src/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ import { ESTreeNode } from './temp-types-based-on-js-source';

const SyntaxKind = ts.SyntaxKind;

let esTreeNodeToTSNodeMap = new WeakMap();
let tsNodeToESTreeNodeMap = new WeakMap();

export function resetASTMaps() {
esTreeNodeToTSNodeMap = new WeakMap();
tsNodeToESTreeNodeMap = new WeakMap();
}

export function getASTMaps() {
return { esTreeNodeToTSNodeMap, tsNodeToESTreeNodeMap };
}

/**
* Converts a TypeScript node into an ESTree node
* @param {Object} config configuration options for the conversion
Expand All @@ -21,7 +33,7 @@ const SyntaxKind = ts.SyntaxKind;
* @param {Object} config.additionalOptions additional options for the conversion
* @returns {ESTreeNode|null} the converted ESTreeNode
*/
export function convert(config: any): ESTreeNode | null {
export default function convert(config: any): ESTreeNode | null {
const node = config.node as ts.Node;
const parent = config.parent;
const ast = config.ast;
Expand All @@ -39,7 +51,7 @@ export function convert(config: any): ESTreeNode | null {
*/
let result: Partial<ESTreeNode> = {
type: '',
range: [node.getStart(), node.end],
range: [node.getStart(ast), node.end],
loc: nodeUtils.getLoc(node, ast)
};

Expand Down Expand Up @@ -108,8 +120,12 @@ export function convert(config: any): ESTreeNode | null {
typeArgumentsParent.kind === SyntaxKind.TypeReference)
) {
const lastTypeArgument = typeArguments[typeArguments.length - 1];
const greaterThanToken = nodeUtils.findNextToken(lastTypeArgument, ast);
end = greaterThanToken.end;
const greaterThanToken = nodeUtils.findNextToken(
lastTypeArgument,
ast,
ast
);
end = greaterThanToken!.end;
}
}
return {
Expand All @@ -120,7 +136,7 @@ export function convert(config: any): ESTreeNode | null {
if (nodeUtils.isTypeKeyword(typeArgument.kind)) {
return {
type: AST_NODE_TYPES[`TS${SyntaxKind[typeArgument.kind]}`],
range: [typeArgument.getStart(), typeArgument.getEnd()],
range: [typeArgument.getStart(ast), typeArgument.getEnd()],
loc: nodeUtils.getLoc(typeArgument, ast)
};
}
Expand All @@ -134,7 +150,7 @@ export function convert(config: any): ESTreeNode | null {
}
return {
type: AST_NODE_TYPES.TSTypeReference,
range: [typeArgument.getStart(), typeArgument.getEnd()],
range: [typeArgument.getStart(ast), typeArgument.getEnd()],
loc: nodeUtils.getLoc(typeArgument, ast),
typeName: convertChild(typeArgument.typeName || typeArgument),
typeParameters: typeArgument.typeArguments
Expand All @@ -156,14 +172,18 @@ export function convert(config: any): ESTreeNode | null {
const firstTypeParameter = typeParameters[0];
const lastTypeParameter = typeParameters[typeParameters.length - 1];

const greaterThanToken = nodeUtils.findNextToken(lastTypeParameter, ast);
const greaterThanToken = nodeUtils.findNextToken(
lastTypeParameter,
ast,
ast
);

return {
type: AST_NODE_TYPES.TSTypeParameterDeclaration,
range: [firstTypeParameter.pos - 1, greaterThanToken.end],
range: [firstTypeParameter.pos - 1, greaterThanToken!.end],
loc: nodeUtils.getLocFor(
firstTypeParameter.pos - 1,
greaterThanToken.end,
greaterThanToken!.end,
ast
),
params: typeParameters.map(typeParameter => {
Expand All @@ -189,7 +209,7 @@ export function convert(config: any): ESTreeNode | null {

return {
type: AST_NODE_TYPES.TSTypeParameter,
range: [typeParameter.getStart(), typeParameter.getEnd()],
range: [typeParameter.getStart(ast), typeParameter.getEnd()],
loc: nodeUtils.getLoc(typeParameter, ast),
name,
constraint,
Expand Down Expand Up @@ -258,7 +278,7 @@ export function convert(config: any): ESTreeNode | null {
const expression = convertChild(decorator.expression);
return {
type: AST_NODE_TYPES.Decorator,
range: [decorator.getStart(), decorator.end],
range: [decorator.getStart(ast), decorator.end],
loc: nodeUtils.getLoc(decorator, ast),
expression
};
Expand Down Expand Up @@ -336,8 +356,10 @@ export function convert(config: any): ESTreeNode | null {
(result as any)[key] = (node as any)[key].map(convertChild);
} else if (
(node as any)[key] &&
typeof (node as any)[key] === 'object'
typeof (node as any)[key] === 'object' &&
(node as any)[key].kind
) {
// need to check node[key].kind to ensure we don't try to convert a symbol
(result as any)[key] = convertChild((node as any)[key]);
} else {
(result as any)[key] = (node as any)[key];
Expand Down Expand Up @@ -475,7 +497,7 @@ export function convert(config: any): ESTreeNode | null {

(result as any).range[1] = (node as any).endOfFileToken.end;
result.loc = nodeUtils.getLocFor(
node.getStart(),
node.getStart(ast),
(result as any).range[1],
ast
);
Expand Down Expand Up @@ -949,11 +971,12 @@ export function convert(config: any): ESTreeNode | null {
return false;
}
return nodeUtils.getTextForTokenKind(token.kind) === '(';
}
},
ast
);

const methodLoc = ast.getLineAndCharacterOfPosition(
(openingParen as any).getStart()
(openingParen as any).getStart(ast)
),
nodeIsMethod = node.kind === SyntaxKind.MethodDeclaration,
method = {
Expand Down Expand Up @@ -1063,7 +1086,7 @@ export function convert(config: any): ESTreeNode | null {
node
),
firstConstructorToken = constructorIsStatic
? nodeUtils.findNextToken((node as any).getFirstToken(), ast)
? nodeUtils.findNextToken((node as any).getFirstToken(), ast, ast)
: node.getFirstToken(),
constructorLoc = ast.getLineAndCharacterOfPosition(
(node as any).parameters.pos - 1
Expand All @@ -1087,10 +1110,10 @@ export function convert(config: any): ESTreeNode | null {
};

const constructorIdentifierLocStart = ast.getLineAndCharacterOfPosition(
(firstConstructorToken as any).getStart()
(firstConstructorToken as any).getStart(ast)
),
constructorIdentifierLocEnd = ast.getLineAndCharacterOfPosition(
(firstConstructorToken as any).getEnd()
(firstConstructorToken as any).getEnd(ast)
),
constructorIsComputed =
!!(node as any).name &&
Expand All @@ -1104,7 +1127,7 @@ export function convert(config: any): ESTreeNode | null {
value: 'constructor',
raw: (node as any).name.getText(),
range: [
(firstConstructorToken as any).getStart(),
(firstConstructorToken as any).getStart(ast),
(firstConstructorToken as any).end
],
loc: {
Expand All @@ -1123,7 +1146,7 @@ export function convert(config: any): ESTreeNode | null {
type: AST_NODE_TYPES.Identifier,
name: 'constructor',
range: [
(firstConstructorToken as any).getStart(),
(firstConstructorToken as any).getStart(ast),
(firstConstructorToken as any).end
],
loc: {
Expand Down Expand Up @@ -1262,11 +1285,11 @@ export function convert(config: any): ESTreeNode | null {
left: convertChild((node as any).name),
right: convertChild((node as any).initializer),
range: [
(node as any).name.getStart(),
(node as any).name.getStart(ast),
(node as any).initializer.end
],
loc: nodeUtils.getLocFor(
(node as any).name.getStart(),
(node as any).name.getStart(ast),
(node as any).initializer.end,
ast
)
Expand Down Expand Up @@ -1323,7 +1346,7 @@ export function convert(config: any): ESTreeNode | null {
{
type: AST_NODE_TYPES.TemplateElement,
value: {
raw: ast.text.slice(node.getStart() + 1, node.end - 1),
raw: ast.text.slice(node.getStart(ast) + 1, node.end - 1),
cooked: (node as any).text
},
tail: true,
Expand Down Expand Up @@ -1366,7 +1389,10 @@ export function convert(config: any): ESTreeNode | null {
Object.assign(result, {
type: AST_NODE_TYPES.TemplateElement,
value: {
raw: ast.text.slice(node.getStart() + 1, node.end - (tail ? 1 : 2)),
raw: ast.text.slice(
node.getStart(ast) + 1,
node.end - (tail ? 1 : 2)
),
cooked: (node as any).text
},
tail
Expand Down Expand Up @@ -1459,7 +1485,7 @@ export function convert(config: any): ESTreeNode | null {
if (node.modifiers) {
return {
type: AST_NODE_TYPES.TSParameterProperty,
range: [node.getStart(), node.end],
range: [node.getStart(ast), node.end],
loc: nodeUtils.getLoc(node, ast),
accessibility: nodeUtils.getTSNodeAccessibility(node) || undefined,
readonly:
Expand Down Expand Up @@ -1493,7 +1519,7 @@ export function convert(config: any): ESTreeNode | null {
];

if (!lastClassToken || lastTypeParameter.pos > lastClassToken.pos) {
lastClassToken = nodeUtils.findNextToken(lastTypeParameter, ast);
lastClassToken = nodeUtils.findNextToken(lastTypeParameter, ast, ast);
}
result.typeParameters = convertTSTypeParametersToTypeParametersDeclaration(
(node as any).typeParameters
Expand All @@ -1517,14 +1543,14 @@ export function convert(config: any): ESTreeNode | null {
const lastModifier = node.modifiers[node.modifiers.length - 1];

if (!lastClassToken || lastModifier.pos > lastClassToken.pos) {
lastClassToken = nodeUtils.findNextToken(lastModifier, ast);
lastClassToken = nodeUtils.findNextToken(lastModifier, ast, ast);
}
} else if (!lastClassToken) {
// no name
lastClassToken = node.getFirstToken();
}

const openBrace = nodeUtils.findNextToken(lastClassToken, ast);
const openBrace = nodeUtils.findNextToken(lastClassToken, ast, ast)!;
const superClass = heritageClauses.find(
(clause: any) => clause.token === SyntaxKind.ExtendsKeyword
);
Expand Down Expand Up @@ -1557,8 +1583,8 @@ export function convert(config: any): ESTreeNode | null {
body: [],

// TODO: Fix location info
range: [openBrace.getStart(), (result as any).range[1]],
loc: nodeUtils.getLocFor(openBrace.getStart(), node.end, ast)
range: [openBrace.getStart(ast), (result as any).range[1]],
loc: nodeUtils.getLocFor(openBrace.getStart(ast), node.end, ast)
},
superClass:
superClass && superClass.types[0]
Expand Down Expand Up @@ -2216,7 +2242,7 @@ export function convert(config: any): ESTreeNode | null {
type: AST_NODE_TYPES.VariableDeclarator,
id: convertChild((node as any).name),
init: convertChild((node as any).type),
range: [(node as any).name.getStart(), (node as any).end]
range: [(node as any).name.getStart(ast), (node as any).end]
};

(typeAliasDeclarator as any).loc = nodeUtils.getLocFor(
Expand Down Expand Up @@ -2359,6 +2385,7 @@ export function convert(config: any): ESTreeNode | null {
) {
interfaceLastClassToken = nodeUtils.findNextToken(
interfaceLastTypeParameter,
ast,
ast
);
}
Expand All @@ -2374,14 +2401,19 @@ export function convert(config: any): ESTreeNode | null {
);
const interfaceOpenBrace = nodeUtils.findNextToken(
interfaceLastClassToken,
ast,
ast
);
)!;

const interfaceBody = {
type: AST_NODE_TYPES.TSInterfaceBody,
body: (node as any).members.map((member: any) => convertChild(member)),
range: [interfaceOpenBrace.getStart(), (result as any).range[1]],
loc: nodeUtils.getLocFor(interfaceOpenBrace.getStart(), node.end, ast)
range: [interfaceOpenBrace.getStart(ast), (result as any).range[1]],
loc: nodeUtils.getLocFor(
interfaceOpenBrace.getStart(ast),
node.end,
ast
)
};

Object.assign(result, {
Expand Down Expand Up @@ -2492,5 +2524,8 @@ export function convert(config: any): ESTreeNode | null {
deeplyCopy();
}

tsNodeToESTreeNodeMap.set(node, result);
esTreeNodeToTSNodeMap.set(result, node);

return result as any;
}
Loading