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

Commit aa88c9e

Browse files
committed
fix: treeNodeMaps for types and add typeMode
Additionally fix issue that Object literal is not TypeReference
1 parent 6f52909 commit aa88c9e

File tree

5 files changed

+1044
-128
lines changed

5 files changed

+1044
-128
lines changed

src/convert.ts

Lines changed: 73 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ interface ConvertAdditionalOptions {
3434
interface ConvertConfig {
3535
node: ts.Node;
3636
parent?: ts.Node | null;
37+
inTypeMode?: boolean;
3738
ast: ts.SourceFile;
3839
additionalOptions: ConvertAdditionalOptions;
3940
}
@@ -80,31 +81,45 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
8081
});
8182
}
8283

83-
/**
84-
* Converts a TypeScript node into an ESTree node.
85-
* @param {ts.Node} child the child ts.Node
86-
* @returns {ESTreeNode|null} the converted ESTree node
87-
*/
88-
function convertChild(child?: ts.Node): ESTreeNode | null {
84+
function converter(child?: ts.Node, inTypeMode?: boolean): ESTreeNode | null {
8985
if (!child) {
9086
return null;
9187
}
9288
return convert({
9389
node: child,
9490
parent: node,
91+
inTypeMode,
9592
ast,
9693
additionalOptions
9794
});
9895
}
9996

97+
/**
98+
* Converts a TypeScript node into an ESTree node.
99+
* @param {ts.Node} child the child ts.Node
100+
* @returns {ESTreeNode|null} the converted ESTree node
101+
*/
102+
function convertChild(child?: ts.Node): ESTreeNode | null {
103+
return converter(child, config.inTypeMode);
104+
}
105+
106+
/**
107+
* Converts a TypeScript node into an ESTree node.
108+
* @param {ts.Node} child the child ts.Node
109+
* @returns {ESTreeNode|null} the converted ESTree node
110+
*/
111+
function convertChildType(child?: ts.Node): ESTreeNode | null {
112+
return converter(child, true);
113+
}
114+
100115
/**
101116
* Converts a child into a type annotation. This creates an intermediary
102117
* TypeAnnotation node to match what Flow does.
103118
* @param {ts.TypeNode} child The TypeScript AST node to convert.
104119
* @returns {ESTreeNode} The type annotation node.
105120
*/
106121
function convertTypeAnnotation(child: ts.TypeNode): ESTreeNode {
107-
const annotation = convertChild(child);
122+
const annotation = convertChildType(child);
108123
const annotationStartCol = child.getFullStart() - 1;
109124
const loc = nodeUtils.getLocFor(annotationStartCol, child.end, ast);
110125
return {
@@ -182,32 +197,7 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
182197
type: AST_NODE_TYPES.TSTypeParameterInstantiation,
183198
range: [start, end],
184199
loc: nodeUtils.getLocFor(start, end, ast),
185-
params: typeArguments.map(typeArgument => {
186-
if (nodeUtils.isTypeKeyword(typeArgument.kind)) {
187-
return {
188-
type: AST_NODE_TYPES[`TS${SyntaxKind[typeArgument.kind]}`],
189-
range: [typeArgument.getStart(ast), typeArgument.getEnd()],
190-
loc: nodeUtils.getLoc(typeArgument, ast)
191-
};
192-
}
193-
if (typeArgument.kind === SyntaxKind.ImportType) {
194-
return convert({
195-
node: typeArgument,
196-
parent: null,
197-
ast,
198-
additionalOptions
199-
});
200-
}
201-
return {
202-
type: AST_NODE_TYPES.TSTypeReference,
203-
range: [typeArgument.getStart(ast), typeArgument.getEnd()],
204-
loc: nodeUtils.getLoc(typeArgument, ast),
205-
typeName: convertChild(typeArgument.typeName || typeArgument),
206-
typeParameters: typeArgument.typeArguments
207-
? convertTypeArgumentsToTypeParameters(typeArgument.typeArguments)
208-
: undefined
209-
};
210-
})
200+
params: typeArguments.map(typeArgument => convertChildType(typeArgument))
211201
};
212202
}
213203

@@ -236,36 +226,9 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
236226
greaterThanToken!.end,
237227
ast
238228
),
239-
params: typeParameters.map(typeParameter => {
240-
const name = typeParameter.name.text;
241-
242-
const constraint = typeParameter.constraint
243-
? convert({
244-
node: typeParameter.constraint,
245-
parent: typeParameter,
246-
ast,
247-
additionalOptions
248-
})
249-
: undefined;
250-
251-
const defaultParameter = typeParameter.default
252-
? convert({
253-
node: typeParameter.default,
254-
parent: typeParameter,
255-
ast,
256-
additionalOptions
257-
})
258-
: typeParameter.default;
259-
260-
return {
261-
type: AST_NODE_TYPES.TSTypeParameter,
262-
range: [typeParameter.getStart(ast), typeParameter.getEnd()],
263-
loc: nodeUtils.getLoc(typeParameter, ast),
264-
name,
265-
constraint,
266-
default: defaultParameter
267-
};
268-
})
229+
params: typeParameters.map(typeParameter =>
230+
convertChildType(typeParameter)
231+
)
269232
};
270233
}
271234

