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

Commit

Permalink
fix: treeNodeMaps for types and add typeMode
Browse files Browse the repository at this point in the history
Additionally fix issue that Object literal is not TypeReference
  • Loading branch information
armano2 committed Dec 26, 2018
1 parent 90319aa commit 5a568c5
Show file tree
Hide file tree
Showing 6 changed files with 1,048 additions and 128 deletions.
144 changes: 73 additions & 71 deletions src/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ interface ConvertAdditionalOptions {
interface ConvertConfig {
node: ts.Node;
parent?: ts.Node | null;
inTypeMode?: boolean;
ast: ts.SourceFile;
additionalOptions: ConvertAdditionalOptions;
}
Expand Down Expand Up @@ -80,31 +81,45 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
});
}

/**
* Converts a TypeScript node into an ESTree node.
* @param {ts.Node} child the child ts.Node
* @returns {ESTreeNode|null} the converted ESTree node
*/
function convertChild(child?: ts.Node): ESTreeNode | null {
function converter(child?: ts.Node, inTypeMode?: boolean): ESTreeNode | null {
if (!child) {
return null;
}
return convert({
node: child,
parent: node,
inTypeMode,
ast,
additionalOptions
});
}

/**
* Converts a TypeScript node into an ESTree node.
* @param {ts.Node} child the child ts.Node
* @returns {ESTreeNode|null} the converted ESTree node
*/
function convertChild(child?: ts.Node): ESTreeNode | null {
return converter(child, config.inTypeMode);
}

/**
* Converts a TypeScript node into an ESTree node.
* @param {ts.Node} child the child ts.Node
* @returns {ESTreeNode|null} the converted ESTree node
*/
function convertChildType(child?: ts.Node): ESTreeNode | null {
return converter(child, true);
}

/**
* Converts a child into a type annotation. This creates an intermediary
* TypeAnnotation node to match what Flow does.
* @param {ts.TypeNode} child The TypeScript AST node to convert.
* @returns {ESTreeNode} The type annotation node.
*/
function convertTypeAnnotation(child: ts.TypeNode): ESTreeNode {
const annotation = convertChild(child);
const annotation = convertChildType(child);
const annotationStartCol = child.getFullStart() - 1;
const loc = nodeUtils.getLocFor(annotationStartCol, child.end, ast);
return {
Expand Down Expand Up @@ -182,32 +197,7 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
type: AST_NODE_TYPES.TSTypeParameterInstantiation,
range: [start, end],
loc: nodeUtils.getLocFor(start, end, ast),
params: typeArguments.map(typeArgument => {
if (nodeUtils.isTypeKeyword(typeArgument.kind)) {
return {
type: AST_NODE_TYPES[`TS${SyntaxKind[typeArgument.kind]}`],
range: [typeArgument.getStart(ast), typeArgument.getEnd()],
loc: nodeUtils.getLoc(typeArgument, ast)
};
}
if (typeArgument.kind === SyntaxKind.ImportType) {
return convert({
node: typeArgument,
parent: null,
ast,
additionalOptions
});
}
return {
type: AST_NODE_TYPES.TSTypeReference,
range: [typeArgument.getStart(ast), typeArgument.getEnd()],
loc: nodeUtils.getLoc(typeArgument, ast),
typeName: convertChild(typeArgument.typeName || typeArgument),
typeParameters: typeArgument.typeArguments
? convertTypeArgumentsToTypeParameters(typeArgument.typeArguments)
: undefined
};
})
params: typeArguments.map(typeArgument => convertChildType(typeArgument))
};
}

Expand Down Expand Up @@ -236,36 +226,9 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
greaterThanToken!.end,
ast
),
params: typeParameters.map(typeParameter => {
const name = typeParameter.name.text;

const constraint = typeParameter.constraint
? convert({
node: typeParameter.constraint,
parent: typeParameter,
ast,
additionalOptions
})
: undefined;

const defaultParameter = typeParameter.default
? convert({
node: typeParameter.default,
parent: typeParameter,
ast,
additionalOptions
})
: typeParameter.default;

return {
type: AST_NODE_TYPES.TSTypeParameter,
range: [typeParameter.getStart(ast), typeParameter.getEnd()],
loc: nodeUtils.getLoc(typeParameter, ast),
name,
constraint,
default: defaultParameter
};
})
params: typeParameters.map(typeParameter =>
convertChildType(typeParameter)
)
};
}

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

