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

Commit 7c1be31

Browse files
authored
Merge branch 'master' into typed-rest-element
2 parents 38da62e + 66ae047 commit 7c1be31

File tree

4 files changed

+955
-126
lines changed

4 files changed

+955
-126
lines changed

src/convert.ts

Lines changed: 47 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -140,33 +140,39 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
140140
}
141141

142142
/**
143-
* Coverts body ExpressionStatements to directives
143+
* Coverts body Nodes and add directive field to StringLiterals
144+
* @param {ts.NodeArray<ts.Statement>} nodes of ts.Node
145+
* @returns {ESTreeNode[]} Array of body statements
144146
*/
145-
function convertBodyExpressionsToDirectives() {
146-
if (result.body && nodeUtils.canContainDirective(node)) {
147-
const unique: string[] = [];
148-
149-
// directives has to be unique, if directive is registered twice pick only first one
150-
result.body
151-
.filter(
152-
(child: ESTreeNode) =>
153-
child.type === AST_NODE_TYPES.ExpressionStatement &&
147+
function convertBodyExpressions(
148+
nodes: ts.NodeArray<ts.Statement>
149+
): ESTreeNode[] {
150+
// directives has to be unique, if directive is registered twice pick only first one
151+
const unique: string[] = [];
152+
const allowDirectives = nodeUtils.canContainDirective(node);
153+
154+
return (
155+
nodes
156+
.map(statement => {
157+
const child = convertChild(statement);
158+
if (
159+
allowDirectives &&
160+
child &&
154161
child.expression &&
155-
child.expression.type === AST_NODE_TYPES.Literal &&
156-
(child.expression as any).value &&
157-
typeof (child.expression as any).value === 'string' &&
158-
// ignore parenthesized expressions
159-
ast.text.charAt(child.range[0]) !== '('
160-
)
161-
.forEach(
162-
(child: { directive: string; expression: { raw: string } }) => {
163-
if (!unique.includes((child.expression as any).raw)) {
164-
child.directive = child.expression.raw.slice(1, -1);
165-
unique.push(child.expression.raw);
162+
ts.isExpressionStatement(statement) &&
163+
ts.isStringLiteral(statement.expression)
164+
) {
165+
const raw = child.expression.raw!;
166+
if (!unique.includes(raw)) {
167+
child.directive = raw.slice(1, -1);
168+
unique.push(raw);
166169
}
167170
}
168-
);
169-
}
171+
return child!; // child can be null but it's filtered below
172+
})
173+
// filter out unknown nodes for now
174+
.filter(statement => statement)
175+
);
170176
}
171177

172178
/**
@@ -244,45 +250,22 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
244250
}
245251

246252
/**
247-
* Converts a child into a class implements node. This creates an intermediary
248-
* ClassImplements node to match what Flow does.
249-
* @param {ts.ExpressionWithTypeArguments} child The TypeScript AST node to convert.
250-
* @returns {ESTreeNode} The type annotation node.
251-
*/
252-
function convertClassImplements(
253-
child: ts.ExpressionWithTypeArguments
254-
): ESTreeNode {
255-
const id = convertChild(child.expression) as ESTreeNode;
256-
const classImplementsNode: ESTreeNode = {
257-
type: AST_NODE_TYPES.ClassImplements,
258-
loc: id.loc,
259-
range: id.range,
260-
id
261-
};
262-
if (child.typeArguments && child.typeArguments.length) {
263-
classImplementsNode.typeParameters = convertTypeArgumentsToTypeParameters(
264-
child.typeArguments
265-
);
266-
}
267-
return classImplementsNode;
268-
}
269-
270-
/**
271-
* Converts a child into a interface heritage node.
253+
* Converts a child into a specified heritage node.
254+
* @param {AST_NODE_TYPES} nodeType Type of node to be used
272255
* @param {ts.ExpressionWithTypeArguments} child The TypeScript AST node to convert.
273-
* @returns {ESTreeNode} The type annotation node.
256+
* @returns {ESTreeNode} The heritage node.
274257
*/
275-
function convertInterfaceHeritageClause(
258+
function convertHeritageClause(
259+
nodeType: AST_NODE_TYPES,
276260
child: ts.ExpressionWithTypeArguments
277261
): ESTreeNode {
278-
const id = convertChild(child.expression) as ESTreeNode;
262+
const id = convertChild(child.expression)!;
279263
const classImplementsNode: ESTreeNode = {
280-
type: AST_NODE_TYPES.TSInterfaceHeritage,
264+
type: nodeType,
281265
loc: id.loc,
282266
range: id.range,
283267
id
284268
};
285-
286269
if (child.typeArguments && child.typeArguments.length) {
287270
classImplementsNode.typeParameters = convertTypeArgumentsToTypeParameters(
288271
child.typeArguments
@@ -488,21 +471,11 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
488471
case SyntaxKind.SourceFile:
489472
Object.assign(result, {
490473
type: AST_NODE_TYPES.Program,
491-
body: [],
474+
body: convertBodyExpressions(node.statements),
492475
// externalModuleIndicator is internal field in TSC
493476
sourceType: (node as any).externalModuleIndicator ? 'module' : 'script'
494477
});
495478

496-
// filter out unknown nodes for now
497-
node.statements.forEach((statement: any) => {
498-
const convertedStatement = convertChild(statement);
499-
if (convertedStatement) {
500-
result.body.push(convertedStatement);
501-
}
502-
});
503-
504-
convertBodyExpressionsToDirectives();
505-
506479
result.range[1] = node.endOfFileToken.end;
507480
result.loc = nodeUtils.getLocFor(
508481
node.getStart(ast),
@@ -514,10 +487,8 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
514487
case SyntaxKind.Block:
515488
Object.assign(result, {
516489
type: AST_NODE_TYPES.BlockStatement,
517-
body: node.statements.map(convertChild)
490+
body: convertBodyExpressions(node.statements)
518491
});
519-
520-
convertBodyExpressionsToDirectives();
521492
break;
522493

523494
case SyntaxKind.Identifier:
@@ -1605,8 +1576,9 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
16051576
});
16061577

16071578
if (implementsClause) {
1608-
(result as any).implements = implementsClause.types.map(
1609-
convertClassImplements
1579+
(result as any).implements = implementsClause.types.map(el =>
1580+
// ClassImplements node to match what Flow does.
1581+
convertHeritageClause(AST_NODE_TYPES.ClassImplements, el)
16101582
);
16111583
}
16121584

@@ -1636,10 +1608,8 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
16361608
case SyntaxKind.ModuleBlock:
16371609
Object.assign(result, {
16381610
type: AST_NODE_TYPES.TSModuleBlock,
1639-
body: node.statements.map(convertChild)
1611+
body: convertBodyExpressions(node.statements)
16401612
});
1641-
1642-
convertBodyExpressionsToDirectives();
16431613
break;
16441614

16451615
case SyntaxKind.ImportDeclaration:
@@ -2236,7 +2206,7 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
22362206
case SyntaxKind.TypeParameter: {
22372207
Object.assign(result, {
22382208
type: AST_NODE_TYPES.TSTypeParameter,
2239-
name: node.name.text,
2209+
name: convertChildType(node.name),
22402210
constraint: node.constraint
22412211
? convertChildType(node.constraint)
22422212
: undefined,
@@ -2525,8 +2495,8 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
25252495

25262496
const interfaceBody = {
25272497
type: AST_NODE_TYPES.TSInterfaceBody,
2528-
body: node.members.map((member: any) => convertChild(member)),
2529-
range: [interfaceOpenBrace.getStart(ast), result.range[1]],
2498+
body: node.members.map(member => convertChild(member)),
2499+
range: [interfaceOpenBrace.getStart(ast), node.end],
25302500
loc: nodeUtils.getLocFor(
25312501
interfaceOpenBrace.getStart(ast),
25322502
node.end,
@@ -2539,8 +2509,8 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
25392509
body: interfaceBody,
25402510
id: convertChild(node.name),
25412511
heritage: hasImplementsClause
2542-
? interfaceHeritageClauses[0].types.map(
2543-
convertInterfaceHeritageClause
2512+
? interfaceHeritageClauses[0].types.map(el =>
2513+
convertHeritageClause(AST_NODE_TYPES.TSInterfaceHeritage, el)
25442514
)
25452515
: []
25462516
});

src/temp-types-based-on-js-source.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export interface ESTreeNode {
3030
typeAnnotation?: ESTreeNode | null;
3131
typeParameters?: ESTreeNode | null;
3232
id?: ESTreeNode | null;
33+
raw?: string;
34+
value?: string;
3335
expression?: ESTreeNode | null;
3436
decorators?: (ESTreeNode | null)[];
3537
const?: boolean;

tests/ast-alignment/utils.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import isPlainObject from 'lodash.isplainobject';
2+
import { AST_NODE_TYPES } from '../../src/ast-node-types';
23

34
/**
45
* By default, pretty-format (within Jest matchers) retains the names/types of nodes from the babylon AST,
@@ -194,6 +195,29 @@ export function preprocessBabylonAST(ast: any): any {
194195
node.params = node.parameters;
195196
delete node.parameters;
196197
}
198+
},
199+
/**
200+
* We want this node to be different
201+
* @see https://github.com/JamesHenry/typescript-estree/issues/109
202+
*/
203+
TSTypeParameter(node: any) {
204+
if (node.name) {
205+
node.name = {
206+
loc: {
207+
start: {
208+
column: node.loc.start.column,
209+
line: node.loc.start.line
210+
},
211+
end: {
212+
column: node.loc.start.column + node.name.length,
213+
line: node.loc.start.line
214+
}
215+
},
216+
name: node.name,
217+
range: [node.range[0], node.range[0] + node.name.length],
218+
type: AST_NODE_TYPES.Identifier
219+
};
220+
}
197221
}
198222
}
199223
);

0 commit comments

Comments
 (0)