From 8bf176ac3dcc5edb8d3e1a4d219c681f22c02377 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 4 Feb 2016 16:41:58 -0800 Subject: [PATCH] Cleanup and reorganization of node tests --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 10 +- src/compiler/emitter.ts | 6 +- src/compiler/factory.ts | 1 + src/compiler/program.ts | 2 +- src/compiler/scanner.ts | 2 +- src/compiler/types.ts | 32 +- src/compiler/utilities.ts | 872 ++++++++++++----------- src/compiler/visitor.ts | 810 ++++++++++----------- src/harness/typeWriter.ts | 2 +- src/services/breakpoints.ts | 2 +- src/services/formatting/rules.ts | 10 +- src/services/formatting/smartIndenter.ts | 4 +- src/services/services.ts | 4 +- 14 files changed, 919 insertions(+), 840 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 0e169ca7aca..f377fb674d2 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1696,7 +1696,7 @@ namespace ts { case Reachability.Unreachable: const reportError = // report error on all statements except empty ones - (isStatement(node) && node.kind !== SyntaxKind.EmptyStatement) || + (isStatementButNotDeclaration(node) && node.kind !== SyntaxKind.EmptyStatement) || // report error on class declarations node.kind === SyntaxKind.ClassDeclaration || // report error on instantiated modules or const-enums only modules if preserveConstEnums is set diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0628e7fd522..3cb9031fd99 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4934,7 +4934,7 @@ namespace ts { case SyntaxKind.JSDocRecordType: return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); // This function assumes that an identifier or qualified name is a type expression - // Callers should first ensure this by calling isTypeNode + // Callers should first ensure this by calling isPartOfTypeNode case SyntaxKind.Identifier: case SyntaxKind.QualifiedName: const symbol = getSymbolAtLocation(node); @@ -15385,7 +15385,7 @@ namespace ts { (entityName.parent.kind === SyntaxKind.JsxClosingElement)) { return getJsxElementTagSymbol(entityName.parent); } - else if (isExpression(entityName)) { + else if (isPartOfExpression(entityName)) { if (nodeIsMissing(entityName)) { // Missing entity name. return undefined; @@ -15468,7 +15468,7 @@ namespace ts { case SyntaxKind.ThisKeyword: case SyntaxKind.SuperKeyword: - const type = isExpression(node) ? checkExpression(node) : getTypeFromTypeNode(node); + const type = isPartOfExpression(node) ? checkExpression(node) : getTypeFromTypeNode(node); return type.symbol; case SyntaxKind.ThisType: @@ -15529,11 +15529,11 @@ namespace ts { return unknownType; } - if (isTypeNode(node)) { + if (isPartOfTypeNode(node)) { return getTypeFromTypeNode(node); } - if (isExpression(node)) { + if (isPartOfExpression(node)) { return getTypeOfExpression(node); } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index e86d86603b4..f0e32bdf96c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1020,7 +1020,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge return; } - const emitOuterParens = isExpression(node.parent) + const emitOuterParens = isPartOfExpression(node.parent) && templateNeedsParens(node, node.parent); if (emitOuterParens) { @@ -5788,7 +5788,7 @@ const _super = (function (geti, seti) { /** Serializes a TypeReferenceNode to an appropriate JS constructor value. Used by the __metadata decorator. */ function emitSerializedTypeReferenceNode(node: TypeReferenceNode) { let location: Node = node.parent; - while (isDeclaration(location) || isTypeNode(location)) { + while (isDeclaration(location) || isPartOfTypeNode(location)) { location = location.parent; } @@ -7156,7 +7156,7 @@ const _super = (function (geti, seti) { } // text should be quoted string - // for deduplication purposes in key remove leading and trailing quotes so 'a' and "a" will be considered the same + // for deduplication purposes in key remove leading and trailing quotes so 'a' and "a" will be considered the same const key = text.substr(1, text.length - 2); if (hasProperty(groupIndices, key)) { diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index d838288ef25..c28162d8723 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -134,4 +134,5 @@ namespace ts { block.statements = createNodeArray(statements); return block; } + } \ No newline at end of file diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 9852b2354e2..4a3d0cbc164 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1719,7 +1719,7 @@ namespace ts { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators")); } - if (options.reactNamespace && !isIdentifier(options.reactNamespace, languageVersion)) { + if (options.reactNamespace && !isIdentifierText(options.reactNamespace, languageVersion)) { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace)); } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 4470d7f623c..68c8f5bc794 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -696,7 +696,7 @@ namespace ts { } /* @internal */ - export function isIdentifier(name: string, languageVersion: ScriptTarget): boolean { + export function isIdentifierText(name: string, languageVersion: ScriptTarget): boolean { if (!isIdentifierStart(name.charCodeAt(0), languageVersion)) { return false; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 177934fc13b..e123d08e81c 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -553,10 +553,12 @@ namespace ts { // @kind(SyntaxKind.ConstructSignature) export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement { } + export type BindingName = Identifier | ObjectBindingPattern | ArrayBindingPattern; + // @kind(SyntaxKind.VariableDeclaration) export interface VariableDeclaration extends Declaration { parent?: VariableDeclarationList; - name: Identifier | BindingPattern; // Declared variable name + name: BindingName; // Declared variable name type?: TypeNode; // Optional type annotation initializer?: Expression; // Optional initializer } @@ -569,7 +571,7 @@ namespace ts { // @kind(SyntaxKind.Parameter) export interface ParameterDeclaration extends Declaration { dotDotDotToken?: Node; // Present on rest parameter - name: Identifier | BindingPattern; // Declared parameter name + name: BindingName; // Declared parameter name questionToken?: Node; // Present on optional parameter type?: TypeNode; // Optional type annotation initializer?: Expression; // Optional initializer @@ -579,7 +581,7 @@ namespace ts { export interface BindingElement extends Declaration { propertyName?: PropertyName; // Binding property name (in object binding pattern) dotDotDotToken?: Node; // Present on rest binding element - name: Identifier | BindingPattern; // Declared binding element name + name: BindingName; // Declared binding element name initializer?: Expression; // Optional initializer } @@ -946,6 +948,8 @@ namespace ts { _templateLiteralFragmentBrand: any; } + export type Template = TemplateExpression | LiteralExpression; + // @kind(SyntaxKind.TemplateExpression) export interface TemplateExpression extends PrimaryExpression { head: TemplateLiteralFragment; @@ -1017,7 +1021,7 @@ namespace ts { // @kind(SyntaxKind.TaggedTemplateExpression) export interface TaggedTemplateExpression extends MemberExpression { tag: LeftHandSideExpression; - template: LiteralExpression | TemplateExpression; + template: Template; } export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator; @@ -1049,7 +1053,7 @@ namespace ts { export interface JsxOpeningElement extends Expression { _openingElementBrand?: any; tagName: EntityName; - attributes: NodeArray; + attributes: NodeArray; } /// A JSX expression of the form @@ -1061,6 +1065,8 @@ namespace ts { /// Either the opening tag in a ... pair, or the lone in a self-closing form export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; + export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute; + // @kind(SyntaxKind.JsxAttribute) export interface JsxAttribute extends Node { name: Identifier; @@ -1143,22 +1149,24 @@ namespace ts { expression: Expression; } + export type ForInitializer = VariableDeclarationList | Expression; + // @kind(SyntaxKind.ForStatement) export interface ForStatement extends IterationStatement { - initializer?: VariableDeclarationList | Expression; + initializer?: ForInitializer; condition?: Expression; incrementor?: Expression; } // @kind(SyntaxKind.ForInStatement) export interface ForInStatement extends IterationStatement { - initializer: VariableDeclarationList | Expression; + initializer: ForInitializer; expression: Expression; } // @kind(SyntaxKind.ForOfStatement) export interface ForOfStatement extends IterationStatement { - initializer: VariableDeclarationList | Expression; + initializer: ForInitializer; expression: Expression; } @@ -1297,9 +1305,11 @@ namespace ts { export type ModuleBody = ModuleBlock | ModuleDeclaration; + export type ModuleName = Identifier | StringLiteral; + // @kind(SyntaxKind.ModuleDeclaration) export interface ModuleDeclaration extends DeclarationStatement { - name: Identifier | LiteralExpression; + name: ModuleName; body: ModuleBlock | ModuleDeclaration; } @@ -1334,6 +1344,8 @@ namespace ts { moduleSpecifier: Expression; } + export type NamedImportBindings = NamespaceImport | NamedImports; + // In case of: // import d from "mod" => name = d, namedBinding = undefined // import * as ns from "mod" => name = undefined, namedBinding: NamespaceImport = { name: ns } @@ -1343,7 +1355,7 @@ namespace ts { // @kind(SyntaxKind.ImportClause) export interface ImportClause extends Declaration { name?: Identifier; // Default binding - namedBindings?: NamespaceImport | NamedImports; + namedBindings?: NamedImportBindings; } // @kind(SyntaxKind.NamespaceImport) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a6df27bc3b9..9cc5ffcf30f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -498,7 +498,7 @@ namespace ts { export let fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; export let fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/; - export function isTypeNode(node: Node): boolean { + export function isPartOfTypeNode(node: Node): boolean { if (SyntaxKind.FirstTypeNode <= node.kind && node.kind <= SyntaxKind.LastTypeNode) { return true; } @@ -527,7 +527,7 @@ namespace ts { } // At this point, node is either a qualified name or an identifier Debug.assert(node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName || node.kind === SyntaxKind.PropertyAccessExpression, - "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'."); + "'node' was expected to be a qualified name, identifier or property access in 'isPartOfTypeNode'."); case SyntaxKind.QualifiedName: case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ThisKeyword: @@ -535,11 +535,11 @@ namespace ts { if (parent.kind === SyntaxKind.TypeQuery) { return false; } - // Do not recursively call isTypeNode on the parent. In the example: + // Do not recursively call isPartOfTypeNode on the parent. In the example: // // let a: A.B.C; // - // Calling isTypeNode would consider the qualified name A.B a type node. Only C or + // Calling isPartOfTypeNode would consider the qualified name A.B a type node. Only C or // A.B.C is a type node. if (SyntaxKind.FirstTypeNode <= parent.kind && parent.kind <= SyntaxKind.LastTypeNode) { return true; @@ -643,7 +643,7 @@ namespace ts { return; } } - else if (!isTypeNode(node)) { + else if (!isPartOfTypeNode(node)) { // This is the general case, which should include mostly expressions and statements. // Also includes NodeArrays. forEachChild(node, traverse); @@ -652,6 +652,7 @@ namespace ts { } } + export function isVariableLike(node: Node): node is VariableLikeDeclaration { if (node) { switch (node.kind) { @@ -938,15 +939,7 @@ namespace ts { && nodeCanBeDecorated(node); } - export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression { - return node.kind === SyntaxKind.PropertyAccessExpression; - } - - export function isElementAccessExpression(node: Node): node is ElementAccessExpression { - return node.kind === SyntaxKind.ElementAccessExpression; - } - - export function isExpression(node: Node): boolean { + export function isPartOfExpression(node: Node): boolean { switch (node.kind) { case SyntaxKind.SuperKeyword: case SyntaxKind.NullKeyword: @@ -1040,7 +1033,7 @@ namespace ts { case SyntaxKind.ExpressionWithTypeArguments: return (parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent); default: - if (isExpression(parent)) { + if (isPartOfExpression(parent)) { return true; } } @@ -1295,10 +1288,6 @@ namespace ts { return SyntaxKind.FirstTemplateToken <= kind && kind <= SyntaxKind.LastTemplateToken; } - export function isBindingPattern(node: Node): node is BindingPattern { - return !!node && (node.kind === SyntaxKind.ArrayBindingPattern || node.kind === SyntaxKind.ObjectBindingPattern); - } - export function isNodeDescendentOf(node: Node, ancestor: Node): boolean { while (node) { if (node === ancestor) return true; @@ -1317,83 +1306,6 @@ namespace ts { return false; } - export function isDeclaration(node: Node): boolean { - switch (node.kind) { - case SyntaxKind.ArrowFunction: - case SyntaxKind.BindingElement: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.Constructor: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.EnumMember: - case SyntaxKind.ExportSpecifier: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.GetAccessor: - case SyntaxKind.ImportClause: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.NamespaceImport: - case SyntaxKind.Parameter: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.SetAccessor: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.TypeParameter: - case SyntaxKind.VariableDeclaration: - return true; - } - return false; - } - - export function isStatement(n: Node): boolean { - switch (n.kind) { - case SyntaxKind.BreakStatement: - case SyntaxKind.ContinueStatement: - case SyntaxKind.DebuggerStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.ExpressionStatement: - case SyntaxKind.EmptyStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.IfStatement: - case SyntaxKind.LabeledStatement: - case SyntaxKind.ReturnStatement: - case SyntaxKind.SwitchStatement: - case SyntaxKind.ThrowStatement: - case SyntaxKind.TryStatement: - case SyntaxKind.VariableStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.WithStatement: - case SyntaxKind.ExportAssignment: - return true; - default: - return false; - } - } - - export function isClassElement(n: Node): n is ClassElement { - switch (n.kind) { - case SyntaxKind.Constructor: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.MethodSignature: - case SyntaxKind.IndexSignature: - return true; - default: - return false; - } - } - // True if the given identifier, string literal, or number literal is the name of a declaration node export function isDeclarationName(name: Node): name is Identifier | StringLiteral | LiteralExpression { if (name.kind !== SyntaxKind.Identifier && name.kind !== SyntaxKind.StringLiteral && name.kind !== SyntaxKind.NumericLiteral) { @@ -1663,10 +1575,6 @@ namespace ts { return clone; } - export function isQualifiedName(node: Node): node is QualifiedName { - return node.kind === SyntaxKind.QualifiedName; - } - export function nodeIsSynthesized(node: TextRange): boolean { return positionIsSynthesized(node.pos) || positionIsSynthesized(node.end); @@ -2332,65 +2240,6 @@ namespace ts { return 0; } - export function isLiteralExpression(node: Node): node is LiteralExpression { - return isLiteralKind(node.kind); - } - - export function isLeftHandSideExpression(node: Node): node is LeftHandSideExpression { - if (node) { - switch (node.kind) { - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.CallExpression: - case SyntaxKind.JsxElement: - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.TaggedTemplateExpression: - case SyntaxKind.ArrayLiteralExpression: - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.ClassExpression: - case SyntaxKind.FunctionExpression: - case SyntaxKind.Identifier: - case SyntaxKind.RegularExpressionLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateExpression: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.ThisKeyword: - case SyntaxKind.TrueKeyword: - case SyntaxKind.SuperKeyword: - return true; - } - } - - return false; - } - - export function isEntityName(node: Node): node is EntityName { - const kind = node.kind; - return kind === SyntaxKind.QualifiedName - || kind === SyntaxKind.Identifier; - } - - export function isIdentifierNode(node: Node): node is Identifier { - return node.kind === SyntaxKind.Identifier; - } - - export function isComputedPropertyName(node: Node): node is ComputedPropertyName { - return node.kind === SyntaxKind.ComputedPropertyName; - } - - export function isBinaryExpression(node: Node): node is BinaryExpression { - return node.kind === SyntaxKind.BinaryExpression; - } - - export function isShortHandPropertyAssignment(node: Node): node is ShorthandPropertyAssignment { - return node.kind === SyntaxKind.ShorthandPropertyAssignment; - } - export function isAssignmentOperator(token: SyntaxKind): boolean { return token >= SyntaxKind.FirstAssignment && token <= SyntaxKind.LastAssignment; } @@ -2401,245 +2250,6 @@ namespace ts { isClassLike(node.parent.parent); } - export function isExpressionNode(node: Node): node is Expression { - const kind = node.kind; - return isUnaryExpression(node) - || kind === SyntaxKind.ConditionalExpression - || kind === SyntaxKind.YieldExpression - || kind === SyntaxKind.ArrowFunction - || kind === SyntaxKind.BinaryExpression - || kind === SyntaxKind.SpreadElementExpression - || kind === SyntaxKind.AsExpression - || kind === SyntaxKind.OmittedExpression; - } - - export function isDecorator(node: Node): node is Decorator { - return node.kind === SyntaxKind.Decorator; - } - - export function isModifier(node: Node): node is Modifier { - return isModifierKind(node.kind); - } - - /** - * Node test that determines whether a node is a valid type node. - * This differs from the existing `isTypeNode` function which - * determines whether a node is *part* of a TypeNode. - */ - export function isTypeNodeNode(node: Node): node is TypeNode { - const kind = node.kind; - return kind === SyntaxKind.AnyKeyword - || kind === SyntaxKind.NumberKeyword - || kind === SyntaxKind.BooleanKeyword - || kind === SyntaxKind.StringKeyword - || kind === SyntaxKind.SymbolKeyword - || kind === SyntaxKind.VoidKeyword - || kind === SyntaxKind.FunctionType - || kind === SyntaxKind.ConstructorType - || kind === SyntaxKind.TypeReference - || kind === SyntaxKind.TypePredicate - || kind === SyntaxKind.TypeQuery - || kind === SyntaxKind.TypeLiteral - || kind === SyntaxKind.ArrayType - || kind === SyntaxKind.TupleType - || kind === SyntaxKind.UnionType - || kind === SyntaxKind.IntersectionType - || kind === SyntaxKind.ParenthesizedType - || kind === SyntaxKind.StringLiteralType - || kind === SyntaxKind.ExpressionWithTypeArguments - || kind === SyntaxKind.ThisType; - } - - export function isStatementNode(node: Node): node is Statement { - return isStatement(node) - || isDeclarationStatement(node); - } - - export function isDeclarationStatement(node: Node): node is DeclarationStatement { - const kind = node.kind; - return kind === SyntaxKind.FunctionDeclaration - || kind === SyntaxKind.MissingDeclaration - || kind === SyntaxKind.ClassDeclaration - || kind === SyntaxKind.InterfaceDeclaration - || kind === SyntaxKind.TypeAliasDeclaration - || kind === SyntaxKind.EnumDeclaration - || kind === SyntaxKind.ModuleDeclaration - || kind === SyntaxKind.ImportEqualsDeclaration - || kind === SyntaxKind.ExportDeclaration - || kind === SyntaxKind.ExportAssignment; - } - - export function isPropertyName(node: Node): node is PropertyName { - const kind = node.kind; - return kind === SyntaxKind.Identifier - || kind === SyntaxKind.StringLiteral - || kind === SyntaxKind.NumericLiteral - || kind === SyntaxKind.ComputedPropertyName; - } - - export function isConciseBody(node: Node): node is Expression | Block { - return isBlock(node) - || isExpressionNode(node); - } - - export function isTypeParameter(node: Node): node is TypeParameterDeclaration { - return node.kind === SyntaxKind.TypeParameter; - } - - export function isParameter(node: Node): node is ParameterDeclaration { - return node.kind === SyntaxKind.Parameter; - } - - export function isBindingElement(node: Node): node is BindingElement { - return node.kind === SyntaxKind.BindingElement; - } - - export function isObjectLiteralElement(node: Node): node is ObjectLiteralElement { - const kind = node.kind; - return kind === SyntaxKind.PropertyAssignment - || kind === SyntaxKind.ShorthandPropertyAssignment - || kind === SyntaxKind.MethodDeclaration - || kind === SyntaxKind.GetAccessor - || kind === SyntaxKind.SetAccessor - || kind === SyntaxKind.MissingDeclaration; - } - - export function isTemplate(node: Node): node is LiteralExpression | TemplateExpression { - const kind = node.kind; - return kind === SyntaxKind.TemplateExpression - || kind === SyntaxKind.NoSubstitutionTemplateLiteral; - } - - export function isUnaryExpression(node: Node): node is UnaryExpression { - const kind = node.kind; - return isLeftHandSideExpression(node) - || kind === SyntaxKind.PrefixUnaryExpression - || kind === SyntaxKind.PostfixUnaryExpression - || kind === SyntaxKind.DeleteExpression - || kind === SyntaxKind.TypeOfExpression - || kind === SyntaxKind.VoidExpression - || kind === SyntaxKind.AwaitExpression - || kind === SyntaxKind.TypeAssertionExpression; - } - - export function isTemplateLiteralFragment(node: Node): node is TemplateLiteralFragment { - const kind = node.kind; - return kind === SyntaxKind.TemplateHead - || kind === SyntaxKind.TemplateMiddle - || kind === SyntaxKind.TemplateTail; - } - - export function isTemplateSpan(node: Node): node is TemplateSpan { - return node.kind === SyntaxKind.TemplateSpan; - } - - export function isHeritageClause(node: Node): node is HeritageClause { - return node.kind === SyntaxKind.HeritageClause; - } - - export function isVariableDeclarationList(node: Node): node is VariableDeclarationList { - return node.kind === SyntaxKind.VariableDeclarationList; - } - - export function isExpressionOrVariableDeclarationList(node: Node): node is Expression | VariableDeclarationList { - return isVariableDeclarationList(node) - || isExpressionNode(node); - } - - export function isCaseBlock(node: Node): node is CaseBlock { - return node.kind === SyntaxKind.CaseBlock; - } - - export function isBlock(node: Node): node is Block { - return node.kind === SyntaxKind.Block; - } - - export function isCatchClause(node: Node): node is CatchClause { - return node.kind === SyntaxKind.CatchClause; - } - - export function isVariableDeclaration(node: Node): node is VariableDeclaration { - return node.kind === SyntaxKind.VariableDeclaration; - } - - export function isEnumMember(node: Node): node is EnumMember { - return node.kind === SyntaxKind.EnumMember; - } - - export function isModuleName(node: Node): node is Identifier | LiteralExpression { - return node.kind === SyntaxKind.Identifier - || node.kind === SyntaxKind.StringLiteral; - } - - export function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause { - return node.kind === SyntaxKind.CaseClause - || node.kind === SyntaxKind.DefaultClause; - } - - export function isModuleReference(node: Node): node is EntityName | ExternalModuleReference { - return node.kind === SyntaxKind.ExternalModuleReference - || isEntityName(node); - } - - export function isImportClause(node: Node): node is ImportClause { - return node.kind === SyntaxKind.ImportClause; - } - - export function isNamedImportsOrNamespaceImport(node: Node): node is NamedImports | NamespaceImport { - const kind = node.kind; - return kind === SyntaxKind.NamedImports - || kind === SyntaxKind.NamespaceImport; - } - - export function isImportSpecifier(node: Node): node is ImportSpecifier { - return node.kind === SyntaxKind.ImportSpecifier; - } - - export function isNamedExports(node: Node): node is NamedExports { - return node.kind === SyntaxKind.NamedExports; - } - - export function isExportSpecifier(node: Node): node is ExportSpecifier { - return node.kind === SyntaxKind.ExportSpecifier; - } - - export function isJsxOpeningElement(node: Node): node is JsxOpeningElement { - return node.kind === SyntaxKind.JsxOpeningElement; - } - - export function isJsxClosingElement(node: Node): node is JsxClosingElement { - return node.kind === SyntaxKind.JsxClosingElement; - } - - export function isJsxChild(node: Node): node is JsxChild { - const kind = node.kind; - return kind === SyntaxKind.JsxElement - || kind === SyntaxKind.JsxExpression - || kind === SyntaxKind.JsxSelfClosingElement - || kind === SyntaxKind.JsxText; - } - - export function isJsxAttributeOrJsxSpreadAttribute(node: Node): node is JsxAttribute | JsxSpreadAttribute { - const kind = node.kind; - return kind === SyntaxKind.JsxAttribute - || kind === SyntaxKind.JsxSpreadAttribute; - } - - export function isExpressionWithTypeArguments(node: Node): node is ExpressionWithTypeArguments { - return node.kind === SyntaxKind.ExpressionWithTypeArguments; - } - - export function isModuleBody(node: Node): node is ModuleBody { - const kind = node.kind; - return kind === SyntaxKind.ModuleBlock - || kind === SyntaxKind.ModuleDeclaration; - } - - export function isBindingPatternOrIdentifier(node: Node): node is (BindingPattern | Identifier) { - return isBindingPattern(node) - || isIdentifierNode(node); - } - // Returns false if this heritage clause element's expression contains something unsupported // (i.e. not a name or dotted name). export function isSupportedExpressionWithTypeArguments(node: ExpressionWithTypeArguments): boolean { @@ -2674,14 +2284,6 @@ namespace ts { return false; } - export function isModifiersArray(array: NodeArray): array is ModifiersArray { - return array.arrayKind === ArrayKind.ModifiersArray; - } - - export function isNodeArrayNode(node: Node): node is NodeArrayNode { - return node.kind === SyntaxKind.NodeArrayNode; - } - export function getLocalSymbolForExportDefault(symbol: Symbol) { return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & NodeFlags.Default) ? symbol.valueDeclaration.localSymbol : undefined; } @@ -2835,6 +2437,464 @@ namespace ts { } return carriageReturnLineFeed; } + + // Node tests + // + // All node tests in the following list should *not* reference parent pointers so that + // they may be used with transformations. + + export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression { + return node.kind === SyntaxKind.PropertyAccessExpression; + } + + export function isElementAccessExpression(node: Node): node is ElementAccessExpression { + return node.kind === SyntaxKind.ElementAccessExpression; + } + + function isBindingPatternKind(kind: SyntaxKind) { + return kind === SyntaxKind.ArrayBindingPattern + || kind === SyntaxKind.ObjectBindingPattern; + } + + export function isBindingPattern(node: Node): node is BindingPattern { + return node && isBindingPatternKind(node.kind); + } + + export function isClassElement(node: Node): node is ClassElement { + const kind = node.kind; + return kind === SyntaxKind.Constructor + || kind === SyntaxKind.PropertyDeclaration + || kind === SyntaxKind.MethodDeclaration + || kind === SyntaxKind.GetAccessor + || kind === SyntaxKind.SetAccessor + || kind === SyntaxKind.MethodSignature + || kind === SyntaxKind.IndexSignature; + } + + export function isQualifiedName(node: Node): node is QualifiedName { + return node.kind === SyntaxKind.QualifiedName; + } + + export function isLiteralExpression(node: Node): node is LiteralExpression { + return isLiteralKind(node.kind); + } + + function isEntityNameKind(kind: SyntaxKind) { + return kind === SyntaxKind.QualifiedName + || kind === SyntaxKind.Identifier; + } + + export function isEntityName(node: Node): node is EntityName { + return isEntityNameKind(node.kind); + } + + export function isIdentifier(node: Node): node is Identifier { + return node.kind === SyntaxKind.Identifier; + } + + export function isComputedPropertyName(node: Node): node is ComputedPropertyName { + return node.kind === SyntaxKind.ComputedPropertyName; + } + + export function isBinaryExpression(node: Node): node is BinaryExpression { + return node.kind === SyntaxKind.BinaryExpression; + } + + export function isShortHandPropertyAssignment(node: Node): node is ShorthandPropertyAssignment { + return node.kind === SyntaxKind.ShorthandPropertyAssignment; + } + + function isLeftHandSideExpressionKind(kind: SyntaxKind) { + return kind === SyntaxKind.PropertyAccessExpression + || kind === SyntaxKind.ElementAccessExpression + || kind === SyntaxKind.NewExpression + || kind === SyntaxKind.CallExpression + || kind === SyntaxKind.JsxElement + || kind === SyntaxKind.JsxSelfClosingElement + || kind === SyntaxKind.TaggedTemplateExpression + || kind === SyntaxKind.ArrayLiteralExpression + || kind === SyntaxKind.ParenthesizedExpression + || kind === SyntaxKind.ObjectLiteralExpression + || kind === SyntaxKind.ClassExpression + || kind === SyntaxKind.FunctionExpression + || kind === SyntaxKind.Identifier + || kind === SyntaxKind.RegularExpressionLiteral + || kind === SyntaxKind.NumericLiteral + || kind === SyntaxKind.StringLiteral + || kind === SyntaxKind.NoSubstitutionTemplateLiteral + || kind === SyntaxKind.TemplateExpression + || kind === SyntaxKind.FalseKeyword + || kind === SyntaxKind.NullKeyword + || kind === SyntaxKind.ThisKeyword + || kind === SyntaxKind.TrueKeyword + || kind === SyntaxKind.SuperKeyword; + } + + export function isLeftHandSideExpression(node: Node): node is LeftHandSideExpression { + return isLeftHandSideExpressionKind(node.kind); + } + + function isUnaryExpressionKind(kind: SyntaxKind): boolean { + return kind === SyntaxKind.PrefixUnaryExpression + || kind === SyntaxKind.PostfixUnaryExpression + || kind === SyntaxKind.DeleteExpression + || kind === SyntaxKind.TypeOfExpression + || kind === SyntaxKind.VoidExpression + || kind === SyntaxKind.AwaitExpression + || kind === SyntaxKind.TypeAssertionExpression + || isLeftHandSideExpressionKind(kind); + } + + export function isUnaryExpression(node: Node): node is UnaryExpression { + return isUnaryExpressionKind(node.kind); + } + + function isExpressionKind(kind: SyntaxKind): boolean { + return kind === SyntaxKind.ConditionalExpression + || kind === SyntaxKind.YieldExpression + || kind === SyntaxKind.ArrowFunction + || kind === SyntaxKind.BinaryExpression + || kind === SyntaxKind.SpreadElementExpression + || kind === SyntaxKind.AsExpression + || kind === SyntaxKind.OmittedExpression + || isUnaryExpressionKind(kind); + } + + export function isExpression(node: Node): node is Expression { + return isExpressionKind(node.kind); + } + + export function isDecorator(node: Node): node is Decorator { + return node.kind === SyntaxKind.Decorator; + } + + export function isModifier(node: Node): node is Modifier { + return isModifierKind(node.kind); + } + + function isTypeNodeKind(kind: SyntaxKind) { + return (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) + || kind === SyntaxKind.AnyKeyword + || kind === SyntaxKind.NumberKeyword + || kind === SyntaxKind.BooleanKeyword + || kind === SyntaxKind.StringKeyword + || kind === SyntaxKind.SymbolKeyword + || kind === SyntaxKind.VoidKeyword + || kind === SyntaxKind.ExpressionWithTypeArguments; + } + + /** + * Node test that determines whether a node is a valid type node. + * This differs from the `isPartOfTypeNode` function which determines whether a node is *part* + * of a TypeNode. + */ + export function isTypeNode(node: Node): node is TypeNode { + return isTypeNodeKind(node.kind); + } + + function isDeclarationKind(kind: SyntaxKind) { + return kind === SyntaxKind.ArrowFunction + || kind === SyntaxKind.BindingElement + || kind === SyntaxKind.ClassDeclaration + || kind === SyntaxKind.ClassExpression + || kind === SyntaxKind.Constructor + || kind === SyntaxKind.EnumDeclaration + || kind === SyntaxKind.EnumMember + || kind === SyntaxKind.ExportSpecifier + || kind === SyntaxKind.FunctionDeclaration + || kind === SyntaxKind.FunctionExpression + || kind === SyntaxKind.GetAccessor + || kind === SyntaxKind.ImportClause + || kind === SyntaxKind.ImportEqualsDeclaration + || kind === SyntaxKind.ImportSpecifier + || kind === SyntaxKind.InterfaceDeclaration + || kind === SyntaxKind.MethodDeclaration + || kind === SyntaxKind.MethodSignature + || kind === SyntaxKind.ModuleDeclaration + || kind === SyntaxKind.NamespaceImport + || kind === SyntaxKind.Parameter + || kind === SyntaxKind.PropertyAssignment + || kind === SyntaxKind.PropertyDeclaration + || kind === SyntaxKind.PropertySignature + || kind === SyntaxKind.SetAccessor + || kind === SyntaxKind.ShorthandPropertyAssignment + || kind === SyntaxKind.TypeAliasDeclaration + || kind === SyntaxKind.TypeParameter + || kind === SyntaxKind.VariableDeclaration; + } + + export function isDeclaration(node: Node): node is Declaration { + return isDeclarationKind(node.kind); + } + + function isDeclarationStatementKind(kind: SyntaxKind) { + return kind === SyntaxKind.FunctionDeclaration + || kind === SyntaxKind.MissingDeclaration + || kind === SyntaxKind.ClassDeclaration + || kind === SyntaxKind.InterfaceDeclaration + || kind === SyntaxKind.TypeAliasDeclaration + || kind === SyntaxKind.EnumDeclaration + || kind === SyntaxKind.ModuleDeclaration + || kind === SyntaxKind.ImportEqualsDeclaration + || kind === SyntaxKind.ExportDeclaration + || kind === SyntaxKind.ExportAssignment; + } + + export function isDeclarationStatement(node: Node): node is DeclarationStatement { + return isDeclarationStatementKind(node.kind); + } + + function isStatementKindButNotDeclarationKind(kind: SyntaxKind) { + return kind === SyntaxKind.BreakStatement + || kind === SyntaxKind.ContinueStatement + || kind === SyntaxKind.DebuggerStatement + || kind === SyntaxKind.DoStatement + || kind === SyntaxKind.ExpressionStatement + || kind === SyntaxKind.EmptyStatement + || kind === SyntaxKind.ForInStatement + || kind === SyntaxKind.ForOfStatement + || kind === SyntaxKind.ForStatement + || kind === SyntaxKind.IfStatement + || kind === SyntaxKind.LabeledStatement + || kind === SyntaxKind.ReturnStatement + || kind === SyntaxKind.SwitchStatement + || kind === SyntaxKind.ThrowStatement + || kind === SyntaxKind.TryStatement + || kind === SyntaxKind.VariableStatement + || kind === SyntaxKind.WhileStatement + || kind === SyntaxKind.WithStatement; + } + + /** + * Determines whether the node is a statement that is not also a declaration + */ + export function isStatementButNotDeclaration(node: Node): node is Statement { + return isStatementKindButNotDeclarationKind(node.kind); + } + + function isStatementKind(kind: SyntaxKind) { + return isStatementKindButNotDeclarationKind(kind) + || isDeclarationStatementKind(kind); + } + + export function isStatement(node: Node): node is Statement { + return isStatementKind(node.kind); + } + + function isPropertyNameKind(kind: SyntaxKind) { + return kind === SyntaxKind.Identifier + || kind === SyntaxKind.StringLiteral + || kind === SyntaxKind.NumericLiteral + || kind === SyntaxKind.ComputedPropertyName; + } + + export function isPropertyName(node: Node): node is PropertyName { + return isPropertyNameKind(node.kind); + } + + function isConciseBodyKind(kind: SyntaxKind) { + return kind === SyntaxKind.Block + || isExpressionKind(kind); + } + + export function isConciseBody(node: Node): node is ConciseBody { + return isConciseBodyKind(node.kind); + } + + export function isTypeParameter(node: Node): node is TypeParameterDeclaration { + return node.kind === SyntaxKind.TypeParameter; + } + + export function isParameter(node: Node): node is ParameterDeclaration { + return node.kind === SyntaxKind.Parameter; + } + + export function isBindingElement(node: Node): node is BindingElement { + return node.kind === SyntaxKind.BindingElement; + } + + function isObjectLiteralElementKind(kind: SyntaxKind) { + return kind === SyntaxKind.PropertyAssignment + || kind === SyntaxKind.ShorthandPropertyAssignment + || kind === SyntaxKind.MethodDeclaration + || kind === SyntaxKind.GetAccessor + || kind === SyntaxKind.SetAccessor + || kind === SyntaxKind.MissingDeclaration; + } + + export function isObjectLiteralElement(node: Node): node is ObjectLiteralElement { + return isObjectLiteralElementKind(node.kind); + } + + function isTemplateKind(kind: SyntaxKind) { + return kind === SyntaxKind.TemplateExpression + || kind === SyntaxKind.NoSubstitutionTemplateLiteral; + } + + export function isTemplate(node: Node): node is Template { + return isTemplateKind(node.kind); + } + + function isTemplateLiteralFragmentKind(kind: SyntaxKind) { + return kind === SyntaxKind.TemplateHead + || kind === SyntaxKind.TemplateMiddle + || kind === SyntaxKind.TemplateTail; + } + + export function isTemplateLiteralFragment(node: Node): node is TemplateLiteralFragment { + return isTemplateLiteralFragmentKind(node.kind); + } + + export function isTemplateSpan(node: Node): node is TemplateSpan { + return node.kind === SyntaxKind.TemplateSpan; + } + + export function isHeritageClause(node: Node): node is HeritageClause { + return node.kind === SyntaxKind.HeritageClause; + } + + export function isVariableDeclarationList(node: Node): node is VariableDeclarationList { + return node.kind === SyntaxKind.VariableDeclarationList; + } + + function isForInitializerKind(kind: SyntaxKind) { + return kind === SyntaxKind.VariableDeclarationList + || isExpressionKind(kind); + } + + export function isForInitializer(node: Node): node is ForInitializer { + return isForInitializerKind(node.kind); + } + + export function isCaseBlock(node: Node): node is CaseBlock { + return node.kind === SyntaxKind.CaseBlock; + } + + export function isBlock(node: Node): node is Block { + return node.kind === SyntaxKind.Block; + } + + export function isCatchClause(node: Node): node is CatchClause { + return node.kind === SyntaxKind.CatchClause; + } + + export function isVariableDeclaration(node: Node): node is VariableDeclaration { + return node.kind === SyntaxKind.VariableDeclaration; + } + + export function isEnumMember(node: Node): node is EnumMember { + return node.kind === SyntaxKind.EnumMember; + } + + function isModuleNameKind(kind: SyntaxKind) { + return kind === SyntaxKind.Identifier + || kind === SyntaxKind.StringLiteral; + } + + export function isModuleName(node: Node): node is ModuleName { + return isModuleNameKind(node.kind); + } + + function isCaseOrDefaultClauseKind(kind: SyntaxKind) { + return kind === SyntaxKind.CaseClause + || kind === SyntaxKind.DefaultClause; + } + + export function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause { + return isCaseOrDefaultClauseKind(node.kind); + } + + function isModuleReferenceKind(kind: SyntaxKind) { + return kind === SyntaxKind.ExternalModuleReference + || isEntityNameKind(kind); + } + + export function isModuleReference(node: Node): node is ModuleReference { + return isModuleReferenceKind(node.kind); + } + + export function isImportClause(node: Node): node is ImportClause { + return node.kind === SyntaxKind.ImportClause; + } + + function isNamedImportBindingsKind(kind: SyntaxKind) { + return kind === SyntaxKind.NamedImports + || kind === SyntaxKind.NamespaceImport; + } + + export function isNamedImportBindings(node: Node): node is NamedImportBindings { + return isNamedImportBindingsKind(node.kind); + } + + export function isImportSpecifier(node: Node): node is ImportSpecifier { + return node.kind === SyntaxKind.ImportSpecifier; + } + + export function isNamedExports(node: Node): node is NamedExports { + return node.kind === SyntaxKind.NamedExports; + } + + export function isExportSpecifier(node: Node): node is ExportSpecifier { + return node.kind === SyntaxKind.ExportSpecifier; + } + + export function isJsxOpeningElement(node: Node): node is JsxOpeningElement { + return node.kind === SyntaxKind.JsxOpeningElement; + } + + export function isJsxClosingElement(node: Node): node is JsxClosingElement { + return node.kind === SyntaxKind.JsxClosingElement; + } + + function isJsxChildKind(kind: SyntaxKind) { + return kind === SyntaxKind.JsxElement + || kind === SyntaxKind.JsxExpression + || kind === SyntaxKind.JsxSelfClosingElement + || kind === SyntaxKind.JsxText; + } + + export function isJsxChild(node: Node): node is JsxChild { + return isJsxChildKind(node.kind); + } + + function isJsxAttributeLikeKind(kind: SyntaxKind) { + return kind === SyntaxKind.JsxAttribute + || kind === SyntaxKind.JsxSpreadAttribute; + } + + export function isJsxAttributeLike(node: Node): node is JsxAttributeLike { + return isJsxAttributeLikeKind(node.kind); + } + + export function isExpressionWithTypeArguments(node: Node): node is ExpressionWithTypeArguments { + return node.kind === SyntaxKind.ExpressionWithTypeArguments; + } + + function isModuleBodyKind(kind: SyntaxKind) { + return kind === SyntaxKind.ModuleBlock + || kind === SyntaxKind.ModuleDeclaration; + } + + export function isModuleBody(node: Node): node is ModuleBody { + return isModuleBodyKind(node.kind); + } + + function isBindingNameKind(kind: SyntaxKind) { + return kind === SyntaxKind.Identifier + || isBindingPatternKind(kind); + } + + export function isBindingName(node: Node): node is BindingName { + return isBindingNameKind(node.kind); + } + + export function isNodeArrayNode(node: Node): node is NodeArrayNode { + return node.kind === SyntaxKind.NodeArrayNode; + } + + export function isModifiersArray(array: NodeArray): array is ModifiersArray { + return array.arrayKind === ArrayKind.ModifiersArray; + } } namespace ts { diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index a75e79565c5..12829a540e5 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -15,6 +15,9 @@ namespace ts { * Describes an edge of a Node, used when traversing a syntax tree. */ interface NodeEdge { + /** The property name for the edge. */ + name: string; + /** Indicates that the result is optional. */ optional?: boolean; @@ -28,7 +31,7 @@ namespace ts { /** * Describes the shape of a Node. */ - type NodeTraversalPath = Map; + type NodeTraversalPath = NodeEdge[]; /** * This map contains information about the shape of each Node in "types.ts" pertaining to how @@ -44,399 +47,399 @@ namespace ts { * significantly impacted. */ const nodeEdgeTraversalMap: Map = { - [SyntaxKind.QualifiedName]: { - left: { test: isEntityName }, - right: { test: isIdentifierNode }, - }, - [SyntaxKind.ComputedPropertyName]: { - expression: { test: isExpressionNode }, - }, - [SyntaxKind.Parameter]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isBindingPatternOrIdentifier }, - type: { test: isTypeNodeNode, optional: true }, - initializer: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.Decorator]: { - expression: { test: isLeftHandSideExpression }, - }, - [SyntaxKind.PropertyDeclaration]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isPropertyName }, - type: { test: isTypeNodeNode, optional: true }, - initializer: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.MethodDeclaration]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isPropertyName }, - typeParameters: { test: isTypeParameter }, - parameters: { test: isParameter }, - type: { test: isTypeNodeNode, optional: true }, - body: { test: isBlock, optional: true }, - }, - [SyntaxKind.Constructor]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - typeParameters: { test: isTypeParameter }, - parameters: { test: isParameter }, - type: { test: isTypeNodeNode, optional: true }, - body: { test: isBlock, optional: true }, - }, - [SyntaxKind.GetAccessor]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isPropertyName }, - typeParameters: { test: isTypeParameter }, - parameters: { test: isParameter }, - type: { test: isTypeNodeNode, optional: true }, - body: { test: isBlock, optional: true }, - }, - [SyntaxKind.SetAccessor]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isPropertyName }, - typeParameters: { test: isTypeParameter }, - parameters: { test: isParameter }, - type: { test: isTypeNodeNode, optional: true }, - body: { test: isBlock, optional: true }, - }, - [SyntaxKind.ObjectBindingPattern]: { - elements: { test: isBindingElement }, - }, - [SyntaxKind.ArrayBindingPattern]: { - elements: { test: isBindingElement }, - }, - [SyntaxKind.BindingElement]: { - propertyName: { test: isPropertyName, optional: true }, - name: { test: isBindingPatternOrIdentifier }, - initializer: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.ArrayLiteralExpression]: { - elements: { test: isExpressionNode }, - }, - [SyntaxKind.ObjectLiteralExpression]: { - properties: { test: isObjectLiteralElement }, - }, - [SyntaxKind.PropertyAccessExpression]: { - expression: { test: isLeftHandSideExpression }, - name: { test: isIdentifierNode }, - }, - [SyntaxKind.ElementAccessExpression]: { - expression: { test: isLeftHandSideExpression }, - argumentExpression: { test: isExpressionNode }, - }, - [SyntaxKind.CallExpression]: { - expression: { test: isLeftHandSideExpression }, - typeArguments: { test: isTypeNodeNode }, - arguments: { test: isExpressionNode }, - }, - [SyntaxKind.NewExpression]: { - expression: { test: isLeftHandSideExpression }, - typeArguments: { test: isTypeNodeNode }, - arguments: { test: isExpressionNode }, - }, - [SyntaxKind.TaggedTemplateExpression]: { - tag: { test: isLeftHandSideExpression }, - template: { test: isTemplate }, - }, - [SyntaxKind.TypeAssertionExpression]: { - type: { test: isTypeNodeNode }, - expression: { test: isUnaryExpression }, - }, - [SyntaxKind.ParenthesizedExpression]: { - expression: { test: isExpressionNode }, - }, - [SyntaxKind.FunctionExpression]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isIdentifierNode, optional: true }, - typeParameters: { test: isTypeParameter }, - parameters: { test: isParameter }, - type: { test: isTypeNodeNode, optional: true }, - body: { test: isBlock, optional: true }, - }, - [SyntaxKind.ArrowFunction]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - typeParameters: { test: isTypeParameter }, - parameters: { test: isParameter }, - type: { test: isTypeNodeNode, optional: true }, - body: { test: isConciseBody, lift: liftToBlock }, - }, - [SyntaxKind.DeleteExpression]: { - expression: { test: isUnaryExpression }, - }, - [SyntaxKind.TypeOfExpression]: { - expression: { test: isUnaryExpression }, - }, - [SyntaxKind.VoidExpression]: { - expression: { test: isUnaryExpression }, - }, - [SyntaxKind.AwaitExpression]: { - expression: { test: isUnaryExpression }, - }, - [SyntaxKind.PrefixUnaryExpression]: { - operand: { test: isUnaryExpression }, - }, - [SyntaxKind.PostfixUnaryExpression]: { - operand: { test: isLeftHandSideExpression }, - }, - [SyntaxKind.BinaryExpression]: { - left: { test: isExpressionNode }, - right: { test: isExpressionNode }, - }, - [SyntaxKind.ConditionalExpression]: { - condition: { test: isExpressionNode }, - whenTrue: { test: isExpressionNode }, - whenFalse: { test: isExpressionNode }, - }, - [SyntaxKind.TemplateExpression]: { - head: { test: isTemplateLiteralFragment }, - templateSpans: { test: isTemplateSpan }, - }, - [SyntaxKind.YieldExpression]: { - expression: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.SpreadElementExpression]: { - expression: { test: isExpressionNode }, - }, - [SyntaxKind.ClassExpression]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isIdentifierNode, optional: true }, - typeParameters: { test: isTypeParameter }, - heritageClauses: { test: isHeritageClause }, - members: { test: isClassElement }, - }, - [SyntaxKind.ExpressionWithTypeArguments]: { - expression: { test: isLeftHandSideExpression }, - typeArguments: { test: isTypeNodeNode }, - }, - [SyntaxKind.AsExpression]: { - expression: { test: isExpressionNode }, - type: { test: isTypeNodeNode }, - }, - [SyntaxKind.TemplateSpan]: { - expression: { test: isExpressionNode }, - literal: { test: isTemplateLiteralFragment }, - }, - [SyntaxKind.Block]: { - statements: { test: isStatementNode }, - }, - [SyntaxKind.VariableStatement]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - declarationList: { test: isVariableDeclarationList }, - }, - [SyntaxKind.ExpressionStatement]: { - expression: { test: isExpressionNode }, - }, - [SyntaxKind.IfStatement]: { - expression: { test: isExpressionNode }, - thenStatement: { test: isStatementNode, lift: liftToBlock }, - elseStatement: { test: isStatementNode, lift: liftToBlock, optional: true}, - }, - [SyntaxKind.DoStatement]: { - statement: { test: isStatementNode, lift: liftToBlock }, - expression: { test: isExpressionNode }, - }, - [SyntaxKind.WhileStatement]: { - expression: { test: isExpressionNode }, - statement: { test: isStatementNode, lift: liftToBlock }, - }, - [SyntaxKind.ForStatement]: { - initializer: { test: isExpressionOrVariableDeclarationList, optional: true }, - condition: { test: isExpressionNode, optional: true }, - incrementor: { test: isExpressionNode, optional: true }, - statement: { test: isStatementNode, lift: liftToBlock }, - }, - [SyntaxKind.ForInStatement]: { - initializer: { test: isExpressionOrVariableDeclarationList }, - expression: { test: isExpressionNode }, - statement: { test: isStatementNode, lift: liftToBlock }, - }, - [SyntaxKind.ForOfStatement]: { - initializer: { test: isExpressionOrVariableDeclarationList }, - expression: { test: isExpressionNode }, - statement: { test: isStatementNode, lift: liftToBlock }, - }, - [SyntaxKind.ContinueStatement]: { - label: { test: isIdentifierNode, optional: true }, - }, - [SyntaxKind.BreakStatement]: { - label: { test: isIdentifierNode, optional: true }, - }, - [SyntaxKind.ReturnStatement]: { - expression: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.WithStatement]: { - expression: { test: isExpressionNode }, - statement: { test: isStatementNode, lift: liftToBlock }, - }, - [SyntaxKind.SwitchStatement]: { - expression: { test: isExpressionNode }, - caseBlock: { test: isCaseBlock }, - }, - [SyntaxKind.LabeledStatement]: { - label: { test: isIdentifierNode }, - statement: { test: isStatementNode, lift: liftToBlock }, - }, - [SyntaxKind.ThrowStatement]: { - expression: { test: isExpressionNode }, - }, - [SyntaxKind.TryStatement]: { - tryBlock: { test: isBlock }, - catchClause: { test: isCatchClause, optional: true }, - finallyBlock: { test: isBlock, optional: true }, - }, - [SyntaxKind.VariableDeclaration]: { - name: { test: isBindingPatternOrIdentifier }, - type: { test: isTypeNodeNode, optional: true }, - initializer: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.VariableDeclarationList]: { - declarations: { test: isVariableDeclaration }, - }, - [SyntaxKind.FunctionDeclaration]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isIdentifierNode, optional: true }, - typeParameters: { test: isTypeParameter }, - parameters: { test: isParameter }, - type: { test: isTypeNodeNode, optional: true }, - body: { test: isBlock, optional: true }, - }, - [SyntaxKind.ClassDeclaration]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isIdentifierNode, optional: true }, - typeParameters: { test: isTypeParameter }, - heritageClauses: { test: isHeritageClause }, - members: { test: isClassElement }, - }, - [SyntaxKind.EnumDeclaration]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isIdentifierNode }, - members: { test: isEnumMember }, - }, - [SyntaxKind.ModuleDeclaration]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isModuleName }, - body: { test: isModuleBody }, - }, - [SyntaxKind.ModuleBlock]: { - statements: { test: isStatementNode }, - }, - [SyntaxKind.CaseBlock]: { - clauses: { test: isCaseOrDefaultClause }, - }, - [SyntaxKind.ImportEqualsDeclaration]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - name: { test: isIdentifierNode }, - moduleReference: { test: isModuleReference }, - }, - [SyntaxKind.ImportDeclaration]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - importClause: { test: isImportClause, optional: true }, - moduleSpecifier: { test: isExpressionNode }, - }, - [SyntaxKind.ImportClause]: { - name: { test: isIdentifierNode, optional: true }, - namedBindings: { test: isNamedImportsOrNamespaceImport, optional: true }, - }, - [SyntaxKind.NamespaceImport]: { - name: { test: isIdentifierNode }, - }, - [SyntaxKind.NamedImports]: { - elements: { test: isImportSpecifier }, - }, - [SyntaxKind.ImportSpecifier]: { - propertyName: { test: isIdentifierNode, optional: true }, - name: { test: isIdentifierNode }, - }, - [SyntaxKind.ExportAssignment]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - expression: { test: isExpressionNode }, - }, - [SyntaxKind.ExportDeclaration]: { - decorators: { test: isDecorator }, - modifiers: { test: isModifier }, - exportClause: { test: isNamedExports, optional: true }, - moduleSpecifier: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.NamedExports]: { - elements: { test: isExportSpecifier }, - }, - [SyntaxKind.ExportSpecifier]: { - propertyName: { test: isIdentifierNode, optional: true }, - name: { test: isIdentifierNode }, - }, - [SyntaxKind.ExternalModuleReference]: { - expression: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.JsxElement]: { - openingElement: { test: isJsxOpeningElement }, - children: { test: isJsxChild }, - closingElement: { test: isJsxClosingElement }, - }, - [SyntaxKind.JsxSelfClosingElement]: { - tagName: { test: isEntityName }, - attributes: { test: isJsxAttributeOrJsxSpreadAttribute }, - }, - [SyntaxKind.JsxOpeningElement]: { - tagName: { test: isEntityName }, - attributes: { test: isJsxAttributeOrJsxSpreadAttribute }, - }, - [SyntaxKind.JsxClosingElement]: { - tagName: { test: isEntityName }, - }, - [SyntaxKind.JsxAttribute]: { - name: { test: isIdentifierNode }, - initializer: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.JsxSpreadAttribute]: { - expression: { test: isExpressionNode }, - }, - [SyntaxKind.JsxExpression]: { - expression: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.CaseClause]: { - expression: { test: isExpressionNode }, - statements: { test: isStatementNode }, - }, - [SyntaxKind.DefaultClause]: { - statements: { test: isStatementNode }, - }, - [SyntaxKind.HeritageClause]: { - types: { test: isExpressionWithTypeArguments }, - }, - [SyntaxKind.CatchClause]: { - variableDeclaration: { test: isVariableDeclaration }, - block: { test: isBlock }, - }, - [SyntaxKind.PropertyAssignment]: { - name: { test: isPropertyName }, - initializer: { test: isExpressionNode }, - }, - [SyntaxKind.ShorthandPropertyAssignment]: { - name: { test: isIdentifierNode }, - objectAssignmentInitializer: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.EnumMember]: { - name: { test: isPropertyName }, - initializer: { test: isExpressionNode, optional: true }, - }, - [SyntaxKind.SourceFile]: { - statements: { test: isStatementNode }, - }, + [SyntaxKind.QualifiedName]: [ + { name: "left", test: isEntityName }, + { name: "right", test: isIdentifier }, + ], + [SyntaxKind.ComputedPropertyName]: [ + { name: "expression", test: isExpression }, + ], + [SyntaxKind.Parameter]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isBindingName }, + { name: "type", test: isTypeNode, optional: true }, + { name: "initializer", test: isExpression, optional: true }, + ], + [SyntaxKind.Decorator]: [ + { name: "expression", test: isLeftHandSideExpression }, + ], + [SyntaxKind.PropertyDeclaration]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isPropertyName }, + { name: "type", test: isTypeNode, optional: true }, + { name: "initializer", test: isExpression, optional: true }, + ], + [SyntaxKind.MethodDeclaration]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isPropertyName }, + { name: "typeParameters", test: isTypeParameter }, + { name: "parameters", test: isParameter }, + { name: "type", test: isTypeNode, optional: true }, + { name: "body", test: isBlock, optional: true }, + ], + [SyntaxKind.Constructor]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "typeParameters", test: isTypeParameter }, + { name: "parameters", test: isParameter }, + { name: "type", test: isTypeNode, optional: true }, + { name: "body", test: isBlock, optional: true }, + ], + [SyntaxKind.GetAccessor]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isPropertyName }, + { name: "typeParameters", test: isTypeParameter }, + { name: "parameters", test: isParameter }, + { name: "type", test: isTypeNode, optional: true }, + { name: "body", test: isBlock, optional: true }, + ], + [SyntaxKind.SetAccessor]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isPropertyName }, + { name: "typeParameters", test: isTypeParameter }, + { name: "parameters", test: isParameter }, + { name: "type", test: isTypeNode, optional: true }, + { name: "body", test: isBlock, optional: true }, + ], + [SyntaxKind.ObjectBindingPattern]: [ + { name: "elements", test: isBindingElement }, + ], + [SyntaxKind.ArrayBindingPattern]: [ + { name: "elements", test: isBindingElement }, + ], + [SyntaxKind.BindingElement]: [ + { name: "propertyName", test: isPropertyName, optional: true }, + { name: "name", test: isBindingName }, + { name: "initializer", test: isExpression, optional: true }, + ], + [SyntaxKind.ArrayLiteralExpression]: [ + { name: "elements", test: isExpression }, + ], + [SyntaxKind.ObjectLiteralExpression]: [ + { name: "properties", test: isObjectLiteralElement }, + ], + [SyntaxKind.PropertyAccessExpression]: [ + { name: "expression", test: isLeftHandSideExpression }, + { name: "name", test: isIdentifier }, + ], + [SyntaxKind.ElementAccessExpression]: [ + { name: "expression", test: isLeftHandSideExpression }, + { name: "argumentExpression", test: isExpression }, + ], + [SyntaxKind.CallExpression]: [ + { name: "expression", test: isLeftHandSideExpression }, + { name: "typeArguments", test: isTypeNode }, + { name: "arguments", test: isExpression }, + ], + [SyntaxKind.NewExpression]: [ + { name: "expression", test: isLeftHandSideExpression }, + { name: "typeArguments", test: isTypeNode }, + { name: "arguments", test: isExpression }, + ], + [SyntaxKind.TaggedTemplateExpression]: [ + { name: "tag", test: isLeftHandSideExpression }, + { name: "template", test: isTemplate }, + ], + [SyntaxKind.TypeAssertionExpression]: [ + { name: "type", test: isTypeNode }, + { name: "expression", test: isUnaryExpression }, + ], + [SyntaxKind.ParenthesizedExpression]: [ + { name: "expression", test: isExpression }, + ], + [SyntaxKind.FunctionExpression]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isIdentifier, optional: true }, + { name: "typeParameters", test: isTypeParameter }, + { name: "parameters", test: isParameter }, + { name: "type", test: isTypeNode, optional: true }, + { name: "body", test: isBlock, optional: true }, + ], + [SyntaxKind.ArrowFunction]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "typeParameters", test: isTypeParameter }, + { name: "parameters", test: isParameter }, + { name: "type", test: isTypeNode, optional: true }, + { name: "body", test: isConciseBody, lift: liftToBlock }, + ], + [SyntaxKind.DeleteExpression]: [ + { name: "expression", test: isUnaryExpression }, + ], + [SyntaxKind.TypeOfExpression]: [ + { name: "expression", test: isUnaryExpression }, + ], + [SyntaxKind.VoidExpression]: [ + { name: "expression", test: isUnaryExpression }, + ], + [SyntaxKind.AwaitExpression]: [ + { name: "expression", test: isUnaryExpression }, + ], + [SyntaxKind.PrefixUnaryExpression]: [ + { name: "operand", test: isUnaryExpression }, + ], + [SyntaxKind.PostfixUnaryExpression]: [ + { name: "operand", test: isLeftHandSideExpression }, + ], + [SyntaxKind.BinaryExpression]: [ + { name: "left", test: isExpression }, + { name: "right", test: isExpression }, + ], + [SyntaxKind.ConditionalExpression]: [ + { name: "condition", test: isExpression }, + { name: "whenTrue", test: isExpression }, + { name: "whenFalse", test: isExpression }, + ], + [SyntaxKind.TemplateExpression]: [ + { name: "head", test: isTemplateLiteralFragment }, + { name: "templateSpans", test: isTemplateSpan }, + ], + [SyntaxKind.YieldExpression]: [ + { name: "expression", test: isExpression, optional: true }, + ], + [SyntaxKind.SpreadElementExpression]: [ + { name: "expression", test: isExpression }, + ], + [SyntaxKind.ClassExpression]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isIdentifier, optional: true }, + { name: "typeParameters", test: isTypeParameter }, + { name: "heritageClauses", test: isHeritageClause }, + { name: "members", test: isClassElement }, + ], + [SyntaxKind.ExpressionWithTypeArguments]: [ + { name: "expression", test: isLeftHandSideExpression }, + { name: "typeArguments", test: isTypeNode }, + ], + [SyntaxKind.AsExpression]: [ + { name: "expression", test: isExpression }, + { name: "type", test: isTypeNode }, + ], + [SyntaxKind.TemplateSpan]: [ + { name: "expression", test: isExpression }, + { name: "literal", test: isTemplateLiteralFragment }, + ], + [SyntaxKind.Block]: [ + { name: "statements", test: isStatement }, + ], + [SyntaxKind.VariableStatement]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "declarationList", test: isVariableDeclarationList }, + ], + [SyntaxKind.ExpressionStatement]: [ + { name: "expression", test: isExpression }, + ], + [SyntaxKind.IfStatement]: [ + { name: "expression", test: isExpression }, + { name: "thenStatement", test: isStatement, lift: liftToBlock }, + { name: "elseStatement", test: isStatement, lift: liftToBlock, optional: true }, + ], + [SyntaxKind.DoStatement]: [ + { name: "statement", test: isStatement, lift: liftToBlock }, + { name: "expression", test: isExpression }, + ], + [SyntaxKind.WhileStatement]: [ + { name: "expression", test: isExpression }, + { name: "statement", test: isStatement, lift: liftToBlock }, + ], + [SyntaxKind.ForStatement]: [ + { name: "initializer", test: isForInitializer, optional: true }, + { name: "condition", test: isExpression, optional: true }, + { name: "incrementor", test: isExpression, optional: true }, + { name: "statement", test: isStatement, lift: liftToBlock }, + ], + [SyntaxKind.ForInStatement]: [ + { name: "initializer", test: isForInitializer }, + { name: "expression", test: isExpression }, + { name: "statement", test: isStatement, lift: liftToBlock }, + ], + [SyntaxKind.ForOfStatement]: [ + { name: "initializer", test: isForInitializer }, + { name: "expression", test: isExpression }, + { name: "statement", test: isStatement, lift: liftToBlock }, + ], + [SyntaxKind.ContinueStatement]: [ + { name: "label", test: isIdentifier, optional: true }, + ], + [SyntaxKind.BreakStatement]: [ + { name: "label", test: isIdentifier, optional: true }, + ], + [SyntaxKind.ReturnStatement]: [ + { name: "expression", test: isExpression, optional: true }, + ], + [SyntaxKind.WithStatement]: [ + { name: "expression", test: isExpression }, + { name: "statement", test: isStatement, lift: liftToBlock }, + ], + [SyntaxKind.SwitchStatement]: [ + { name: "expression", test: isExpression }, + { name: "caseBlock", test: isCaseBlock }, + ], + [SyntaxKind.LabeledStatement]: [ + { name: "label", test: isIdentifier }, + { name: "statement", test: isStatement, lift: liftToBlock }, + ], + [SyntaxKind.ThrowStatement]: [ + { name: "expression", test: isExpression }, + ], + [SyntaxKind.TryStatement]: [ + { name: "tryBlock", test: isBlock }, + { name: "catchClause", test: isCatchClause, optional: true }, + { name: "finallyBlock", test: isBlock, optional: true }, + ], + [SyntaxKind.VariableDeclaration]: [ + { name: "name", test: isBindingName }, + { name: "type", test: isTypeNode, optional: true }, + { name: "initializer", test: isExpression, optional: true }, + ], + [SyntaxKind.VariableDeclarationList]: [ + { name: "declarations", test: isVariableDeclaration }, + ], + [SyntaxKind.FunctionDeclaration]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isIdentifier, optional: true }, + { name: "typeParameters", test: isTypeParameter }, + { name: "parameters", test: isParameter }, + { name: "type", test: isTypeNode, optional: true }, + { name: "body", test: isBlock, optional: true }, + ], + [SyntaxKind.ClassDeclaration]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isIdentifier, optional: true }, + { name: "typeParameters", test: isTypeParameter }, + { name: "heritageClauses", test: isHeritageClause }, + { name: "members", test: isClassElement }, + ], + [SyntaxKind.EnumDeclaration]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isIdentifier }, + { name: "members", test: isEnumMember }, + ], + [SyntaxKind.ModuleDeclaration]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isModuleName }, + { name: "body", test: isModuleBody }, + ], + [SyntaxKind.ModuleBlock]: [ + { name: "statements", test: isStatement }, + ], + [SyntaxKind.CaseBlock]: [ + { name: "clauses", test: isCaseOrDefaultClause }, + ], + [SyntaxKind.ImportEqualsDeclaration]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "name", test: isIdentifier }, + { name: "moduleReference", test: isModuleReference }, + ], + [SyntaxKind.ImportDeclaration]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "importClause", test: isImportClause, optional: true }, + { name: "moduleSpecifier", test: isExpression }, + ], + [SyntaxKind.ImportClause]: [ + { name: "name", test: isIdentifier, optional: true }, + { name: "namedBindings", test: isNamedImportBindings, optional: true }, + ], + [SyntaxKind.NamespaceImport]: [ + { name: "name", test: isIdentifier }, + ], + [SyntaxKind.NamedImports]: [ + { name: "elements", test: isImportSpecifier }, + ], + [SyntaxKind.ImportSpecifier]: [ + { name: "propertyName", test: isIdentifier, optional: true }, + { name: "name", test: isIdentifier }, + ], + [SyntaxKind.ExportAssignment]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "expression", test: isExpression }, + ], + [SyntaxKind.ExportDeclaration]: [ + { name: "decorators", test: isDecorator }, + { name: "modifiers", test: isModifier }, + { name: "exportClause", test: isNamedExports, optional: true }, + { name: "moduleSpecifier", test: isExpression, optional: true }, + ], + [SyntaxKind.NamedExports]: [ + { name: "elements", test: isExportSpecifier }, + ], + [SyntaxKind.ExportSpecifier]: [ + { name: "propertyName", test: isIdentifier, optional: true }, + { name: "name", test: isIdentifier }, + ], + [SyntaxKind.ExternalModuleReference]: [ + { name: "expression", test: isExpression, optional: true }, + ], + [SyntaxKind.JsxElement]: [ + { name: "openingElement", test: isJsxOpeningElement }, + { name: "children", test: isJsxChild }, + { name: "closingElement", test: isJsxClosingElement }, + ], + [SyntaxKind.JsxSelfClosingElement]: [ + { name: "tagName", test: isEntityName }, + { name: "attributes", test: isJsxAttributeLike }, + ], + [SyntaxKind.JsxOpeningElement]: [ + { name: "tagName", test: isEntityName }, + { name: "attributes", test: isJsxAttributeLike }, + ], + [SyntaxKind.JsxClosingElement]: [ + { name: "tagName", test: isEntityName }, + ], + [SyntaxKind.JsxAttribute]: [ + { name: "name", test: isIdentifier }, + { name: "initializer", test: isExpression, optional: true }, + ], + [SyntaxKind.JsxSpreadAttribute]: [ + { name: "expression", test: isExpression }, + ], + [SyntaxKind.JsxExpression]: [ + { name: "expression", test: isExpression, optional: true }, + ], + [SyntaxKind.CaseClause]: [ + { name: "expression", test: isExpression }, + { name: "statements", test: isStatement }, + ], + [SyntaxKind.DefaultClause]: [ + { name: "statements", test: isStatement }, + ], + [SyntaxKind.HeritageClause]: [ + { name: "types", test: isExpressionWithTypeArguments }, + ], + [SyntaxKind.CatchClause]: [ + { name: "variableDeclaration", test: isVariableDeclaration }, + { name: "block", test: isBlock }, + ], + [SyntaxKind.PropertyAssignment]: [ + { name: "name", test: isPropertyName }, + { name: "initializer", test: isExpression }, + ], + [SyntaxKind.ShorthandPropertyAssignment]: [ + { name: "name", test: isIdentifier }, + { name: "objectAssignmentInitializer", test: isExpression, optional: true }, + ], + [SyntaxKind.EnumMember]: [ + { name: "name", test: isPropertyName }, + { name: "initializer", test: isExpression, optional: true }, + ], + [SyntaxKind.SourceFile]: [ + { name: "statements", test: isStatement }, + ], }; /** @@ -456,8 +459,8 @@ namespace ts { let result = initial; const edgeTraversalPath = nodeEdgeTraversalMap[node.kind]; if (edgeTraversalPath) { - for (const propertyName in edgeTraversalPath) { - const value = (>node)[propertyName]; + for (const edge of edgeTraversalPath) { + const value = (>node)[edge.name]; if (value !== undefined) { result = isArray(value) ? reduceLeft(>value, f, result) @@ -568,24 +571,24 @@ namespace ts { environment.startLexicalEnvironment(); } + let modifiers: NodeFlags; let updated: T & Map; const edgeTraversalPath = nodeEdgeTraversalMap[node.kind]; if (edgeTraversalPath) { - for (const propertyName in edgeTraversalPath) { - const value = (>node)[propertyName]; + for (const edge of edgeTraversalPath) { + const value = (>node)[edge.name]; if (value !== undefined) { - const edge = edgeTraversalPath[propertyName]; const visited = visitEdge(edge, value, visitor); if (updated !== undefined || visited !== value) { if (updated === undefined) { updated = cloneNode(node, /*location*/ undefined, node.flags & ~NodeFlags.Modifier, /*parent*/ undefined, /*original*/ node); } - updated[propertyName] = visited; + updated[edge.name] = visited; } if (visited && isArray(visited) && isModifiersArray(visited)) { - updated.flags |= visited.flags; + modifiers = visited.flags; } } } @@ -594,6 +597,9 @@ namespace ts { if (updated === undefined) { updated = node; } + else if (modifiers) { + updated.flags |= modifiers; + } if (isNewLexicalEnvironment) { const declarations = environment.endLexicalEnvironment(); @@ -740,7 +746,7 @@ namespace ts { * @param nodes The NodeArray. */ function liftToBlock(nodes: NodeArray) { - Debug.assert(trueForAll(nodes, isStatementNode), "Cannot lift nodes to a Block."); + Debug.assert(trueForAll(nodes, isStatement), "Cannot lift nodes to a Block."); return createBlock(>nodes); } diff --git a/src/harness/typeWriter.ts b/src/harness/typeWriter.ts index e332dab648e..145e81f30a8 100644 --- a/src/harness/typeWriter.ts +++ b/src/harness/typeWriter.ts @@ -29,7 +29,7 @@ class TypeWriterWalker { } private visitNode(node: ts.Node): void { - if (ts.isExpression(node) || node.kind === ts.SyntaxKind.Identifier) { + if (ts.isPartOfExpression(node) || node.kind === ts.SyntaxKind.Identifier) { this.logTypeAndSymbol(node); } diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 1c4d5957a02..6f20093c7da 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -296,7 +296,7 @@ namespace ts.BreakpointResolver { } } - if (isExpression(node)) { + if (isPartOfExpression(node)) { switch (node.parent.kind) { case SyntaxKind.DoStatement: // Set span as if on while keyword diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 2df78df01dc..4bc0ad70ad3 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -313,7 +313,7 @@ namespace ts.formatting { this.SpaceAfterVoidOperator = new Rule(RuleDescriptor.create3(SyntaxKind.VoidKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsVoidOpContext), RuleAction.Space)); this.NoSpaceBetweenReturnAndSemicolon = new Rule(RuleDescriptor.create1(SyntaxKind.ReturnKeyword, SyntaxKind.SemicolonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); - + // Add a space between statements. All keywords except (do,else,case) has open/close parens after them. // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any] this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotForContext), RuleAction.Space)); @@ -554,17 +554,17 @@ namespace ts.formatting { static IsSameLineTokenOrBeforeMultilineBlockContext(context: FormattingContext): boolean { //// This check is mainly used inside SpaceBeforeOpenBraceInControl and SpaceBeforeOpenBraceInFunction. //// - //// Ex: + //// Ex: //// if (1) { .... //// * ) and { are on the same line so apply the rule. Here we don't care whether it's same or multi block context //// - //// Ex: + //// Ex: //// if (1) //// { ... } //// * ) and { are on differnet lines. We only need to format if the block is multiline context. So in this case we don't format. //// //// Ex: - //// if (1) + //// if (1) //// { ... //// } //// * ) and { are on differnet lines. We only need to format if the block is multiline context. So in this case we format. @@ -735,7 +735,7 @@ namespace ts.formatting { } static NodeIsInDecoratorContext(node: Node): boolean { - while (isExpression(node)) { + while (isPartOfExpression(node)) { node = node.parent; } return node.kind === SyntaxKind.Decorator; diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 8e0fef884e7..248d81cb072 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -467,7 +467,7 @@ namespace ts.formatting { } return false; } - + /* @internal */ export function nodeWillIndentChild(parent: TextRangeWithKind, child: TextRangeWithKind, indentByDefault: boolean) { let childKind = child ? child.kind : SyntaxKind.Unknown; @@ -497,7 +497,7 @@ namespace ts.formatting { Function returns true when the parent node should indent the given child by an explicit rule */ export function shouldIndentChildNode(parent: TextRangeWithKind, child?: TextRangeWithKind): boolean { - return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, false); + return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, false); } } } diff --git a/src/services/services.ts b/src/services/services.ts index 373d0c3a8ff..24e20ed070a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2986,7 +2986,7 @@ namespace ts { // e.g "b a" is valid quoted name but when we strip off the quotes, it is invalid. // We, thus, need to check if whatever was inside the quotes is actually a valid identifier name. if (performCharacterChecks) { - if (!isIdentifier(name, target)) { + if (!isIdentifierText(name, target)) { return undefined; } } @@ -6342,7 +6342,7 @@ namespace ts { return node.parent.kind === SyntaxKind.TypeReference || (node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isExpressionWithTypeArgumentsInClassExtendsClause(node.parent)) || - (node.kind === SyntaxKind.ThisKeyword && !isExpression(node)) || + (node.kind === SyntaxKind.ThisKeyword && !isPartOfExpression(node)) || node.kind === SyntaxKind.ThisType; }