@@ -2091,7 +2054,7 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
20912054
break;
20922055

20932056
case SyntaxKind.NullKeyword: {
2094-
if (nodeUtils.isWithinTypeAnnotation(node)) {
2057+
if (config.inTypeMode) {
20952058
Object.assign(result, {
20962059
type: AST_NODE_TYPES.TSNullKeyword
20972060
});
@@ -2279,6 +2242,45 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
22792242

22802243
// TypeScript specific
22812244

2245+
case SyntaxKind.TypeReference: {
2246+
Object.assign(result, {
2247+
type: AST_NODE_TYPES.TSTypeReference,
2248+
typeName: convertChildType(node.typeName),
2249+
typeParameters: node.typeArguments
2250+
? convertTypeArgumentsToTypeParameters(node.typeArguments)
2251+
: undefined
2252+
});
2253+
break;
2254+
}
2255+
2256+
case SyntaxKind.TypeParameter: {
2257+
Object.assign(result, {
2258+
type: AST_NODE_TYPES.TSTypeParameter,
2259+
name: node.name.text,
2260+
constraint: node.constraint
2261+
? convertChildType(node.constraint)
2262+
: undefined,
2263+
default: node.default ? convertChildType(node.default) : undefined
2264+
});
2265+
break;
2266+
}
2267+
2268+
case SyntaxKind.AnyKeyword:
2269+
case SyntaxKind.BigIntKeyword:
2270+
case SyntaxKind.BooleanKeyword:
2271+
case SyntaxKind.NeverKeyword:
2272+
case SyntaxKind.NumberKeyword:
2273+
case SyntaxKind.ObjectKeyword:
2274+
case SyntaxKind.StringKeyword:
2275+
case SyntaxKind.SymbolKeyword:
2276+
case SyntaxKind.UnknownKeyword:
2277+
case SyntaxKind.VoidKeyword: {
2278+
Object.assign(result, {
2279+
type: `TS${SyntaxKind[node.kind]}`
2280+
});
2281+
break;
2282+
}
2283+
22822284
case SyntaxKind.ParenthesizedExpression:
22832285
return convert({
22842286
node: node.expression,
@@ -2291,7 +2293,7 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
22912293
Object.assign(result, {
22922294
type: AST_NODE_TYPES.TSTypeAliasDeclaration,
22932295
id: convertChild(node.name),
2294-
typeAnnotation: convertChild(node.type)
2296+
typeAnnotation: convertChildType(node.type)
22952297
});
22962298

22972299
if (nodeUtils.hasModifier(SyntaxKind.DeclareKeyword, node)) {
@@ -2583,42 +2585,42 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
25832585
case SyntaxKind.OptionalType: {
25842586
Object.assign(result, {
25852587
type: AST_NODE_TYPES.TSOptionalType,
2586-
typeAnnotation: convertChild(node.type)
2588+
typeAnnotation: convertChildType(node.type)
25872589
});
25882590
break;
25892591
}
25902592
case SyntaxKind.ParenthesizedType: {
25912593
Object.assign(result, {
25922594
type: AST_NODE_TYPES.TSParenthesizedType,
2593-
typeAnnotation: convertChild(node.type)
2595+
typeAnnotation: convertChildType(node.type)
25942596
});
25952597
break;
25962598
}
25972599
case SyntaxKind.TupleType: {
25982600
Object.assign(result, {
25992601
type: AST_NODE_TYPES.TSTupleType,
2600-
elementTypes: node.elementTypes.map(convertChild)
2602+
elementTypes: node.elementTypes.map(convertChildType)
26012603
});
26022604
break;
26032605
}
26042606
case SyntaxKind.UnionType: {
26052607
Object.assign(result, {
26062608
type: AST_NODE_TYPES.TSUnionType,
2607-
types: node.types.map(convertChild)
2609+
types: node.types.map(convertChildType)
26082610
});
26092611
break;
26102612
}
26112613
case SyntaxKind.IntersectionType: {
26122614
Object.assign(result, {
26132615
type: AST_NODE_TYPES.TSIntersectionType,
2614-
types: node.types.map(convertChild)
2616+
types: node.types.map(convertChildType)
26152617
});
26162618
break;
26172619
}
26182620
case SyntaxKind.RestType: {
26192621
Object.assign(result, {
26202622
type: AST_NODE_TYPES.TSRestType,
2621-
typeAnnotation: convertChild(node.type)
2623+
typeAnnotation: convertChildType(node.type)
26222624
});
26232625
break;
26242626
}

src/node-utils.ts

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,6 @@ export default {
160160
convertToken,
161161
convertTokens,
162162
getNodeContainer,
163-
isWithinTypeAnnotation,
164-
isTypeKeyword,
165163
isComment,
166164
isJSDocComment,
167165
createError,
@@ -357,29 +355,6 @@ function isJSXToken(node: ts.Node): boolean {
357355
);
358356
}
359357

360-
/**
361-
* Returns true if the given ts.Node.kind value corresponds to a type keyword
362-
* @param {number} kind TypeScript SyntaxKind
363-
* @returns {boolean} is a type keyword
364-
*/
365-
function isTypeKeyword(kind: number): boolean {
366-
switch (kind) {
367-
case SyntaxKind.AnyKeyword:
368-
case SyntaxKind.BooleanKeyword:
369-
case SyntaxKind.BigIntKeyword:
370-
case SyntaxKind.NeverKeyword:
371-
case SyntaxKind.NumberKeyword:
372-
case SyntaxKind.ObjectKeyword:
373-
case SyntaxKind.StringKeyword:
374-
case SyntaxKind.SymbolKeyword:
375-
case SyntaxKind.UnknownKeyword:
376-
case SyntaxKind.VoidKeyword:
377-
return true;
378-
default:
379-
return false;
380-
}
381-
}
382-
383358
/**
384359
* Returns the declaration kind of the given ts.Node
385360
* @param {ts.Node} node TypeScript AST node
@@ -566,19 +541,6 @@ function isOptional(node: { questionToken?: ts.QuestionToken }): boolean {
566541
: false;
567542
}
568543

569-
/**
570-
* Returns true if the given ts.Node is within the context of a "typeAnnotation",
571-
* which effectively means - is it coming from its parent's `type` or `types` property
572-
* @param {ts.Node} node ts.Node to be checked
573-
* @returns {boolean} is within "typeAnnotation context"
574-
*/
575-
function isWithinTypeAnnotation(node: any): boolean {
576-
return (
577-
node.parent.type === node ||
578-
(node.parent.types && node.parent.types.indexOf(node) > -1)
579-
);
580-
}
581-
582544
/**
583545
* Fixes the exports of the given ts.Node
584546
* @param {ts.Node} node the ts.Node
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
function M<T extends Constructor<M>>(Base: T) {
2+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
let x: number extends string ? boolean : null;

0 commit comments

Comments
 (0)