From 0d7c84ef283adc807b33a07323e4005dc30461d3 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 3 Oct 2016 19:05:12 -0700 Subject: [PATCH 1/4] Added literal kind properties for each node. --- scripts/tslint/typeOperatorSpacingRule.ts | 9 +- src/compiler/binder.ts | 4 +- src/compiler/checker.ts | 40 +- src/compiler/core.ts | 6 +- src/compiler/declarationEmitter.ts | 7 +- src/compiler/emitter.ts | 12 +- src/compiler/factory.ts | 48 +- src/compiler/parser.ts | 82 +-- src/compiler/transformers/destructuring.ts | 4 +- src/compiler/transformers/es6.ts | 2 +- src/compiler/transformers/generators.ts | 2 +- src/compiler/transformers/module/module.ts | 8 +- src/compiler/transformers/module/system.ts | 2 +- src/compiler/transformers/ts.ts | 10 +- src/compiler/types.ts | 591 ++++++++++++--------- src/compiler/utilities.ts | 14 +- src/compiler/visitor.ts | 4 +- src/services/formatting/formatting.ts | 2 +- src/services/formatting/smartIndenter.ts | 7 +- src/services/services.ts | 29 +- src/services/symbolDisplay.ts | 6 +- 21 files changed, 509 insertions(+), 380 deletions(-) diff --git a/scripts/tslint/typeOperatorSpacingRule.ts b/scripts/tslint/typeOperatorSpacingRule.ts index 7ceef2372bf..559d1b34937 100644 --- a/scripts/tslint/typeOperatorSpacingRule.ts +++ b/scripts/tslint/typeOperatorSpacingRule.ts @@ -18,8 +18,13 @@ class TypeOperatorSpacingWalker extends Lint.RuleWalker { for (let i = 1; i < types.length; i++) { const currentType = types[i]; if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) { - const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING); - this.addFailure(failure); + const sourceFile = currentType.getSourceFile(); + const previousTypeEndPos = sourceFile.getLineAndCharacterOfPosition(types[i - 1].end); + const currentTypeStartPos = sourceFile.getLineAndCharacterOfPosition(currentType.pos); + if (previousTypeEndPos.line === currentTypeStartPos.line) { + const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING); + this.addFailure(failure); + } } expectedStart = currentType.end + 2; } diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 2fe7d30ab56..65c2f5f3f84 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1111,7 +1111,7 @@ namespace ts { } else { forEachChild(node, bind); - if (node.operator === SyntaxKind.PlusEqualsToken || node.operator === SyntaxKind.MinusMinusToken) { + if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) { bindAssignmentTargetFlow(node.operand); } } @@ -1360,7 +1360,7 @@ namespace ts { function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean { const body = node.kind === SyntaxKind.SourceFile ? node : (node).body; if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) { - for (const stat of (body).statements) { + for (const stat of (body).statements) { if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) { return true; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bf7e4ef92e6..2088fa8761e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3886,7 +3886,7 @@ namespace ts { if (!links.declaredType) { const enumType = getDeclaredTypeOfEnum(getParentOfSymbol(symbol)); links.declaredType = enumType.flags & TypeFlags.Union ? - enumType.memberTypes[getEnumMemberValue(symbol.valueDeclaration)] : + enumType.memberTypes[getEnumMemberValue(symbol.valueDeclaration)] : enumType; } return links.declaredType; @@ -6049,7 +6049,7 @@ namespace ts { return !node.typeParameters && areAllParametersUntyped && !isNullaryArrow; } - function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | MethodDeclaration { + function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration { return (isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func); } @@ -10022,7 +10022,7 @@ namespace ts { } } - function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression { + function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction { return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction; } @@ -10033,7 +10033,7 @@ namespace ts { : undefined; } - function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | MethodDeclaration) { + function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | ArrowFunction | MethodDeclaration) { return isObjectLiteralMethod(node) ? getContextualTypeForObjectLiteralMethod(node) : getApparentTypeOfContextualType(node); @@ -10044,7 +10044,7 @@ namespace ts { // If the contextual type is a union type, get the signature from each type possible and if they are // all identical ignoring their return type, the result is same signature but with return type as // union type of return types from these signatures - function getContextualSignature(node: FunctionExpression | MethodDeclaration): Signature { + function getContextualSignature(node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature { Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); const type = getContextualTypeForFunctionLikeDeclaration(node); if (!type) { @@ -11392,7 +11392,7 @@ namespace ts { argCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature); } else { - const callExpression = node; + const callExpression = node; if (!callExpression.arguments) { // This only happens when we have something of the form: 'new C' Debug.assert(callExpression.kind === SyntaxKind.NewExpression); @@ -11403,7 +11403,7 @@ namespace ts { argCount = signatureHelpTrailingComma ? args.length + 1 : args.length; // If we are missing the close paren, the call is incomplete. - callIsIncomplete = (callExpression).arguments.end === callExpression.end; + callIsIncomplete = callExpression.arguments.end === callExpression.end; typeArguments = callExpression.typeArguments; spreadArgIndex = getSpreadArgumentIndex(args); @@ -12490,7 +12490,7 @@ namespace ts { * @param node The call/new expression to be checked. * @returns On success, the expression's signature's return type. On failure, anyType. */ - function checkCallExpression(node: CallExpression): Type { + function checkCallExpression(node: CallExpression | NewExpression): Type { // Grammar checking; stop grammar-checking if checkGrammarTypeArguments return true checkGrammarTypeArguments(node, node.typeArguments) || checkGrammarArguments(node, node.arguments); @@ -12945,7 +12945,7 @@ namespace ts { } } - if (produceDiagnostics && node.kind !== SyntaxKind.MethodDeclaration && node.kind !== SyntaxKind.MethodSignature) { + if (produceDiagnostics && node.kind !== SyntaxKind.MethodDeclaration) { checkCollisionWithCapturedSuperVariable(node, (node).name); checkCollisionWithCapturedThisVariable(node, (node).name); } @@ -17419,9 +17419,12 @@ namespace ts { } } - checkCollisionWithCapturedThisVariable(node, node.name); - checkCollisionWithRequireExportsInGeneratedCode(node, node.name); - checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); + if (isIdentifier(node.name)) { + checkCollisionWithCapturedThisVariable(node, node.name); + checkCollisionWithRequireExportsInGeneratedCode(node, node.name); + checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); + } + checkExportsOnMergedDeclarations(node); const symbol = getSymbolOfNode(node); @@ -19040,7 +19043,7 @@ namespace ts { return undefined; } - function isLiteralConstDeclaration(node: VariableDeclaration): boolean { + function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean { if (isConst(node)) { const type = getTypeOfSymbol(getSymbolOfNode(node)); return !!(type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral); @@ -19048,7 +19051,7 @@ namespace ts { return false; } - function writeLiteralConstValue(node: VariableDeclaration, writer: SymbolWriter) { + function writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter) { const type = getTypeOfSymbol(getSymbolOfNode(node)); writer.writeStringLiteral(literalTypeToString(type)); } @@ -19785,7 +19788,7 @@ namespace ts { checkGrammarForAtLeastOneTypeArgument(node, typeArguments); } - function checkGrammarForOmittedArgument(node: CallExpression, args: NodeArray): boolean { + function checkGrammarForOmittedArgument(node: CallExpression | NewExpression, args: NodeArray): boolean { if (args) { const sourceFile = getSourceFileOfNode(node); for (const arg of args) { @@ -19796,7 +19799,7 @@ namespace ts { } } - function checkGrammarArguments(node: CallExpression, args: NodeArray): boolean { + function checkGrammarArguments(node: CallExpression | NewExpression, args: NodeArray): boolean { return checkGrammarForOmittedArgument(node, args); } @@ -19918,8 +19921,7 @@ namespace ts { for (const prop of node.properties) { const name = prop.name; - if (prop.kind === SyntaxKind.OmittedExpression || - name.kind === SyntaxKind.ComputedPropertyName) { + if (name.kind === SyntaxKind.ComputedPropertyName) { // If the name is not a ComputedPropertyName, the grammar checking will skip it checkGrammarComputedPropertyName(name); } @@ -19966,7 +19968,7 @@ namespace ts { currentKind = SetAccessor; } else { - Debug.fail("Unexpected syntax kind:" + prop.kind); + Debug.fail("Unexpected syntax kind:" + (prop).kind); } const effectiveName = getPropertyNameForPropertyNameNode(name); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 4e1f4553642..3cad89cc652 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1813,9 +1813,9 @@ namespace ts { export interface ObjectAllocator { getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node; - getTokenConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token; - getIdentifierConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Token; - getSourceFileConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => SourceFile; + getTokenConstructor(): new (kind: TKind, pos?: number, end?: number) => Token; + getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier; + getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile; getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol; getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type; getSignatureConstructor(): new (checker: TypeChecker) => Signature; diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 4e19aafa484..8bcce86c31f 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -1121,7 +1121,7 @@ namespace ts { writeLine(); } - function emitVariableDeclaration(node: VariableDeclaration) { + function emitVariableDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration) { // If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted // so there is no check needed to see if declaration is visible if (node.kind !== SyntaxKind.VariableDeclaration || resolver.isDeclarationVisible(node)) { @@ -1136,7 +1136,7 @@ namespace ts { // If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor // we don't want to emit property declaration with "?" if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature || - (node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) { + (node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) { write("?"); } if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) { @@ -1626,8 +1626,7 @@ namespace ts { } } - function emitBindingElement(bindingElement: BindingElement) { - + function emitBindingElement(bindingElement: BindingElement | OmittedExpression) { if (bindingElement.kind === SyntaxKind.OmittedExpression) { // If bindingElement is an omittedExpression (i.e. containing elision), // we will emit blank space (although this may differ from users' original code, diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index b3242e211de..3ea550830cb 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -655,7 +655,7 @@ const _super = (function (geti, seti) { case SyntaxKind.ModuleDeclaration: return emitModuleDeclaration(node); case SyntaxKind.ModuleBlock: - return emitModuleBlock(node); + return emitModuleBlock(node); case SyntaxKind.CaseBlock: return emitCaseBlock(node); case SyntaxKind.ImportEqualsDeclaration: @@ -1394,7 +1394,7 @@ const _super = (function (geti, seti) { } } - function emitBlockStatements(node: Block) { + function emitBlockStatements(node: BlockLike) { if (getEmitFlags(node) & EmitFlags.SingleLine) { emitList(node, node.statements, ListFormat.SingleLineBlockStatements); } @@ -1795,7 +1795,7 @@ const _super = (function (geti, seti) { } function emitModuleBlock(node: ModuleBlock) { - if (isSingleLineEmptyBlock(node)) { + if (isEmptyBlock(node)) { write("{ }"); } else { @@ -2615,7 +2615,11 @@ const _super = (function (geti, seti) { function isSingleLineEmptyBlock(block: Block) { return !block.multiLine - && block.statements.length === 0 + && isEmptyBlock(block); + } + + function isEmptyBlock(block: BlockLike) { + return block.statements.length === 0 && rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile); } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index d873c3ef877..b9a87e05457 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -187,8 +187,8 @@ namespace ts { // Punctuation - export function createToken(token: SyntaxKind) { - return createNode(token); + export function createToken(token: TKind) { + return >createNode(token); } // Reserved words @@ -238,7 +238,7 @@ namespace ts { ); } - export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: Node, name: string | Identifier | BindingPattern, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) { + export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) { const node = createNode(SyntaxKind.Parameter, location, flags); node.decorators = decorators ? createNodeArray(decorators) : undefined; node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; @@ -260,7 +260,7 @@ namespace ts { // Type members - export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange) { + export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange) { const node = createNode(SyntaxKind.PropertyDeclaration, location); node.decorators = decorators ? createNodeArray(decorators) : undefined; node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; @@ -278,7 +278,7 @@ namespace ts { return node; } - export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { + export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { const node = createNode(SyntaxKind.MethodDeclaration, location, flags); node.decorators = decorators ? createNodeArray(decorators) : undefined; node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; @@ -381,7 +381,7 @@ namespace ts { return node; } - export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: Node, name: string | BindingName, initializer?: Expression, location?: TextRange) { + export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: DotDotDotToken, name: string | BindingName, initializer?: Expression, location?: TextRange) { const node = createNode(SyntaxKind.BindingElement, location); node.propertyName = typeof propertyName === "string" ? createIdentifier(propertyName) : propertyName; node.dotDotDotToken = dotDotDotToken; @@ -524,7 +524,7 @@ namespace ts { return node; } - export function createFunctionExpression(asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { + export function createFunctionExpression(asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { const node = createNode(SyntaxKind.FunctionExpression, location, flags); node.modifiers = undefined; node.asteriskToken = asteriskToken; @@ -543,13 +543,13 @@ namespace ts { return node; } - export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: Node, body: ConciseBody, location?: TextRange, flags?: NodeFlags) { + export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody, location?: TextRange, flags?: NodeFlags) { const node = createNode(SyntaxKind.ArrowFunction, location, flags); node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; node.parameters = createNodeArray(parameters); node.type = type; - node.equalsGreaterThanToken = equalsGreaterThanToken || createNode(SyntaxKind.EqualsGreaterThanToken); + node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(SyntaxKind.EqualsGreaterThanToken); node.body = parenthesizeConciseBody(body); return node; } @@ -613,7 +613,7 @@ namespace ts { return node; } - export function createPrefix(operator: SyntaxKind, operand: Expression, location?: TextRange) { + export function createPrefix(operator: PrefixUnaryOperator, operand: Expression, location?: TextRange) { const node = createNode(SyntaxKind.PrefixUnaryExpression, location); node.operator = operator; node.operand = parenthesizePrefixOperand(operand); @@ -627,7 +627,7 @@ namespace ts { return node; } - export function createPostfix(operand: Expression, operator: SyntaxKind, location?: TextRange) { + export function createPostfix(operand: Expression, operator: PostfixUnaryOperator, location?: TextRange) { const node = createNode(SyntaxKind.PostfixUnaryExpression, location); node.operand = parenthesizePostfixOperand(operand); node.operator = operator; @@ -641,8 +641,8 @@ namespace ts { return node; } - export function createBinary(left: Expression, operator: SyntaxKind | Node, right: Expression, location?: TextRange) { - const operatorToken = typeof operator === "number" ? createSynthesizedNode(operator) : operator; + export function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression, location?: TextRange) { + const operatorToken = typeof operator === "number" ? createToken(operator) : operator; const operatorKind = operatorToken.kind; const node = createNode(SyntaxKind.BinaryExpression, location); node.left = parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined); @@ -658,7 +658,7 @@ namespace ts { return node; } - export function createConditional(condition: Expression, questionToken: Node, whenTrue: Expression, colonToken: Node, whenFalse: Expression, location?: TextRange) { + export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression, location?: TextRange) { const node = createNode(SyntaxKind.ConditionalExpression, location); node.condition = condition; node.questionToken = questionToken; @@ -675,21 +675,21 @@ namespace ts { return node; } - export function createTemplateExpression(head: TemplateLiteralFragment, templateSpans: TemplateSpan[], location?: TextRange) { + export function createTemplateExpression(head: TemplateHead, templateSpans: TemplateSpan[], location?: TextRange) { const node = createNode(SyntaxKind.TemplateExpression, location); node.head = head; node.templateSpans = createNodeArray(templateSpans); return node; } - export function updateTemplateExpression(node: TemplateExpression, head: TemplateLiteralFragment, templateSpans: TemplateSpan[]) { + export function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: TemplateSpan[]) { if (node.head !== head || node.templateSpans !== templateSpans) { return updateNode(createTemplateExpression(head, templateSpans, node), node); } return node; } - export function createYield(asteriskToken: Node, expression: Expression, location?: TextRange) { + export function createYield(asteriskToken: AsteriskToken, expression: Expression, location?: TextRange) { const node = createNode(SyntaxKind.YieldExpression, location); node.asteriskToken = asteriskToken; node.expression = expression; @@ -756,14 +756,14 @@ namespace ts { // Misc - export function createTemplateSpan(expression: Expression, literal: TemplateLiteralFragment, location?: TextRange) { + export function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail, location?: TextRange) { const node = createNode(SyntaxKind.TemplateSpan, location); node.expression = expression; node.literal = literal; return node; } - export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateLiteralFragment) { + export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) { if (node.expression !== expression || node.literal !== literal) { return updateNode(createTemplateSpan(expression, literal, node), node); } @@ -932,14 +932,14 @@ namespace ts { return node; } - export function updateForOf(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { + export function updateForOf(node: ForOfStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) { return updateNode(createForOf(initializer, expression, statement, node), node); } return node; } - export function createContinue(label?: Identifier, location?: TextRange): BreakStatement { + export function createContinue(label?: Identifier, location?: TextRange): ContinueStatement { const node = createNode(SyntaxKind.ContinueStatement, location); if (label) { node.label = label; @@ -1065,7 +1065,7 @@ namespace ts { return node; } - export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { + export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { const node = createNode(SyntaxKind.FunctionDeclaration, location, flags); node.decorators = decorators ? createNodeArray(decorators) : undefined; node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; @@ -1560,7 +1560,7 @@ namespace ts { return createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createSynthesizedNode(SyntaxKind.DotDotDotToken), + createToken(SyntaxKind.DotDotDotToken), name, /*questionToken*/ undefined, /*type*/ undefined, @@ -1735,7 +1735,7 @@ namespace ts { export function createAwaiterHelper(externalHelpersModuleName: Identifier | undefined, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) { const generatorFunc = createFunctionExpression( - createNode(SyntaxKind.AsteriskToken), + createToken(SyntaxKind.AsteriskToken), /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ [], diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9bd9311b749..1d52ec9f648 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -637,7 +637,7 @@ namespace ts { sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement); Debug.assert(token() === SyntaxKind.EndOfFileToken); - sourceFile.endOfFileToken = parseTokenNode(); + sourceFile.endOfFileToken = parseTokenNode(); setExternalModuleIndicator(sourceFile); @@ -1004,6 +1004,7 @@ namespace ts { return false; } + function parseOptionalToken(t: TKind): Token; function parseOptionalToken(t: SyntaxKind): Node { if (token() === t) { return parseTokenNode(); @@ -1011,6 +1012,7 @@ namespace ts { return undefined; } + function parseExpectedToken(t: TKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Token; function parseExpectedToken(t: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node { return parseOptionalToken(t) || createMissingNode(t, reportAtCurrentPosition, diagnosticMessage, arg0); @@ -1047,7 +1049,7 @@ namespace ts { } // note: this function creates only node - function createNode(kind: SyntaxKind, pos?: number): Node | Token | Identifier { + function createNode(kind: TKind, pos?: number): Node | Token | Identifier { nodeCount++; if (!(pos >= 0)) { pos = scanner.getStartPos(); @@ -1920,7 +1922,7 @@ namespace ts { function parseTemplateExpression(): TemplateExpression { const template = createNode(SyntaxKind.TemplateExpression); - template.head = parseTemplateLiteralFragment(); + template.head = parseTemplateHead(); Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind"); const templateSpans = createNodeArray(); @@ -1940,14 +1942,13 @@ namespace ts { const span = createNode(SyntaxKind.TemplateSpan); span.expression = allowInAnd(parseExpression); - let literal: TemplateLiteralFragment; - + let literal: TemplateMiddle | TemplateTail; if (token() === SyntaxKind.CloseBraceToken) { reScanTemplateToken(); - literal = parseTemplateLiteralFragment(); + literal = parseTemplateMiddleOrTemplateTail(); } else { - literal = parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)); + literal = parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)); } span.literal = literal; @@ -1958,8 +1959,16 @@ namespace ts { return parseLiteralLikeNode(token(), internName); } - function parseTemplateLiteralFragment(): TemplateLiteralFragment { - return parseLiteralLikeNode(token(), /*internName*/ false); + function parseTemplateHead(): TemplateHead { + const fragment = parseLiteralLikeNode(token(), /*internName*/ false); + Debug.assert(fragment.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind"); + return fragment; + } + + function parseTemplateMiddleOrTemplateTail(): TemplateMiddle | TemplateTail { + const fragment = parseLiteralLikeNode(token(), /*internName*/ false); + Debug.assert(fragment.kind === SyntaxKind.TemplateMiddle || fragment.kind === SyntaxKind.TemplateTail, "Template fragment has wrong token kind"); + return fragment; } function parseLiteralLikeNode(kind: SyntaxKind, internName: boolean): LiteralLikeNode { @@ -2719,7 +2728,7 @@ namespace ts { } let expr = parseAssignmentExpressionOrHigher(); - let operatorToken: Node; + let operatorToken: BinaryOperatorToken; while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) { expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher()); } @@ -2812,7 +2821,7 @@ namespace ts { // Note: we call reScanGreaterToken so that we get an appropriately merged token // for cases like > > = becoming >>= if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) { - return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher()); + return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher()); } // It wasn't an assignment or a lambda. This is a conditional expression: @@ -3247,7 +3256,7 @@ namespace ts { } } else { - leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence)); + leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence)); } } @@ -3307,7 +3316,7 @@ namespace ts { return -1; } - function makeBinaryExpression(left: Expression, operatorToken: Node, right: Expression): BinaryExpression { + function makeBinaryExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression): BinaryExpression { const node = createNode(SyntaxKind.BinaryExpression, left.pos); node.left = left; node.operatorToken = operatorToken; @@ -3324,7 +3333,7 @@ namespace ts { function parsePrefixUnaryExpression() { const node = createNode(SyntaxKind.PrefixUnaryExpression); - node.operator = token(); + node.operator = token(); nextToken(); node.operand = parseSimpleUnaryExpression(); @@ -3511,7 +3520,7 @@ namespace ts { function parseIncrementExpression(): IncrementExpression { if (token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) { const node = createNode(SyntaxKind.PrefixUnaryExpression); - node.operator = token(); + node.operator = token(); nextToken(); node.operand = parseLeftHandSideExpressionOrHigher(); return finishNode(node); @@ -3527,7 +3536,7 @@ namespace ts { if ((token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) { const node = createNode(SyntaxKind.PostfixUnaryExpression, expression.pos); node.operand = expression; - node.operator = token(); + node.operator = token(); nextToken(); return finishNode(node); } @@ -3700,7 +3709,7 @@ namespace ts { badNode.end = invalidElement.end; badNode.left = result; badNode.right = invalidElement; - badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined); + badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined); badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos; return badNode; } @@ -3836,7 +3845,7 @@ namespace ts { if (token() === SyntaxKind.EqualsToken) { switch (scanJsxAttributeValue()) { case SyntaxKind.StringLiteral: - node.initializer = parseLiteralNode(); + node.initializer = parseLiteralNode(); break; default: node.initializer = parseJsxExpression(/*inExpressionContext*/ true); @@ -4959,7 +4968,7 @@ namespace ts { return addJSDocComment(finishNode(node)); } - function parseMethodDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, asteriskToken: Node, name: PropertyName, questionToken: Node, diagnosticMessage?: DiagnosticMessage): MethodDeclaration { + function parseMethodDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, asteriskToken: AsteriskToken, name: PropertyName, questionToken: QuestionToken, diagnosticMessage?: DiagnosticMessage): MethodDeclaration { const method = createNode(SyntaxKind.MethodDeclaration, fullStart); method.decorators = decorators; method.modifiers = modifiers; @@ -4973,7 +4982,7 @@ namespace ts { return addJSDocComment(finishNode(method)); } - function parsePropertyDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, name: PropertyName, questionToken: Node): ClassElement { + function parsePropertyDeclaration(fullStart: number, decorators: NodeArray, modifiers: NodeArray, name: PropertyName, questionToken: QuestionToken): ClassElement { const property = createNode(SyntaxKind.PropertyDeclaration, fullStart); property.decorators = decorators; property.modifiers = modifiers; @@ -5395,7 +5404,7 @@ namespace ts { node.flags |= flags; node.name = parseIdentifier(); node.body = parseOptional(SyntaxKind.DotToken) - ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag) + ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag) : parseModuleBlock(); return addJSDocComment(finishNode(node)); } @@ -5574,8 +5583,10 @@ namespace ts { return finishNode(namespaceImport); } + function parseNamedImportsOrExports(kind: SyntaxKind.NamedImports): NamedImports; + function parseNamedImportsOrExports(kind: SyntaxKind.NamedExports): NamedExports; function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports { - const node = createNode(kind); + const node = createNode(kind); // NamedImports: // { } @@ -5585,7 +5596,7 @@ namespace ts { // ImportsList: // ImportSpecifier // ImportsList, ImportSpecifier - node.elements = parseBracketedList(ParsingContext.ImportOrExportSpecifiers, + node.elements = | NodeArray>parseBracketedList(ParsingContext.ImportOrExportSpecifiers, kind === SyntaxKind.NamedImports ? parseImportSpecifier : parseExportSpecifier, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken); return finishNode(node); @@ -5969,14 +5980,15 @@ namespace ts { const parameter = createNode(SyntaxKind.Parameter); parameter.type = parseJSDocType(); if (parseOptional(SyntaxKind.EqualsToken)) { - parameter.questionToken = createNode(SyntaxKind.EqualsToken); + // TODO(rbuckton): Can this be changed to SyntaxKind.QuestionToken? + parameter.questionToken = createNode(SyntaxKind.EqualsToken); } return finishNode(parameter); } function parseJSDocTypeReference(): JSDocTypeReference { const result = createNode(SyntaxKind.JSDocTypeReference); - result.name = parseSimplePropertyName(); + result.name = parseSimplePropertyName(); if (token() === SyntaxKind.LessThanToken) { result.typeArguments = parseTypeArguments(); @@ -6304,7 +6316,7 @@ namespace ts { function parseTag(indent: number) { Debug.assert(token() === SyntaxKind.AtToken); - const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos()); + const atToken = createNode(SyntaxKind.AtToken, scanner.getTokenPos()); atToken.end = scanner.getTextPos(); nextJSDocToken(); @@ -6410,7 +6422,7 @@ namespace ts { return comments; } - function parseUnknownTag(atToken: Node, tagName: Identifier) { + function parseUnknownTag(atToken: AtToken, tagName: Identifier) { const result = createNode(SyntaxKind.JSDocTag, atToken.pos); result.atToken = atToken; result.tagName = tagName; @@ -6440,7 +6452,7 @@ namespace ts { }); } - function parseParamTag(atToken: Node, tagName: Identifier) { + function parseParamTag(atToken: AtToken, tagName: Identifier) { let typeExpression = tryParseTypeExpression(); skipWhitespace(); @@ -6491,7 +6503,7 @@ namespace ts { return finishNode(result); } - function parseReturnTag(atToken: Node, tagName: Identifier): JSDocReturnTag { + function parseReturnTag(atToken: AtToken, tagName: Identifier): JSDocReturnTag { if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text); } @@ -6503,7 +6515,7 @@ namespace ts { return finishNode(result); } - function parseTypeTag(atToken: Node, tagName: Identifier): JSDocTypeTag { + function parseTypeTag(atToken: AtToken, tagName: Identifier): JSDocTypeTag { if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text); } @@ -6515,7 +6527,7 @@ namespace ts { return finishNode(result); } - function parsePropertyTag(atToken: Node, tagName: Identifier): JSDocPropertyTag { + function parsePropertyTag(atToken: AtToken, tagName: Identifier): JSDocPropertyTag { const typeExpression = tryParseTypeExpression(); skipWhitespace(); const name = parseJSDocIdentifierName(); @@ -6533,7 +6545,7 @@ namespace ts { return finishNode(result); } - function parseTypedefTag(atToken: Node, tagName: Identifier): JSDocTypedefTag { + function parseTypedefTag(atToken: AtToken, tagName: Identifier): JSDocTypedefTag { const typeExpression = tryParseTypeExpression(); skipWhitespace(); @@ -6555,7 +6567,7 @@ namespace ts { } } if (!typedefTag.jsDocTypeLiteral) { - typedefTag.jsDocTypeLiteral = typeExpression.type; + typedefTag.jsDocTypeLiteral = typeExpression.type; } } else { @@ -6607,7 +6619,7 @@ namespace ts { function tryParseChildTag(parentTag: JSDocTypeLiteral): boolean { Debug.assert(token() === SyntaxKind.AtToken); - const atToken = createNode(SyntaxKind.AtToken, scanner.getStartPos()); + const atToken = createNode(SyntaxKind.AtToken, scanner.getStartPos()); atToken.end = scanner.getTextPos(); nextJSDocToken(); @@ -6637,7 +6649,7 @@ namespace ts { return false; } - function parseTemplateTag(atToken: Node, tagName: Identifier): JSDocTemplateTag { + function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag { if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text); } diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 3bfa778cf9b..c7219866df7 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -220,7 +220,7 @@ namespace ts { function flattenDestructuring( context: TransformationContext, - root: BindingElement | BinaryExpression, + root: VariableDeclaration | ParameterDeclaration | BindingElement | BinaryExpression, value: Expression, location: TextRange, emitAssignment: (name: Identifier, value: Expression, location: TextRange, original: Node) => void, @@ -320,7 +320,7 @@ namespace ts { } } - function emitBindingElement(target: BindingElement, value: Expression) { + function emitBindingElement(target: VariableDeclaration | ParameterDeclaration | BindingElement, value: Expression) { // Any temporary assignments needed to emit target = value should point to target const initializer = visitor ? visitNode(target.initializer, visitor, isExpression) : target.initializer; if (initializer) { diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index e3ee1dd4c3a..d8bf9ffa0f9 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -3199,7 +3199,7 @@ namespace ts { * @param node The declaration. * @param allowComments Allow comments for the name. */ - function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) { + function getDeclarationName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) { if (node.name && !isGeneratedIdentifier(node.name)) { const name = getMutableClone(node.name); emitFlags |= getEmitFlags(node.name); diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 6fe3187bee1..6d20f4b1e30 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -528,7 +528,7 @@ namespace ts { * * @param node The node to visit. */ - function visitAccessorDeclaration(node: GetAccessorDeclaration) { + function visitAccessorDeclaration(node: AccessorDeclaration) { const savedInGeneratorFunctionBody = inGeneratorFunctionBody; const savedInStatementContainingYield = inStatementContainingYield; inGeneratorFunctionBody = false; diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index c4e9b4c31c8..516ed5433b8 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -599,7 +599,7 @@ namespace ts { } else { statements.push( - createExportStatement(node.name, setEmitFlags(getSynthesizedClone(node.name), EmitFlags.LocalName), /*location*/ node) + createExportStatement(node.name, setEmitFlags(getSynthesizedClone(node.name), EmitFlags.LocalName), /*location*/ node) ); } } @@ -796,7 +796,7 @@ namespace ts { addVarForExportedEnumOrNamespaceDeclaration(statements, original); } - addExportMemberAssignments(statements, original.name); + addExportMemberAssignments(statements, original.name); return statements; } @@ -819,7 +819,7 @@ namespace ts { } function getDeclarationName(node: DeclarationStatement) { - return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node); + return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node); } function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void { @@ -916,7 +916,7 @@ namespace ts { if (node.kind === SyntaxKind.PostfixUnaryExpression) { transformedUnaryExpression = createBinary( operand, - createNode(operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken), + createToken(operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken), createLiteral(1), /*location*/ node ); diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 4a137c89a93..303c0e1bb96 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -1201,7 +1201,7 @@ namespace ts { * @param node The declaration statement. */ function getDeclarationName(node: DeclarationStatement) { - return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node); + return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node); } function addExportStarFunction(statements: Statement[], localNames: Identifier) { diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index f6e8074cb07..2b757619365 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -3069,7 +3069,7 @@ namespace ts { return createStatement(expression, /*location*/ undefined); } - function addExportMemberAssignment(statements: Statement[], node: DeclarationStatement) { + function addExportMemberAssignment(statements: Statement[], node: ClassDeclaration | FunctionDeclaration) { const expression = createAssignment( getExportName(node), getLocalName(node, /*noSourceMaps*/ true) @@ -3147,7 +3147,7 @@ namespace ts { * @param noSourceMaps A value indicating whether source maps may not be emitted for the name. * @param allowComments A value indicating whether comments may be emitted for the name. */ - function getLocalName(node: DeclarationStatement | ClassExpression, noSourceMaps?: boolean, allowComments?: boolean) { + function getLocalName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, noSourceMaps?: boolean, allowComments?: boolean) { return getDeclarationName(node, allowComments, !noSourceMaps, EmitFlags.LocalName); } @@ -3161,7 +3161,7 @@ namespace ts { * @param noSourceMaps A value indicating whether source maps may not be emitted for the name. * @param allowComments A value indicating whether comments may be emitted for the name. */ - function getExportName(node: DeclarationStatement | ClassExpression, noSourceMaps?: boolean, allowComments?: boolean) { + function getExportName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, noSourceMaps?: boolean, allowComments?: boolean) { if (isNamespaceExport(node)) { return getNamespaceMemberName(getDeclarationName(node), allowComments, !noSourceMaps); } @@ -3177,9 +3177,9 @@ namespace ts { * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. * @param emitFlags Additional NodeEmitFlags to specify for the name. */ - function getDeclarationName(node: DeclarationStatement | ClassExpression, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) { + function getDeclarationName(node: FunctionDeclaration | ClassDeclaration | ClassExpression | ModuleDeclaration | EnumDeclaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) { if (node.name) { - const name = getMutableClone(node.name); + const name = getMutableClone(node.name); emitFlags |= getEmitFlags(node.name); if (!allowSourceMaps) { emitFlags |= EmitFlags.NoSourceMap; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f6d79176992..7cc8dcd81d2 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -436,8 +436,6 @@ namespace ts { TypeExcludesFlags = YieldContext | AwaitContext, } - export type ModifiersArray = NodeArray; - export const enum ModifierFlags { None = 0, Export = 1 << 0, // Declarations @@ -501,21 +499,33 @@ namespace ts { hasTrailingComma?: boolean; } - export interface Token extends Node { - __tokenTag: any; + export interface Token extends Node { + kind: TKind; } - // @kind(SyntaxKind.AbstractKeyword) - // @kind(SyntaxKind.AsyncKeyword) - // @kind(SyntaxKind.ConstKeyword) - // @kind(SyntaxKind.DeclareKeyword) - // @kind(SyntaxKind.DefaultKeyword) - // @kind(SyntaxKind.ExportKeyword) - // @kind(SyntaxKind.PublicKeyword) - // @kind(SyntaxKind.PrivateKeyword) - // @kind(SyntaxKind.ProtectedKeyword) - // @kind(SyntaxKind.StaticKeyword) - export interface Modifier extends Token { } + export type DotDotDotToken = Token; + export type QuestionToken = Token; + export type ColonToken = Token; + export type EqualsToken = Token; + export type AsteriskToken = Token; + export type EqualsGreaterThanToken = Token; + export type EndOfFileToken = Token; + export type AtToken = Token; + + export type Modifier + = Token + | Token + | Token + | Token + | Token + | Token + | Token + | Token + | Token + | Token + | Token; + + export type ModifiersArray = NodeArray; /*@internal*/ export const enum GeneratedIdentifierKind { @@ -526,8 +536,8 @@ namespace ts { Node, // Unique name based on the node in the 'original' property. } - // @kind(SyntaxKind.Identifier) export interface Identifier extends PrimaryExpression { + kind: SyntaxKind.Identifier; text: string; // Text of identifier (with escapes converted to characters) originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later /*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier. @@ -539,9 +549,8 @@ namespace ts { resolvedSymbol: Symbol; } - // @kind(SyntaxKind.QualifiedName) export interface QualifiedName extends Node { - // Must have same layout as PropertyAccess + kind: SyntaxKind.QualifiedName; left: EntityName; right: Identifier; } @@ -558,21 +567,21 @@ namespace ts { } export interface DeclarationStatement extends Declaration, Statement { - name?: Identifier; + name?: Identifier | LiteralExpression; } - // @kind(SyntaxKind.ComputedPropertyName) export interface ComputedPropertyName extends Node { + kind: SyntaxKind.ComputedPropertyName; expression: Expression; } - // @kind(SyntaxKind.Decorator) export interface Decorator extends Node { + kind: SyntaxKind.Decorator; expression: LeftHandSideExpression; } - // @kind(SyntaxKind.TypeParameter) export interface TypeParameterDeclaration extends Declaration { + kind: SyntaxKind.TypeParameter; name: Identifier; constraint?: TypeNode; @@ -587,55 +596,57 @@ namespace ts { type?: TypeNode; } - // @kind(SyntaxKind.CallSignature) - export interface CallSignatureDeclaration extends SignatureDeclaration, TypeElement { } + export interface CallSignatureDeclaration extends SignatureDeclaration, TypeElement { + kind: SyntaxKind.CallSignature; + } - // @kind(SyntaxKind.ConstructSignature) - export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement { } + export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement { + kind: SyntaxKind.ConstructSignature; + } export type BindingName = Identifier | BindingPattern; - // @kind(SyntaxKind.VariableDeclaration) export interface VariableDeclaration extends Declaration { + kind: SyntaxKind.VariableDeclaration; parent?: VariableDeclarationList; name: BindingName; // Declared variable name type?: TypeNode; // Optional type annotation initializer?: Expression; // Optional initializer } - // @kind(SyntaxKind.VariableDeclarationList) export interface VariableDeclarationList extends Node { + kind: SyntaxKind.VariableDeclarationList; declarations: NodeArray; } - // @kind(SyntaxKind.Parameter) export interface ParameterDeclaration extends Declaration { - dotDotDotToken?: Node; // Present on rest parameter + kind: SyntaxKind.Parameter; + dotDotDotToken?: DotDotDotToken; // Present on rest parameter name: BindingName; // Declared parameter name - questionToken?: Node; // Present on optional parameter + questionToken?: QuestionToken; // Present on optional parameter type?: TypeNode; // Optional type annotation initializer?: Expression; // Optional initializer } - // @kind(SyntaxKind.BindingElement) export interface BindingElement extends Declaration { + kind: SyntaxKind.BindingElement; propertyName?: PropertyName; // Binding property name (in object binding pattern) - dotDotDotToken?: Node; // Present on rest binding element + dotDotDotToken?: DotDotDotToken; // Present on rest binding element name: BindingName; // Declared binding element name initializer?: Expression; // Optional initializer } - // @kind(SyntaxKind.PropertySignature) export interface PropertySignature extends TypeElement { + kind: SyntaxKind.PropertySignature | SyntaxKind.JSDocRecordMember; name: PropertyName; // Declared property name - questionToken?: Node; // Present on optional property + questionToken?: QuestionToken; // Present on optional property type?: TypeNode; // Optional type annotation initializer?: Expression; // Optional initializer } - // @kind(SyntaxKind.PropertyDeclaration) export interface PropertyDeclaration extends ClassElement { - questionToken?: Node; // Present for use with reporting a grammar error + kind: SyntaxKind.PropertyDeclaration; + questionToken?: QuestionToken; // Present for use with reporting a grammar error name: PropertyName; type?: TypeNode; initializer?: Expression; // Optional initializer @@ -644,25 +655,24 @@ namespace ts { export interface ObjectLiteralElement extends Declaration { _objectLiteralBrandBrand: any; name?: PropertyName; - } + } export type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | MethodDeclaration | AccessorDeclaration; - // @kind(SyntaxKind.PropertyAssignment) export interface PropertyAssignment extends ObjectLiteralElement { - _propertyAssignmentBrand: any; + kind: SyntaxKind.PropertyAssignment; name: PropertyName; - questionToken?: Node; + questionToken?: QuestionToken; initializer: Expression; } - // @kind(SyntaxKind.ShorthandPropertyAssignment) export interface ShorthandPropertyAssignment extends ObjectLiteralElement { + kind: SyntaxKind.ShorthandPropertyAssignment; name: Identifier; - questionToken?: Node; + questionToken?: QuestionToken; // used when ObjectLiteralExpression is used in ObjectAssignmentPattern // it is grammar error to appear in actual object initializer - equalsToken?: Node; + equalsToken?: Token; objectAssignmentInitializer?: Expression; } @@ -676,9 +686,9 @@ namespace ts { // SyntaxKind.JSDocPropertyTag export interface VariableLikeDeclaration extends Declaration { propertyName?: PropertyName; - dotDotDotToken?: Node; + dotDotDotToken?: DotDotDotToken; name: DeclarationName; - questionToken?: Node; + questionToken?: QuestionToken; type?: TypeNode; initializer?: Expression; } @@ -691,15 +701,15 @@ namespace ts { elements: NodeArray; } - // @kind(SyntaxKind.ObjectBindingPattern) export interface ObjectBindingPattern extends BindingPattern { + kind: SyntaxKind.ObjectBindingPattern; elements: NodeArray; } export type ArrayBindingElement = BindingElement | OmittedExpression; - // @kind(SyntaxKind.ArrayBindingPattern) export interface ArrayBindingPattern extends BindingPattern { + kind: SyntaxKind.ArrayBindingPattern; elements: NodeArray; } @@ -714,19 +724,19 @@ namespace ts { export interface FunctionLikeDeclaration extends SignatureDeclaration { _functionLikeDeclarationBrand: any; - asteriskToken?: Node; - questionToken?: Node; + asteriskToken?: AsteriskToken; + questionToken?: QuestionToken; body?: Block | Expression; } - // @kind(SyntaxKind.FunctionDeclaration) export interface FunctionDeclaration extends FunctionLikeDeclaration, DeclarationStatement { + kind: SyntaxKind.FunctionDeclaration; name?: Identifier; body?: FunctionBody; } - // @kind(SyntaxKind.MethodSignature) export interface MethodSignature extends SignatureDeclaration, TypeElement { + kind: SyntaxKind.MethodSignature; name: PropertyName; } @@ -739,126 +749,132 @@ namespace ts { // Because of this, it may be necessary to determine what sort of MethodDeclaration you have // at later stages of the compiler pipeline. In that case, you can either check the parent kind // of the method, or use helpers like isObjectLiteralMethodDeclaration - // @kind(SyntaxKind.MethodDeclaration) export interface MethodDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement { + kind: SyntaxKind.MethodDeclaration; name: PropertyName; body?: FunctionBody; } - // @kind(SyntaxKind.Constructor) export interface ConstructorDeclaration extends FunctionLikeDeclaration, ClassElement { + kind: SyntaxKind.Constructor; body?: FunctionBody; } // For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. - // @kind(SyntaxKind.SemicolonClassElement) export interface SemicolonClassElement extends ClassElement { - _semicolonClassElementBrand: any; + kind: SyntaxKind.SemicolonClassElement; } - // See the comment on MethodDeclaration for the intuition behind AccessorDeclaration being a + // See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a // ClassElement and an ObjectLiteralElement. - export interface AccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement { - _accessorDeclarationBrand: any; + export interface GetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement { + kind: SyntaxKind.GetAccessor; name: PropertyName; body: FunctionBody; } - // @kind(SyntaxKind.GetAccessor) - export interface GetAccessorDeclaration extends AccessorDeclaration { } - - // @kind(SyntaxKind.SetAccessor) - export interface SetAccessorDeclaration extends AccessorDeclaration { } - - // @kind(SyntaxKind.IndexSignature) - export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement { - _indexSignatureDeclarationBrand: any; + // See the comment on MethodDeclaration for the intuition behind SetAccessorDeclaration being a + // ClassElement and an ObjectLiteralElement. + export interface SetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement { + kind: SyntaxKind.SetAccessor; + name: PropertyName; + body: FunctionBody; + } + + export type AccessorDeclaration = GetAccessorDeclaration | SetAccessorDeclaration; + + export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement { + kind: SyntaxKind.IndexSignature; } - // @kind(SyntaxKind.AnyKeyword) - // @kind(SyntaxKind.NumberKeyword) - // @kind(SyntaxKind.BooleanKeyword) - // @kind(SyntaxKind.StringKeyword) - // @kind(SyntaxKind.SymbolKeyword) - // @kind(SyntaxKind.VoidKeyword) export interface TypeNode extends Node { _typeNodeBrand: any; } - // @kind(SyntaxKind.ThisType) + export interface KeywordTypeNode extends TypeNode { + kind: SyntaxKind.AnyKeyword + | SyntaxKind.NumberKeyword + | SyntaxKind.BooleanKeyword + | SyntaxKind.StringKeyword + | SyntaxKind.SymbolKeyword + | SyntaxKind.VoidKeyword; + } + export interface ThisTypeNode extends TypeNode { - _thisTypeNodeBrand: any; + kind: SyntaxKind.ThisType; } export interface FunctionOrConstructorTypeNode extends TypeNode, SignatureDeclaration { - _functionOrConstructorTypeNodeBrand: any; + kind: SyntaxKind.FunctionType | SyntaxKind.ConstructorType; } - // @kind(SyntaxKind.FunctionType) - export interface FunctionTypeNode extends FunctionOrConstructorTypeNode { } + export interface FunctionTypeNode extends FunctionOrConstructorTypeNode { + kind: SyntaxKind.FunctionType; + } - // @kind(SyntaxKind.ConstructorType) - export interface ConstructorTypeNode extends FunctionOrConstructorTypeNode { } + export interface ConstructorTypeNode extends FunctionOrConstructorTypeNode { + kind: SyntaxKind.ConstructorType; + } - // @kind(SyntaxKind.TypeReference) export interface TypeReferenceNode extends TypeNode { + kind: SyntaxKind.TypeReference; typeName: EntityName; typeArguments?: NodeArray; } - // @kind(SyntaxKind.TypePredicate) export interface TypePredicateNode extends TypeNode { + kind: SyntaxKind.TypePredicate; parameterName: Identifier | ThisTypeNode; type: TypeNode; } - // @kind(SyntaxKind.TypeQuery) export interface TypeQueryNode extends TypeNode { + kind: SyntaxKind.TypeQuery; exprName: EntityName; } // A TypeLiteral is the declaration node for an anonymous symbol. - // @kind(SyntaxKind.TypeLiteral) export interface TypeLiteralNode extends TypeNode, Declaration { + kind: SyntaxKind.TypeLiteral; members: NodeArray; } - // @kind(SyntaxKind.ArrayType) export interface ArrayTypeNode extends TypeNode { + kind: SyntaxKind.ArrayType; elementType: TypeNode; } - // @kind(SyntaxKind.TupleType) export interface TupleTypeNode extends TypeNode { + kind: SyntaxKind.TupleType; elementTypes: NodeArray; } export interface UnionOrIntersectionTypeNode extends TypeNode { + kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType; types: NodeArray; } - // @kind(SyntaxKind.UnionType) - export interface UnionTypeNode extends UnionOrIntersectionTypeNode { } + export interface UnionTypeNode extends UnionOrIntersectionTypeNode { + kind: SyntaxKind.UnionType; + } - // @kind(SyntaxKind.IntersectionType) - export interface IntersectionTypeNode extends UnionOrIntersectionTypeNode { } + export interface IntersectionTypeNode extends UnionOrIntersectionTypeNode { + kind: SyntaxKind.IntersectionType; + } - // @kind(SyntaxKind.ParenthesizedType) export interface ParenthesizedTypeNode extends TypeNode { + kind: SyntaxKind.ParenthesizedType; type: TypeNode; } - // @kind(SyntaxKind.StringLiteralType) export interface LiteralTypeNode extends TypeNode { - _stringLiteralTypeBrand: any; + kind: SyntaxKind.LiteralType; literal: Expression; } - // @kind(SyntaxKind.StringLiteral) export interface StringLiteral extends LiteralExpression { - _stringLiteralBrand: any; - /* @internal */ - textSourceNode?: Identifier | StringLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). + kind: SyntaxKind.StringLiteral; + /* @internal */ textSourceNode?: Identifier | StringLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). } // Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing. @@ -873,16 +889,15 @@ namespace ts { contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution } - // @kind(SyntaxKind.OmittedExpression) export interface OmittedExpression extends Expression { - _omittedExpressionBrand: any; + kind: SyntaxKind.OmittedExpression; } // Represents an expression that is elided as part of a transformation to emit comments on a // not-emitted node. The 'expression' property of a NotEmittedExpression should be emitted. // @internal - // @kind(SyntaxKind.NotEmittedExpression) export interface PartiallyEmittedExpression extends LeftHandSideExpression { + kind: SyntaxKind.PartiallyEmittedExpression; expression: Expression; } @@ -894,16 +909,28 @@ namespace ts { _incrementExpressionBrand: any; } - // @kind(SyntaxKind.PrefixUnaryExpression) + export type PrefixUnaryOperator + = SyntaxKind.PlusPlusToken + | SyntaxKind.MinusMinusToken + | SyntaxKind.PlusToken + | SyntaxKind.MinusToken + | SyntaxKind.TildeToken + | SyntaxKind.ExclamationToken; + export interface PrefixUnaryExpression extends IncrementExpression { - operator: SyntaxKind; + kind: SyntaxKind.PrefixUnaryExpression; + operator: PrefixUnaryOperator; operand: UnaryExpression; } - // @kind(SyntaxKind.PostfixUnaryExpression) + export type PostfixUnaryOperator + = SyntaxKind.PlusPlusToken + | SyntaxKind.MinusMinusToken; + export interface PostfixUnaryExpression extends IncrementExpression { + kind: SyntaxKind.PostfixUnaryExpression; operand: LeftHandSideExpression; - operator: SyntaxKind; + operator: PostfixUnaryOperator; } export interface PostfixExpression extends UnaryExpression { @@ -918,70 +945,114 @@ namespace ts { _memberExpressionBrand: any; } - // @kind(SyntaxKind.TrueKeyword) - // @kind(SyntaxKind.FalseKeyword) - // @kind(SyntaxKind.NullKeyword) - // @kind(SyntaxKind.ThisKeyword) - // @kind(SyntaxKind.SuperKeyword) export interface PrimaryExpression extends MemberExpression { _primaryExpressionBrand: any; } - // @kind(SyntaxKind.DeleteExpression) + export interface KeywordExpression extends PrimaryExpression { + kind: SyntaxKind.TrueKeyword + | SyntaxKind.FalseKeyword + | SyntaxKind.NullKeyword + | SyntaxKind.ThisKeyword + | SyntaxKind.SuperKeyword; + } + export interface DeleteExpression extends UnaryExpression { + kind: SyntaxKind.DeleteExpression; expression: UnaryExpression; } - // @kind(SyntaxKind.TypeOfExpression) export interface TypeOfExpression extends UnaryExpression { + kind: SyntaxKind.TypeOfExpression; expression: UnaryExpression; } - // @kind(SyntaxKind.VoidExpression) export interface VoidExpression extends UnaryExpression { + kind: SyntaxKind.VoidExpression; expression: UnaryExpression; } - // @kind(SyntaxKind.AwaitExpression) export interface AwaitExpression extends UnaryExpression { + kind: SyntaxKind.AwaitExpression; expression: UnaryExpression; } - // @kind(SyntaxKind.YieldExpression) export interface YieldExpression extends Expression { - asteriskToken?: Node; + kind: SyntaxKind.YieldExpression; + asteriskToken?: AsteriskToken; expression?: Expression; } - // @kind(SyntaxKind.BinaryExpression) + export type BinaryOperator + = SyntaxKind.PlusToken + | SyntaxKind.PlusEqualsToken + | SyntaxKind.MinusToken + | SyntaxKind.MinusEqualsToken + | SyntaxKind.AsteriskToken + | SyntaxKind.AsteriskAsteriskToken + | SyntaxKind.AsteriskAsteriskEqualsToken + | SyntaxKind.AsteriskEqualsToken + | SyntaxKind.SlashToken + | SyntaxKind.SlashEqualsToken + | SyntaxKind.PercentToken + | SyntaxKind.PercentEqualsToken + | SyntaxKind.AmpersandToken + | SyntaxKind.AmpersandAmpersandToken + | SyntaxKind.AmpersandEqualsToken + | SyntaxKind.BarToken + | SyntaxKind.BarBarToken + | SyntaxKind.BarEqualsToken + | SyntaxKind.CaretToken + | SyntaxKind.CaretEqualsToken + | SyntaxKind.LessThanToken + | SyntaxKind.LessThanLessThanToken + | SyntaxKind.LessThanLessThanEqualsToken + | SyntaxKind.LessThanEqualsToken + | SyntaxKind.GreaterThanToken + | SyntaxKind.GreaterThanGreaterThanToken + | SyntaxKind.GreaterThanGreaterThanGreaterThanToken + | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken + | SyntaxKind.GreaterThanGreaterThanEqualsToken + | SyntaxKind.GreaterThanEqualsToken + | SyntaxKind.EqualsToken + | SyntaxKind.EqualsEqualsToken + | SyntaxKind.EqualsEqualsEqualsToken + | SyntaxKind.ExclamationEqualsEqualsToken + | SyntaxKind.ExclamationEqualsToken + | SyntaxKind.InstanceOfKeyword + | SyntaxKind.CommaToken; + + export type BinaryOperatorToken = Token; + // Binary expressions can be declarations if they are 'exports.foo = bar' expressions in JS files export interface BinaryExpression extends Expression, Declaration { + kind: SyntaxKind.BinaryExpression; left: Expression; - operatorToken: Node; + operatorToken: BinaryOperatorToken; right: Expression; } - // @kind(SyntaxKind.ConditionalExpression) export interface ConditionalExpression extends Expression { + kind: SyntaxKind.ConditionalExpression; condition: Expression; - questionToken: Node; + questionToken: QuestionToken; whenTrue: Expression; - colonToken: Node; + colonToken: ColonToken; whenFalse: Expression; } export type FunctionBody = Block; export type ConciseBody = FunctionBody | Expression; - // @kind(SyntaxKind.FunctionExpression) export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclaration { + kind: SyntaxKind.FunctionExpression; name?: Identifier; body: FunctionBody; // Required, whereas the member inherited from FunctionDeclaration is optional } - // @kind(SyntaxKind.ArrowFunction) export interface ArrowFunction extends Expression, FunctionLikeDeclaration { - equalsGreaterThanToken: Node; + kind: SyntaxKind.ArrowFunction; + equalsGreaterThanToken: EqualsGreaterThanToken; body: ConciseBody; } @@ -996,55 +1067,65 @@ namespace ts { // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral, // or any literal of a template, this means quotes have been removed and escapes have been converted to actual characters. // For a NumericLiteral, the stored value is the toString() representation of the number. For example 1, 1.00, and 1e0 are all stored as just "1". - // @kind(SyntaxKind.RegularExpressionLiteral) - // @kind(SyntaxKind.NoSubstitutionTemplateLiteral) export interface LiteralExpression extends LiteralLikeNode, PrimaryExpression { _literalExpressionBrand: any; } - // @kind(SyntaxKind.NumericLiteral) + export interface RegularExpressionLiteral extends LiteralExpression { + kind: SyntaxKind.RegularExpressionLiteral; + } + + export interface NoSubstitutionTemplateLiteral extends LiteralExpression { + kind: SyntaxKind.NoSubstitutionTemplateLiteral; + } + export interface NumericLiteral extends LiteralExpression { - _numericLiteralBrand: any; + kind: SyntaxKind.NumericLiteral; trailingComment?: string; } - // @kind(SyntaxKind.TemplateHead) - // @kind(SyntaxKind.TemplateMiddle) - // @kind(SyntaxKind.TemplateTail) - export interface TemplateLiteralFragment extends LiteralLikeNode { - _templateLiteralFragmentBrand: any; + export interface TemplateHead extends LiteralLikeNode { + kind: SyntaxKind.TemplateHead; + } + + export interface TemplateMiddle extends LiteralLikeNode { + kind: SyntaxKind.TemplateMiddle; + } + + export interface TemplateTail extends LiteralLikeNode { + kind: SyntaxKind.TemplateTail; } export type Template = TemplateExpression | LiteralExpression; - // @kind(SyntaxKind.TemplateExpression) export interface TemplateExpression extends PrimaryExpression { - head: TemplateLiteralFragment; + kind: SyntaxKind.TemplateExpression; + head: TemplateHead; templateSpans: NodeArray; } // Each of these corresponds to a substitution expression and a template literal, in that order. // The template literal must have kind TemplateMiddleLiteral or TemplateTailLiteral. - // @kind(SyntaxKind.TemplateSpan) export interface TemplateSpan extends Node { + kind: SyntaxKind.TemplateSpan; expression: Expression; - literal: TemplateLiteralFragment; + literal: TemplateMiddle | TemplateTail; } - // @kind(SyntaxKind.ParenthesizedExpression) export interface ParenthesizedExpression extends PrimaryExpression { + kind: SyntaxKind.ParenthesizedExpression; expression: Expression; } - // @kind(SyntaxKind.ArrayLiteralExpression) export interface ArrayLiteralExpression extends PrimaryExpression { + kind: SyntaxKind.ArrayLiteralExpression; elements: NodeArray; /* @internal */ multiLine?: boolean; } - // @kind(SyntaxKind.SpreadElementExpression) export interface SpreadElementExpression extends Expression { + kind: SyntaxKind.SpreadElementExpression; expression: Expression; } @@ -1059,8 +1140,8 @@ namespace ts { } // An ObjectLiteralExpression is the declaration node for an anonymous symbol. - // @kind(SyntaxKind.ObjectLiteralExpression) export interface ObjectLiteralExpression extends ObjectLiteralExpressionBase { + kind: SyntaxKind.ObjectLiteralExpression; /* @internal */ multiLine?: boolean; } @@ -1068,69 +1149,74 @@ namespace ts { export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression; export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression; - // @kind(SyntaxKind.PropertyAccessExpression) export interface PropertyAccessExpression extends MemberExpression, Declaration { + kind: SyntaxKind.PropertyAccessExpression; expression: LeftHandSideExpression; name: Identifier; } + /** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */ export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { _propertyAccessExpressionLikeQualifiedNameBrand?: any; expression: EntityNameExpression; } - // @kind(SyntaxKind.ElementAccessExpression) export interface ElementAccessExpression extends MemberExpression { + kind: SyntaxKind.ElementAccessExpression; expression: LeftHandSideExpression; argumentExpression?: Expression; } - // @kind(SyntaxKind.CallExpression) export interface CallExpression extends LeftHandSideExpression, Declaration { + kind: SyntaxKind.CallExpression; expression: LeftHandSideExpression; typeArguments?: NodeArray; arguments: NodeArray; } - // @kind(SyntaxKind.ExpressionWithTypeArguments) export interface ExpressionWithTypeArguments extends TypeNode { + kind: SyntaxKind.ExpressionWithTypeArguments; expression: LeftHandSideExpression; typeArguments?: NodeArray; } - // @kind(SyntaxKind.NewExpression) - export interface NewExpression extends CallExpression, PrimaryExpression { } + export interface NewExpression extends PrimaryExpression, Declaration { + kind: SyntaxKind.NewExpression; + expression: LeftHandSideExpression; + typeArguments?: NodeArray; + arguments: NodeArray; + } - // @kind(SyntaxKind.TaggedTemplateExpression) export interface TaggedTemplateExpression extends MemberExpression { + kind: SyntaxKind.TaggedTemplateExpression; tag: LeftHandSideExpression; template: Template; } export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator; - // @kind(SyntaxKind.AsExpression) export interface AsExpression extends Expression { + kind: SyntaxKind.AsExpression; expression: Expression; type: TypeNode; } - // @kind(SyntaxKind.TypeAssertionExpression) export interface TypeAssertion extends UnaryExpression { + kind: SyntaxKind.TypeAssertionExpression; type: TypeNode; expression: UnaryExpression; } export type AssertionExpression = TypeAssertion | AsExpression; - // @kind(SyntaxKind.NonNullExpression) export interface NonNullExpression extends LeftHandSideExpression { + kind: SyntaxKind.NonNullExpression; expression: Expression; } /// A JSX expression of the form ... - // @kind(SyntaxKind.JsxElement) export interface JsxElement extends PrimaryExpression { + kind: SyntaxKind.JsxElement; openingElement: JsxOpeningElement; children: NodeArray; closingElement: JsxClosingElement; @@ -1139,17 +1225,17 @@ namespace ts { export type JsxTagNameExpression = PrimaryExpression | PropertyAccessExpression; /// The opening element of a ... JsxElement - // @kind(SyntaxKind.JsxOpeningElement) export interface JsxOpeningElement extends Expression { - _openingElementBrand?: any; + kind: SyntaxKind.JsxOpeningElement; tagName: JsxTagNameExpression; attributes: NodeArray; } /// A JSX expression of the form - // @kind(SyntaxKind.JsxSelfClosingElement) - export interface JsxSelfClosingElement extends PrimaryExpression, JsxOpeningElement { - _selfClosingElementBrand?: any; + export interface JsxSelfClosingElement extends PrimaryExpression { + kind: SyntaxKind.JsxSelfClosingElement; + tagName: JsxTagNameExpression; + attributes: NodeArray; } /// Either the opening tag in a ... pair, or the lone in a self-closing form @@ -1157,31 +1243,30 @@ namespace ts { export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute; - // @kind(SyntaxKind.JsxAttribute) export interface JsxAttribute extends Node { + kind: SyntaxKind.JsxAttribute; name: Identifier; /// JSX attribute initializers are optional; is sugar for initializer?: StringLiteral | JsxExpression; } - // @kind(SyntaxKind.JsxSpreadAttribute) export interface JsxSpreadAttribute extends Node { + kind: SyntaxKind.JsxSpreadAttribute; expression: Expression; } - // @kind(SyntaxKind.JsxClosingElement) export interface JsxClosingElement extends Node { + kind: SyntaxKind.JsxClosingElement; tagName: JsxTagNameExpression; } - // @kind(SyntaxKind.JsxExpression) export interface JsxExpression extends Expression { + kind: SyntaxKind.JsxExpression; expression?: Expression; } - // @kind(SyntaxKind.JsxText) export interface JsxText extends Node { - _jsxTextExpressionBrand: any; + kind: SyntaxKind.JsxText; } export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement; @@ -1193,41 +1278,43 @@ namespace ts { // Represents a statement that is elided as part of a transformation to emit comments on a // not-emitted node. // @internal - // @kind(SyntaxKind.NotEmittedStatement) export interface NotEmittedStatement extends Statement { + kind: SyntaxKind.NotEmittedStatement; } - // @kind(SyntaxKind.EmptyStatement) - export interface EmptyStatement extends Statement { } + export interface EmptyStatement extends Statement { + kind: SyntaxKind.EmptyStatement; + } - // @kind(SyntaxKind.DebuggerStatement) - export interface DebuggerStatement extends Statement { } + export interface DebuggerStatement extends Statement { + kind: SyntaxKind.DebuggerStatement; + } - // @kind(SyntaxKind.MissingDeclaration) export interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement { + kind: SyntaxKind.MissingDeclaration; name?: Identifier; } export type BlockLike = SourceFile | Block | ModuleBlock | CaseClause; - // @kind(SyntaxKind.Block) export interface Block extends Statement { + kind: SyntaxKind.Block; statements: NodeArray; /*@internal*/ multiLine?: boolean; } - // @kind(SyntaxKind.VariableStatement) export interface VariableStatement extends Statement { + kind: SyntaxKind.VariableStatement; declarationList: VariableDeclarationList; } - // @kind(SyntaxKind.ExpressionStatement) export interface ExpressionStatement extends Statement { + kind: SyntaxKind.ExpressionStatement; expression: Expression; } - // @kind(SyntaxKind.IfStatement) export interface IfStatement extends Statement { + kind: SyntaxKind.IfStatement; expression: Expression; thenStatement: Statement; elseStatement?: Statement; @@ -1237,105 +1324,105 @@ namespace ts { statement: Statement; } - // @kind(SyntaxKind.DoStatement) export interface DoStatement extends IterationStatement { + kind: SyntaxKind.DoStatement; expression: Expression; } - // @kind(SyntaxKind.WhileStatement) export interface WhileStatement extends IterationStatement { + kind: SyntaxKind.WhileStatement; expression: Expression; } export type ForInitializer = VariableDeclarationList | Expression; - // @kind(SyntaxKind.ForStatement) export interface ForStatement extends IterationStatement { + kind: SyntaxKind.ForStatement; initializer?: ForInitializer; condition?: Expression; incrementor?: Expression; } - // @kind(SyntaxKind.ForInStatement) export interface ForInStatement extends IterationStatement { + kind: SyntaxKind.ForInStatement; initializer: ForInitializer; expression: Expression; } - // @kind(SyntaxKind.ForOfStatement) export interface ForOfStatement extends IterationStatement { + kind: SyntaxKind.ForOfStatement; initializer: ForInitializer; expression: Expression; } - // @kind(SyntaxKind.BreakStatement) export interface BreakStatement extends Statement { + kind: SyntaxKind.BreakStatement; label?: Identifier; } - // @kind(SyntaxKind.ContinueStatement) export interface ContinueStatement extends Statement { + kind: SyntaxKind.ContinueStatement; label?: Identifier; } export type BreakOrContinueStatement = BreakStatement | ContinueStatement; - // @kind(SyntaxKind.ReturnStatement) export interface ReturnStatement extends Statement { + kind: SyntaxKind.ReturnStatement; expression?: Expression; } - // @kind(SyntaxKind.WithStatement) export interface WithStatement extends Statement { + kind: SyntaxKind.WithStatement; expression: Expression; statement: Statement; } - // @kind(SyntaxKind.SwitchStatement) export interface SwitchStatement extends Statement { + kind: SyntaxKind.SwitchStatement; expression: Expression; caseBlock: CaseBlock; possiblyExhaustive?: boolean; } - // @kind(SyntaxKind.CaseBlock) export interface CaseBlock extends Node { + kind: SyntaxKind.CaseBlock; clauses: NodeArray; } - // @kind(SyntaxKind.CaseClause) export interface CaseClause extends Node { + kind: SyntaxKind.CaseClause; expression: Expression; statements: NodeArray; } - // @kind(SyntaxKind.DefaultClause) export interface DefaultClause extends Node { + kind: SyntaxKind.DefaultClause; statements: NodeArray; } export type CaseOrDefaultClause = CaseClause | DefaultClause; - // @kind(SyntaxKind.LabeledStatement) export interface LabeledStatement extends Statement { + kind: SyntaxKind.LabeledStatement; label: Identifier; statement: Statement; } - // @kind(SyntaxKind.ThrowStatement) export interface ThrowStatement extends Statement { + kind: SyntaxKind.ThrowStatement; expression: Expression; } - // @kind(SyntaxKind.TryStatement) export interface TryStatement extends Statement { + kind: SyntaxKind.TryStatement; tryBlock: Block; catchClause?: CatchClause; finallyBlock?: Block; } - // @kind(SyntaxKind.CatchClause) export interface CatchClause extends Node { + kind: SyntaxKind.CatchClause; variableDeclaration: VariableDeclaration; block: Block; } @@ -1349,13 +1436,13 @@ namespace ts { members: NodeArray; } - // @kind(SyntaxKind.ClassDeclaration) export interface ClassDeclaration extends ClassLikeDeclaration, DeclarationStatement { + kind: SyntaxKind.ClassDeclaration; name?: Identifier; } - // @kind(SyntaxKind.ClassExpression) export interface ClassExpression extends ClassLikeDeclaration, PrimaryExpression { + kind: SyntaxKind.ClassExpression; } export interface ClassElement extends Declaration { @@ -1366,40 +1453,40 @@ namespace ts { export interface TypeElement extends Declaration { _typeElementBrand: any; name?: PropertyName; - questionToken?: Node; + questionToken?: QuestionToken; } - // @kind(SyntaxKind.InterfaceDeclaration) export interface InterfaceDeclaration extends DeclarationStatement { + kind: SyntaxKind.InterfaceDeclaration; name: Identifier; typeParameters?: NodeArray; heritageClauses?: NodeArray; members: NodeArray; } - // @kind(SyntaxKind.HeritageClause) export interface HeritageClause extends Node { + kind: SyntaxKind.HeritageClause; token: SyntaxKind; types?: NodeArray; } - // @kind(SyntaxKind.TypeAliasDeclaration) export interface TypeAliasDeclaration extends DeclarationStatement { + kind: SyntaxKind.TypeAliasDeclaration; name: Identifier; typeParameters?: NodeArray; type: TypeNode; } - // @kind(SyntaxKind.EnumMember) export interface EnumMember extends Declaration { + kind: SyntaxKind.EnumMember; // This does include ComputedPropertyName, but the parser will give an error // if it parses a ComputedPropertyName in an EnumMember name: PropertyName; initializer?: Expression; } - // @kind(SyntaxKind.EnumDeclaration) export interface EnumDeclaration extends DeclarationStatement { + kind: SyntaxKind.EnumDeclaration; name: Identifier; members: NodeArray; } @@ -1408,21 +1495,26 @@ namespace ts { export type ModuleName = Identifier | StringLiteral; - // @kind(SyntaxKind.ModuleDeclaration) export interface ModuleDeclaration extends DeclarationStatement { + kind: SyntaxKind.ModuleDeclaration; name: Identifier | LiteralExpression; - body?: ModuleBlock | ModuleDeclaration; + body?: ModuleBlock | NamespaceDeclaration; + } + + export interface NamespaceDeclaration extends ModuleDeclaration { + name: Identifier; + body: ModuleBlock | NamespaceDeclaration; } - // @kind(SyntaxKind.ModuleBlock) export interface ModuleBlock extends Node, Statement { + kind: SyntaxKind.ModuleBlock; statements: NodeArray; } export type ModuleReference = EntityName | ExternalModuleReference; - // @kind(SyntaxKind.ImportEqualsDeclaration) export interface ImportEqualsDeclaration extends DeclarationStatement { + kind: SyntaxKind.ImportEqualsDeclaration; name: Identifier; // 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external @@ -1430,8 +1522,8 @@ namespace ts { moduleReference: ModuleReference; } - // @kind(SyntaxKind.ExternalModuleReference) export interface ExternalModuleReference extends Node { + kind: SyntaxKind.ExternalModuleReference; expression?: Expression; } @@ -1439,8 +1531,8 @@ namespace ts { // import "mod" => importClause = undefined, moduleSpecifier = "mod" // In rest of the cases, module specifier is string literal corresponding to module // ImportClause information is shown at its declaration below. - // @kind(SyntaxKind.ImportDeclaration) export interface ImportDeclaration extends Statement { + kind: SyntaxKind.ImportDeclaration; importClause?: ImportClause; moduleSpecifier: Expression; } @@ -1453,57 +1545,57 @@ namespace ts { // import d, * as ns from "mod" => name = d, namedBinding: NamespaceImport = { name: ns } // import { a, b as x } from "mod" => name = undefined, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]} // import d, { a, b as x } from "mod" => name = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]} - // @kind(SyntaxKind.ImportClause) export interface ImportClause extends Declaration { + kind: SyntaxKind.ImportClause; name?: Identifier; // Default binding namedBindings?: NamedImportBindings; } - // @kind(SyntaxKind.NamespaceImport) export interface NamespaceImport extends Declaration { + kind: SyntaxKind.NamespaceImport; name: Identifier; } - // @kind(SyntaxKind.NamespaceExportDeclaration) export interface NamespaceExportDeclaration extends DeclarationStatement { + kind: SyntaxKind.NamespaceExportDeclaration; name: Identifier; moduleReference: LiteralLikeNode; } - // @kind(SyntaxKind.ExportDeclaration) export interface ExportDeclaration extends DeclarationStatement { + kind: SyntaxKind.ExportDeclaration; exportClause?: NamedExports; moduleSpecifier?: Expression; } - // @kind(SyntaxKind.NamedImports) export interface NamedImports extends Node { + kind: SyntaxKind.NamedImports; elements: NodeArray; } - // @kind(SyntaxKind.NamedExports) export interface NamedExports extends Node { + kind: SyntaxKind.NamedExports; elements: NodeArray; } export type NamedImportsOrExports = NamedImports | NamedExports; - // @kind(SyntaxKind.ImportSpecifier) export interface ImportSpecifier extends Declaration { + kind: SyntaxKind.ImportSpecifier; propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) name: Identifier; // Declared name } - // @kind(SyntaxKind.ExportSpecifier) export interface ExportSpecifier extends Declaration { + kind: SyntaxKind.ExportSpecifier; propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) name: Identifier; // Declared name } export type ImportOrExportSpecifier = ImportSpecifier | ExportSpecifier; - // @kind(SyntaxKind.ExportAssignment) export interface ExportAssignment extends DeclarationStatement { + kind: SyntaxKind.ExportAssignment; isExportEquals?: boolean; expression: Expression; } @@ -1518,8 +1610,8 @@ namespace ts { } // represents a top level: { type } expression in a JSDoc comment. - // @kind(SyntaxKind.JSDocTypeExpression) export interface JSDocTypeExpression extends Node { + kind: SyntaxKind.JSDocTypeExpression; type: JSDocType; } @@ -1527,139 +1619,141 @@ namespace ts { _jsDocTypeBrand: any; } - // @kind(SyntaxKind.JSDocAllType) export interface JSDocAllType extends JSDocType { - _JSDocAllTypeBrand: any; + kind: SyntaxKind.JSDocAllType; } - // @kind(SyntaxKind.JSDocUnknownType) export interface JSDocUnknownType extends JSDocType { - _JSDocUnknownTypeBrand: any; + kind: SyntaxKind.JSDocUnknownType; } - // @kind(SyntaxKind.JSDocArrayType) export interface JSDocArrayType extends JSDocType { + kind: SyntaxKind.JSDocArrayType; elementType: JSDocType; } - // @kind(SyntaxKind.JSDocUnionType) export interface JSDocUnionType extends JSDocType { + kind: SyntaxKind.JSDocUnionType; types: NodeArray; } - // @kind(SyntaxKind.JSDocTupleType) export interface JSDocTupleType extends JSDocType { + kind: SyntaxKind.JSDocTupleType; types: NodeArray; } - // @kind(SyntaxKind.JSDocNonNullableType) export interface JSDocNonNullableType extends JSDocType { + kind: SyntaxKind.JSDocNonNullableType; type: JSDocType; } - // @kind(SyntaxKind.JSDocNullableType) export interface JSDocNullableType extends JSDocType { + kind: SyntaxKind.JSDocNullableType; type: JSDocType; } - // @kind(SyntaxKind.JSDocRecordType) - export interface JSDocRecordType extends JSDocType, TypeLiteralNode { + export interface JSDocRecordType extends JSDocType { + kind: SyntaxKind.JSDocRecordType; literal: TypeLiteralNode; } - // @kind(SyntaxKind.JSDocTypeReference) export interface JSDocTypeReference extends JSDocType { + kind: SyntaxKind.JSDocTypeReference; name: EntityName; typeArguments: NodeArray; } - // @kind(SyntaxKind.JSDocOptionalType) export interface JSDocOptionalType extends JSDocType { + kind: SyntaxKind.JSDocOptionalType; type: JSDocType; } - // @kind(SyntaxKind.JSDocFunctionType) export interface JSDocFunctionType extends JSDocType, SignatureDeclaration { + kind: SyntaxKind.JSDocFunctionType; parameters: NodeArray; type: JSDocType; } - // @kind(SyntaxKind.JSDocVariadicType) export interface JSDocVariadicType extends JSDocType { + kind: SyntaxKind.JSDocVariadicType; type: JSDocType; } - // @kind(SyntaxKind.JSDocConstructorType) export interface JSDocConstructorType extends JSDocType { + kind: SyntaxKind.JSDocConstructorType; type: JSDocType; } - // @kind(SyntaxKind.JSDocThisType) export interface JSDocThisType extends JSDocType { + kind: SyntaxKind.JSDocThisType; type: JSDocType; } export interface JSDocLiteralType extends JSDocType { + kind: SyntaxKind.JSDocLiteralType; literal: LiteralTypeNode; } export type JSDocTypeReferencingNode = JSDocThisType | JSDocConstructorType | JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType; - // @kind(SyntaxKind.JSDocRecordMember) export interface JSDocRecordMember extends PropertySignature { + kind: SyntaxKind.JSDocRecordMember; name: Identifier | LiteralExpression; type?: JSDocType; } - // @kind(SyntaxKind.JSDocComment) export interface JSDoc extends Node { + kind: SyntaxKind.JSDocComment; tags: NodeArray | undefined; comment: string | undefined; } - // @kind(SyntaxKind.JSDocTag) export interface JSDocTag extends Node { - atToken: Node; + atToken: AtToken; tagName: Identifier; comment: string | undefined; } - // @kind(SyntaxKind.JSDocTemplateTag) + export interface JSDocUnknownTag extends JSDocTag { + kind: SyntaxKind.JSDocTag; + } + export interface JSDocTemplateTag extends JSDocTag { + kind: SyntaxKind.JSDocTemplateTag; typeParameters: NodeArray; } - // @kind(SyntaxKind.JSDocReturnTag) export interface JSDocReturnTag extends JSDocTag { + kind: SyntaxKind.JSDocReturnTag; typeExpression: JSDocTypeExpression; } - // @kind(SyntaxKind.JSDocTypeTag) export interface JSDocTypeTag extends JSDocTag { + kind: SyntaxKind.JSDocTypeTag; typeExpression: JSDocTypeExpression; } - // @kind(SyntaxKind.JSDocTypedefTag) export interface JSDocTypedefTag extends JSDocTag, Declaration { + kind: SyntaxKind.JSDocTypedefTag; name?: Identifier; typeExpression?: JSDocTypeExpression; jsDocTypeLiteral?: JSDocTypeLiteral; } - // @kind(SyntaxKind.JSDocPropertyTag) export interface JSDocPropertyTag extends JSDocTag, TypeElement { + kind: SyntaxKind.JSDocPropertyTag; name: Identifier; typeExpression: JSDocTypeExpression; } - // @kind(SyntaxKind.JSDocTypeLiteral) export interface JSDocTypeLiteral extends JSDocType { + kind: SyntaxKind.JSDocTypeLiteral; jsDocPropertyTags?: NodeArray; jsDocTypeTag?: JSDocTypeTag; } - // @kind(SyntaxKind.JSDocParameterTag) export interface JSDocParameterTag extends JSDocTag { + kind: SyntaxKind.JSDocParameterTag; /** the parameter name, if provided *before* the type (TypeScript-style) */ preParameterName?: Identifier; typeExpression?: JSDocTypeExpression; @@ -1739,10 +1833,10 @@ namespace ts { } // Source files are declarations when they are external modules. - // @kind(SyntaxKind.SourceFile) export interface SourceFile extends Declaration { + kind: SyntaxKind.SourceFile; statements: NodeArray; - endOfFileToken: Node; + endOfFileToken: Token; fileName: string; /* internal */ path: Path; @@ -2086,13 +2180,12 @@ namespace ts { type: Type; } - // @kind (TypePredicateKind.This) export interface ThisTypePredicate extends TypePredicateBase { - _thisTypePredicateBrand: any; + kind: TypePredicateKind.This; } - // @kind (TypePredicateKind.Identifier) export interface IdentifierTypePredicate extends TypePredicateBase { + kind: TypePredicateKind.Identifier; parameterName: string; parameterIndex: number; } @@ -2167,8 +2260,8 @@ namespace ts { getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): SourceFile; getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[]; getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[]; - isLiteralConstDeclaration(node: VariableDeclaration): boolean; - writeLiteralConstValue(node: VariableDeclaration, writer: SymbolWriter): void; + isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean; + writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter): void; } export const enum SymbolFlags { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1a4d95feca5..ca0468516c1 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1375,7 +1375,7 @@ namespace ts { } } - export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) { + export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): ImportEqualsDeclaration | NamespaceImport { if (node.kind === SyntaxKind.ImportEqualsDeclaration) { return node; } @@ -2459,7 +2459,7 @@ namespace ts { return file.moduleName || getExternalModuleNameFromPath(host, file.fileName); } - export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration): string { + export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): string { const file = resolver.getExternalModuleFileFromDeclaration(declaration); if (!file || isDeclarationFile(file)) { return undefined; @@ -3611,8 +3611,14 @@ namespace ts { || kind === SyntaxKind.TemplateTail; } - export function isTemplateLiteralFragment(node: Node): node is TemplateLiteralFragment { - return isTemplateLiteralFragmentKind(node.kind); + export function isTemplateHead(node: Node): node is TemplateHead { + return node.kind === SyntaxKind.TemplateHead; + } + + export function isTemplateMiddleOrTemplateTail(node: Node): node is TemplateMiddle | TemplateTail { + const kind = node.kind; + return kind === SyntaxKind.TemplateMiddle + || kind === SyntaxKind.TemplateTail; } // Identifiers diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index e147eda8535..d16c038eeef 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -862,7 +862,7 @@ namespace ts { case SyntaxKind.TemplateExpression: return updateTemplateExpression(node, - visitNode((node).head, visitor, isTemplateLiteralFragment), + visitNode((node).head, visitor, isTemplateHead), visitNodes((node).templateSpans, visitor, isTemplateSpan)); case SyntaxKind.YieldExpression: @@ -890,7 +890,7 @@ namespace ts { case SyntaxKind.TemplateSpan: return updateTemplateSpan(node, visitNode((node).expression, visitor, isExpression), - visitNode((node).literal, visitor, isTemplateLiteralFragment)); + visitNode((node).literal, visitor, isTemplateMiddleOrTemplateTail)); // Element case SyntaxKind.Block: diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index b998d57a265..16108450d2c 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -175,7 +175,7 @@ namespace ts.formatting { return rangeContainsRange((parent).members, node); case SyntaxKind.ModuleDeclaration: const body = (parent).body; - return body && body.kind === SyntaxKind.Block && rangeContainsRange((body).statements, node); + return body && body.kind === SyntaxKind.ModuleBlock && rangeContainsRange((body).statements, node); case SyntaxKind.SourceFile: case SyntaxKind.Block: case SyntaxKind.ModuleBlock: diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 4fffa394fc5..84f83a9c7db 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -332,7 +332,7 @@ namespace ts.formatting { (node.parent).expression !== node) { const fullCallOrNewExpression = (node.parent).expression; - const startingExpression = getStartingExpression(fullCallOrNewExpression); + const startingExpression = getStartingExpression(fullCallOrNewExpression); if (fullCallOrNewExpression === startingExpression) { return Value.Unknown; @@ -350,15 +350,14 @@ namespace ts.formatting { return Value.Unknown; - function getStartingExpression(node: PropertyAccessExpression | CallExpression | ElementAccessExpression) { + function getStartingExpression(node: Expression) { while (true) { switch (node.kind) { case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: - - node = node.expression; + node = (node).expression; break; default: return node; diff --git a/src/services/services.ts b/src/services/services.ts index b50e1d3313d..83c449a39c2 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -29,9 +29,9 @@ namespace ts { /** The version of the language service API */ export const servicesVersion = "0.5"; - function createNode(kind: SyntaxKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject | IdentifierObject { + function createNode(kind: TKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject | IdentifierObject { const node = kind >= SyntaxKind.FirstNode ? new NodeObject(kind, pos, end) : - kind === SyntaxKind.Identifier ? new IdentifierObject(kind, pos, end) : + kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) : new TokenObject(kind, pos, end); node.parent = parent; return node; @@ -210,14 +210,13 @@ namespace ts { } } - class TokenOrIdentifierObject implements Token { + class TokenOrIdentifierObject implements Node { public kind: SyntaxKind; public pos: number; public end: number; public flags: NodeFlags; public parent: Node; public jsDocComments: JSDoc[]; - public __tokenTag: any; constructor(pos: number, end: number) { // Set properties in same order as NodeObject @@ -319,16 +318,25 @@ namespace ts { } } - class TokenObject extends TokenOrIdentifierObject { - public kind: SyntaxKind; - constructor(kind: SyntaxKind, pos: number, end: number) { + class TokenObject extends TokenOrIdentifierObject implements Token { + public kind: TKind; + + constructor(kind: TKind, pos: number, end: number) { super(pos, end); this.kind = kind; } } - class IdentifierObject extends TokenOrIdentifierObject { - constructor(kind: SyntaxKind, pos: number, end: number) { + class IdentifierObject extends TokenOrIdentifierObject implements Identifier { + public kind: SyntaxKind.Identifier; + public text: string; + _primaryExpressionBrand: any; + _memberExpressionBrand: any; + _leftHandSideExpressionBrand: any; + _incrementExpressionBrand: any; + _unaryExpressionBrand: any; + _expressionBrand: any; + constructor(kind: SyntaxKind.Identifier, pos: number, end: number) { super(pos, end); } } @@ -424,6 +432,7 @@ namespace ts { } class SourceFileObject extends NodeObject implements SourceFile { + public kind: SyntaxKind.SourceFile; public _declarationBrand: any; public fileName: string; public path: Path; @@ -432,7 +441,7 @@ namespace ts { public lineMap: number[]; public statements: NodeArray; - public endOfFileToken: Node; + public endOfFileToken: Token; public amdDependencies: { name: string; path: string }[]; public moduleName: string; diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 8b4d986df53..c9141278b10 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -114,12 +114,12 @@ namespace ts.SymbolDisplay { } // try get the call/construct signature from the type if it matches - let callExpression: CallExpression; + let callExpression: CallExpression | NewExpression; if (location.kind === SyntaxKind.CallExpression || location.kind === SyntaxKind.NewExpression) { - callExpression = location; + callExpression = location; } else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) { - callExpression = location.parent; + callExpression = location.parent; } if (callExpression) { From b63e1345f3b01a24b11d268e4fbcfe0595eb7dd0 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 4 Oct 2016 10:41:43 -0700 Subject: [PATCH 2/4] Removed isTemplateLiteralFragmentKind --- src/compiler/utilities.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ca0468516c1..89fc8d9a81d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3605,12 +3605,6 @@ namespace ts { return SyntaxKind.FirstTemplateToken <= kind && kind <= SyntaxKind.LastTemplateToken; } - function isTemplateLiteralFragmentKind(kind: SyntaxKind) { - return kind === SyntaxKind.TemplateHead - || kind === SyntaxKind.TemplateMiddle - || kind === SyntaxKind.TemplateTail; - } - export function isTemplateHead(node: Node): node is TemplateHead { return node.kind === SyntaxKind.TemplateHead; } From f89db7d99f3cddb2a2842a026c9c2ed71d1188e9 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 4 Oct 2016 17:13:29 -0700 Subject: [PATCH 3/4] Added missing binary operator In. --- src/compiler/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 7cc8dcd81d2..224c26a7263 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1020,6 +1020,7 @@ namespace ts { | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.InstanceOfKeyword + | SyntaxKind.InKeyword | SyntaxKind.CommaToken; export type BinaryOperatorToken = Token; From 49695edadb2143da2c3e8b7c0f7e7548ea35fa7c Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 4 Oct 2016 17:38:35 -0700 Subject: [PATCH 4/4] Split up binary operators --- src/compiler/checker.ts | 6 +- src/compiler/factory.ts | 7 +- src/compiler/parser.ts | 2 +- src/compiler/transformers/es6.ts | 2 +- src/compiler/transformers/generators.ts | 4 +- src/compiler/transformers/ts.ts | 2 +- src/compiler/types.ts | 217 +++++++++++++++++++----- src/compiler/utilities.ts | 6 +- src/compiler/visitor.ts | 2 +- 9 files changed, 191 insertions(+), 57 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2088fa8761e..8dcc7fc8961 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9244,7 +9244,7 @@ namespace ts { } function findFirstSuperCall(n: Node): Node { - if (isSuperCallExpression(n)) { + if (isSuperCall(n)) { return n; } else if (isFunctionLike(n)) { @@ -14407,7 +14407,7 @@ namespace ts { } function containsSuperCall(n: Node): boolean { - if (isSuperCallExpression(n)) { + if (isSuperCall(n)) { return true; } else if (isFunctionLike(n)) { @@ -14463,7 +14463,7 @@ namespace ts { let superCallStatement: ExpressionStatement; for (const statement of statements) { - if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) { + if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((statement).expression)) { superCallStatement = statement; break; } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index b9a87e05457..97a36f46b13 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -105,6 +105,7 @@ namespace ts { export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral; export function createLiteral(value: string, location?: TextRange): StringLiteral; export function createLiteral(value: number, location?: TextRange): NumericLiteral; + export function createLiteral(value: boolean, location?: TextRange): BooleanLiteral; export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression; export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression { if (typeof value === "number") { @@ -120,7 +121,7 @@ namespace ts { node.text = value; return node; } - else { + else if (value) { const node = createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined); node.textSourceNode = value; node.text = value.text; @@ -497,14 +498,14 @@ namespace ts { return node; } - export function createTaggedTemplate(tag: Expression, template: Template, location?: TextRange) { + export function createTaggedTemplate(tag: Expression, template: TemplateLiteral, location?: TextRange) { const node = createNode(SyntaxKind.TaggedTemplateExpression, location); node.tag = parenthesizeForAccess(tag); node.template = template; return node; } - export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: Template) { + export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral) { if (node.tag !== tag || node.template !== template) { return updateNode(createTaggedTemplate(tag, template, node), node); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1d52ec9f648..2675f752752 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3930,7 +3930,7 @@ namespace ts { const tagExpression = createNode(SyntaxKind.TaggedTemplateExpression, expression.pos); tagExpression.tag = expression; tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral - ? parseLiteralNode() + ? parseLiteralNode() : parseTemplateExpression(); expression = finishNode(tagExpression); continue; diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index d8bf9ffa0f9..2f2beafbfdf 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -982,7 +982,7 @@ namespace ts { if (statementOffset < ctorStatements.length) { firstStatement = ctorStatements[statementOffset]; - if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((firstStatement as ExpressionStatement).expression)) { + if (firstStatement.kind === SyntaxKind.ExpressionStatement && isSuperCall((firstStatement as ExpressionStatement).expression)) { const superCall = (firstStatement as ExpressionStatement).expression as CallExpression; superCallExpression = setOriginalNode( saveStateAndInvoke(superCall, visitImmediateSuperCallInBody), diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 6d20f4b1e30..3b10f90e76a 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -657,12 +657,12 @@ namespace ts { } } - function isCompoundAssignment(kind: SyntaxKind) { + function isCompoundAssignment(kind: BinaryOperator): kind is CompoundAssignmentOperator { return kind >= SyntaxKind.FirstCompoundAssignment && kind <= SyntaxKind.LastCompoundAssignment; } - function getOperatorForCompoundAssignment(kind: SyntaxKind) { + function getOperatorForCompoundAssignment(kind: CompoundAssignmentOperator): BitwiseOperatorOrHigher { switch (kind) { case SyntaxKind.PlusEqualsToken: return SyntaxKind.PlusToken; case SyntaxKind.MinusEqualsToken: return SyntaxKind.MinusToken; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 2b757619365..29f2d743172 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -989,7 +989,7 @@ namespace ts { } const statement = statements[index]; - if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) { + if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((statement).expression)) { result.push(visitNode(statement, visitor, isStatement)); return index + 1; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 224c26a7263..d5ba0249317 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -523,7 +523,8 @@ namespace ts { | Token | Token | Token - | Token; + | Token + ; export type ModifiersArray = NodeArray; @@ -909,13 +910,16 @@ namespace ts { _incrementExpressionBrand: any; } + // see: https://tc39.github.io/ecma262/#prod-UpdateExpression + // see: https://tc39.github.io/ecma262/#prod-UnaryExpression export type PrefixUnaryOperator = SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken - | SyntaxKind.ExclamationToken; + | SyntaxKind.ExclamationToken + ; export interface PrefixUnaryExpression extends IncrementExpression { kind: SyntaxKind.PrefixUnaryExpression; @@ -923,9 +927,11 @@ namespace ts { operand: UnaryExpression; } + // see: https://tc39.github.io/ecma262/#prod-UpdateExpression export type PostfixUnaryOperator = SyntaxKind.PlusPlusToken - | SyntaxKind.MinusMinusToken; + | SyntaxKind.MinusMinusToken + ; export interface PostfixUnaryExpression extends IncrementExpression { kind: SyntaxKind.PostfixUnaryExpression; @@ -949,12 +955,20 @@ namespace ts { _primaryExpressionBrand: any; } - export interface KeywordExpression extends PrimaryExpression { - kind: SyntaxKind.TrueKeyword - | SyntaxKind.FalseKeyword - | SyntaxKind.NullKeyword - | SyntaxKind.ThisKeyword - | SyntaxKind.SuperKeyword; + export interface NullLiteral extends PrimaryExpression { + kind: SyntaxKind.NullKeyword; + } + + export interface BooleanLiteral extends PrimaryExpression { + kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword; + } + + export interface ThisExpression extends PrimaryExpression { + kind: SyntaxKind.ThisKeyword; + } + + export interface SuperExpression extends PrimaryExpression { + kind: SyntaxKind.SuperKeyword; } export interface DeleteExpression extends UnaryExpression { @@ -983,45 +997,142 @@ namespace ts { expression?: Expression; } - export type BinaryOperator - = SyntaxKind.PlusToken - | SyntaxKind.PlusEqualsToken - | SyntaxKind.MinusToken - | SyntaxKind.MinusEqualsToken - | SyntaxKind.AsteriskToken - | SyntaxKind.AsteriskAsteriskToken - | SyntaxKind.AsteriskAsteriskEqualsToken - | SyntaxKind.AsteriskEqualsToken + // see: https://tc39.github.io/ecma262/#prod-ExponentiationExpression + export type ExponentiationOperator + = SyntaxKind.AsteriskAsteriskToken + ; + + // see: https://tc39.github.io/ecma262/#prod-MultiplicativeOperator + export type MultiplicativeOperator + = SyntaxKind.AsteriskToken | SyntaxKind.SlashToken - | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentToken - | SyntaxKind.PercentEqualsToken - | SyntaxKind.AmpersandToken - | SyntaxKind.AmpersandAmpersandToken - | SyntaxKind.AmpersandEqualsToken - | SyntaxKind.BarToken - | SyntaxKind.BarBarToken - | SyntaxKind.BarEqualsToken - | SyntaxKind.CaretToken - | SyntaxKind.CaretEqualsToken - | SyntaxKind.LessThanToken - | SyntaxKind.LessThanLessThanToken - | SyntaxKind.LessThanLessThanEqualsToken - | SyntaxKind.LessThanEqualsToken - | SyntaxKind.GreaterThanToken + ; + + // see: https://tc39.github.io/ecma262/#prod-MultiplicativeExpression + export type MultiplicativeOperatorOrHigher + = ExponentiationOperator + | MultiplicativeOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-AdditiveExpression + export type AdditiveOperator + = SyntaxKind.PlusToken + | SyntaxKind.MinusToken + ; + + // see: https://tc39.github.io/ecma262/#prod-AdditiveExpression + export type AdditiveOperatorOrHigher + = MultiplicativeOperatorOrHigher + | AdditiveOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-ShiftExpression + export type ShiftOperator + = SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken - | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken - | SyntaxKind.GreaterThanGreaterThanEqualsToken + ; + + // see: https://tc39.github.io/ecma262/#prod-ShiftExpression + export type ShiftOperatorOrHigher + = AdditiveOperatorOrHigher + | ShiftOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-RelationalExpression + export type RelationalOperator + = SyntaxKind.LessThanToken + | SyntaxKind.LessThanEqualsToken + | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken - | SyntaxKind.EqualsToken - | SyntaxKind.EqualsEqualsToken + | SyntaxKind.InstanceOfKeyword + | SyntaxKind.InKeyword + ; + + // see: https://tc39.github.io/ecma262/#prod-RelationalExpression + export type RelationalOperatorOrHigher + = ShiftOperatorOrHigher + | RelationalOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-EqualityExpression + export type EqualityOperator + = SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken - | SyntaxKind.InstanceOfKeyword - | SyntaxKind.InKeyword - | SyntaxKind.CommaToken; + ; + + // see: https://tc39.github.io/ecma262/#prod-EqualityExpression + export type EqualityOperatorOrHigher + = RelationalOperatorOrHigher + | EqualityOperator; + + // see: https://tc39.github.io/ecma262/#prod-BitwiseANDExpression + // see: https://tc39.github.io/ecma262/#prod-BitwiseXORExpression + // see: https://tc39.github.io/ecma262/#prod-BitwiseORExpression + export type BitwiseOperator + = SyntaxKind.AmpersandToken + | SyntaxKind.BarToken + | SyntaxKind.CaretToken + ; + + // see: https://tc39.github.io/ecma262/#prod-BitwiseANDExpression + // see: https://tc39.github.io/ecma262/#prod-BitwiseXORExpression + // see: https://tc39.github.io/ecma262/#prod-BitwiseORExpression + export type BitwiseOperatorOrHigher + = EqualityOperatorOrHigher + | BitwiseOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-LogicalANDExpression + // see: https://tc39.github.io/ecma262/#prod-LogicalORExpression + export type LogicalOperator + = SyntaxKind.AmpersandAmpersandToken + | SyntaxKind.BarBarToken + ; + + // see: https://tc39.github.io/ecma262/#prod-LogicalANDExpression + // see: https://tc39.github.io/ecma262/#prod-LogicalORExpression + export type LogicalOperatorOrHigher + = BitwiseOperatorOrHigher + | LogicalOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-AssignmentOperator + export type CompoundAssignmentOperator + = SyntaxKind.PlusEqualsToken + | SyntaxKind.MinusEqualsToken + | SyntaxKind.AsteriskAsteriskEqualsToken + | SyntaxKind.AsteriskEqualsToken + | SyntaxKind.SlashEqualsToken + | SyntaxKind.PercentEqualsToken + | SyntaxKind.AmpersandEqualsToken + | SyntaxKind.BarEqualsToken + | SyntaxKind.CaretEqualsToken + | SyntaxKind.LessThanLessThanEqualsToken + | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken + | SyntaxKind.GreaterThanGreaterThanEqualsToken + ; + + // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression + export type AssignmentOperator + = SyntaxKind.EqualsToken + | CompoundAssignmentOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression + export type AssignmentOperatorOrHigher + = LogicalOperatorOrHigher + | AssignmentOperator + ; + + // see: https://tc39.github.io/ecma262/#prod-Expression + export type BinaryOperator + = AssignmentOperatorOrHigher + | SyntaxKind.CommaToken + ; export type BinaryOperatorToken = Token; @@ -1057,6 +1168,9 @@ namespace ts { body: ConciseBody; } + // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral, + // or any literal of a template, this means quotes have been removed and escapes have been converted to actual characters. + // For a NumericLiteral, the stored value is the toString() representation of the number. For example 1, 1.00, and 1e0 are all stored as just "1". export interface LiteralLikeNode extends Node { text: string; isUnterminated?: boolean; @@ -1097,7 +1211,7 @@ namespace ts { kind: SyntaxKind.TemplateTail; } - export type Template = TemplateExpression | LiteralExpression; + export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral; export interface TemplateExpression extends PrimaryExpression { kind: SyntaxKind.TemplateExpression; @@ -1156,6 +1270,10 @@ namespace ts { name: Identifier; } + export interface SuperPropertyAccessExpression extends PropertyAccessExpression { + expression: SuperExpression; + } + /** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */ export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { _propertyAccessExpressionLikeQualifiedNameBrand?: any; @@ -1168,6 +1286,16 @@ namespace ts { argumentExpression?: Expression; } + export interface SuperElementAccessExpression extends ElementAccessExpression { + expression: SuperExpression; + } + + // see: https://tc39.github.io/ecma262/#prod-SuperProperty + export type SuperProperty + = SuperPropertyAccessExpression + | SuperElementAccessExpression + ; + export interface CallExpression extends LeftHandSideExpression, Declaration { kind: SyntaxKind.CallExpression; expression: LeftHandSideExpression; @@ -1175,6 +1303,11 @@ namespace ts { arguments: NodeArray; } + // see: https://tc39.github.io/ecma262/#prod-SuperCall + export interface SuperCall extends CallExpression { + expression: SuperExpression; + } + export interface ExpressionWithTypeArguments extends TypeNode { kind: SyntaxKind.ExpressionWithTypeArguments; expression: LeftHandSideExpression; @@ -1191,7 +1324,7 @@ namespace ts { export interface TaggedTemplateExpression extends MemberExpression { kind: SyntaxKind.TaggedTemplateExpression; tag: LeftHandSideExpression; - template: Template; + template: TemplateLiteral; } export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 89fc8d9a81d..938064dab4e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -609,7 +609,7 @@ namespace ts { return !!(getCombinedNodeFlags(node) & NodeFlags.Let); } - export function isSuperCallExpression(n: Node): boolean { + export function isSuperCall(n: Node): n is SuperCall { return n.kind === SyntaxKind.CallExpression && (n).expression.kind === SyntaxKind.SuperKeyword; } @@ -1047,7 +1047,7 @@ namespace ts { /** * Determines whether a node is a property or element access expression for super. */ - export function isSuperProperty(node: Node): node is (PropertyAccessExpression | ElementAccessExpression) { + export function isSuperProperty(node: Node): node is SuperProperty { const kind = node.kind; return (kind === SyntaxKind.PropertyAccessExpression || kind === SyntaxKind.ElementAccessExpression) && (node).expression.kind === SyntaxKind.SuperKeyword; @@ -3777,7 +3777,7 @@ namespace ts { return node.kind === SyntaxKind.CallExpression; } - export function isTemplate(node: Node): node is Template { + export function isTemplateLiteral(node: Node): node is TemplateLiteral { const kind = node.kind; return kind === SyntaxKind.TemplateExpression || kind === SyntaxKind.NoSubstitutionTemplateLiteral; diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index d16c038eeef..643c5c91eda 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -799,7 +799,7 @@ namespace ts { case SyntaxKind.TaggedTemplateExpression: return updateTaggedTemplate(node, visitNode((node).tag, visitor, isExpression), - visitNode((node).template, visitor, isTemplate)); + visitNode((node).template, visitor, isTemplateLiteral)); case SyntaxKind.ParenthesizedExpression: return updateParen(node,