case SyntaxKind.NullKeyword: {
if (nodeUtils.isWithinTypeAnnotation(node)) {
if (config.inTypeMode) {
Object.assign(result, {
type: AST_NODE_TYPES.TSNullKeyword
});
Expand Down Expand Up @@ -2279,6 +2242,45 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {

// TypeScript specific

case SyntaxKind.TypeReference: {
Object.assign(result, {
type: AST_NODE_TYPES.TSTypeReference,
typeName: convertChildType(node.typeName),
typeParameters: node.typeArguments
? convertTypeArgumentsToTypeParameters(node.typeArguments)
: undefined
});
break;
}

case SyntaxKind.TypeParameter: {
Object.assign(result, {
type: AST_NODE_TYPES.TSTypeParameter,
name: node.name.text,
constraint: node.constraint
? convertChildType(node.constraint)
: undefined,
default: node.default ? convertChildType(node.default) : undefined
});
break;
}

case SyntaxKind.AnyKeyword:
case SyntaxKind.BigIntKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.ObjectKeyword:
case SyntaxKind.StringKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.UnknownKeyword:
case SyntaxKind.VoidKeyword: {
Object.assign(result, {
type: `TS${SyntaxKind[node.kind]}`
});
break;
}

case SyntaxKind.ParenthesizedExpression:
return convert({
node: node.expression,
Expand All @@ -2291,7 +2293,7 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
Object.assign(result, {
type: AST_NODE_TYPES.TSTypeAliasDeclaration,
id: convertChild(node.name),
typeAnnotation: convertChild(node.type)
typeAnnotation: convertChildType(node.type)
});

if (nodeUtils.hasModifier(SyntaxKind.DeclareKeyword, node)) {
Expand Down Expand Up @@ -2561,42 +2563,42 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
case SyntaxKind.OptionalType: {
Object.assign(result, {
type: AST_NODE_TYPES.TSOptionalType,
typeAnnotation: convertChild(node.type)
typeAnnotation: convertChildType(node.type)
});
break;
}
case SyntaxKind.ParenthesizedType: {
Object.assign(result, {
type: AST_NODE_TYPES.TSParenthesizedType,
typeAnnotation: convertChild(node.type)
typeAnnotation: convertChildType(node.type)
});
break;
}
case SyntaxKind.TupleType: {
Object.assign(result, {
type: AST_NODE_TYPES.TSTupleType,
elementTypes: node.elementTypes.map(convertChild)
elementTypes: node.elementTypes.map(convertChildType)
});
break;
}
case SyntaxKind.UnionType: {
Object.assign(result, {
type: AST_NODE_TYPES.TSUnionType,
types: node.types.map(convertChild)
types: node.types.map(convertChildType)
});
break;
}
case SyntaxKind.IntersectionType: {
Object.assign(result, {
type: AST_NODE_TYPES.TSIntersectionType,
types: node.types.map(convertChild)
types: node.types.map(convertChildType)
});
break;
}
case SyntaxKind.RestType: {
Object.assign(result, {
type: AST_NODE_TYPES.TSRestType,
typeAnnotation: convertChild(node.type)
typeAnnotation: convertChildType(node.type)
});
break;
}
Expand Down
38 changes: 0 additions & 38 deletions src/node-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ export default {
convertToken,
convertTokens,
getNodeContainer,
isWithinTypeAnnotation,
isTypeKeyword,
isComment,
isJSDocComment,
createError,
Expand Down Expand Up @@ -357,29 +355,6 @@ function isJSXToken(node: ts.Node): boolean {
);
}

/**
* Returns true if the given ts.Node.kind value corresponds to a type keyword
* @param {number} kind TypeScript SyntaxKind
* @returns {boolean} is a type keyword
*/
function isTypeKeyword(kind: number): boolean {
switch (kind) {
case SyntaxKind.AnyKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.BigIntKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.ObjectKeyword:
case SyntaxKind.StringKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.UnknownKeyword:
case SyntaxKind.VoidKeyword:
return true;
default:
return false;
}
}

/**
* Returns the declaration kind of the given ts.Node
* @param {ts.Node} node TypeScript AST node
Expand Down Expand Up @@ -566,19 +541,6 @@ function isOptional(node: { questionToken?: ts.QuestionToken }): boolean {
: false;
}

/**
* Returns true if the given ts.Node is within the context of a "typeAnnotation",
* which effectively means - is it coming from its parent's `type` or `types` property
* @param {ts.Node} node ts.Node to be checked
* @returns {boolean} is within "typeAnnotation context"
*/
function isWithinTypeAnnotation(node: any): boolean {
return (
node.parent.type === node ||
(node.parent.types && node.parent.types.indexOf(node) > -1)
);
}

/**
* Fixes the exports of the given ts.Node
* @param {ts.Node} node the ts.Node
Expand Down
4 changes: 4 additions & 0 deletions tests/ast-alignment/fixtures-to-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,10 @@ let fixturePatternConfigsToTest = [
]
}),

createFixturePatternConfigFor('typescript/types', {
fileType: 'ts'
}),

createFixturePatternConfigFor('typescript/declare', {
fileType: 'ts',
ignore: [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
function M<T extends Constructor<M>>(Base: T) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let x: number extends string ? boolean : null;
Loading

0 comments on commit 5a568c5

Please sign in to comment.