From acec74b1afc93bba32ac44afc0c6aa8fc12e2807 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 8 May 2017 14:24:45 -0700 Subject: [PATCH] Revert "Convert `Declaration` to union, not type hierarchy" This reverts commit 573040f0cfa713929bfa1fe84f4fd2a81cc82658. --- src/compiler/binder.ts | 6 +- src/compiler/checker.ts | 20 +-- src/compiler/transformers/es2015.ts | 2 +- src/compiler/types.ts | 182 ++++++---------------------- src/compiler/utilities.ts | 9 +- 5 files changed, 58 insertions(+), 161 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 8506378e216..38cb93bff7e 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -304,7 +304,7 @@ namespace ts { } function getDisplayName(node: Declaration): string { - return (node as DeclarationBase).name ? declarationNameToString((node as DeclarationBase).name) : getDeclarationName(node); + return (node as RealDeclaration).name ? declarationNameToString((node as RealDeclaration).name) : getDeclarationName(node); } /** @@ -367,8 +367,8 @@ namespace ts { symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name)); } else { - if ((node as DeclarationBase).name) { - (node as DeclarationBase).name.parent = node; + if ((node as RealDeclaration).name) { + (node as RealDeclaration).name.parent = node; } // Report errors every position with duplicate declaration diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index aea175ac8b1..f7d7a79f9a0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3621,7 +3621,7 @@ namespace ts { }); } - function isDeclarationVisible(node: Node): boolean { + function isDeclarationVisible(node: Declaration): boolean { if (node) { const links = getNodeLinks(node); if (links.isVisible === undefined) { @@ -3635,10 +3635,10 @@ namespace ts { function determineIfDeclarationIsVisible() { switch (node.kind) { case SyntaxKind.BindingElement: - return isDeclarationVisible(node.parent.parent); + return isDeclarationVisible(node.parent.parent); case SyntaxKind.VariableDeclaration: - const declaration = node as VariableDeclaration; - if (isBindingPattern(declaration.name) && !declaration.name.elements.length) { + if (isBindingPattern(node.name) && + !(node.name).elements.length) { // If the binding pattern is empty, this variable declaration is not visible return false; } @@ -3661,7 +3661,7 @@ namespace ts { return isGlobalSourceFile(parent); } // Exported members/ambient module elements (exception import declaration) are visible if parent is visible - return isDeclarationVisible(parent); + return isDeclarationVisible(parent); case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: @@ -3691,7 +3691,7 @@ namespace ts { case SyntaxKind.UnionType: case SyntaxKind.IntersectionType: case SyntaxKind.ParenthesizedType: - return isDeclarationVisible(node.parent); + return isDeclarationVisible(node.parent); // Default binding, import specifier and namespace import is visible // only on demand so by default it is not visible @@ -6236,8 +6236,8 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - return (node).name.kind === SyntaxKind.ComputedPropertyName - && traverse((node).name); + return (node).name.kind === SyntaxKind.ComputedPropertyName + && traverse((node).name); default: return !nodeStartsNewLexicalEnvironment(node) && !isPartOfTypeNode(node) && forEachChild(node, traverse); @@ -21909,7 +21909,7 @@ namespace ts { function isTypeDeclarationName(name: Node): boolean { return name.kind === SyntaxKind.Identifier && isTypeDeclaration(name.parent) && - (name.parent).name === name; + (name.parent).name === name; } function isTypeDeclaration(node: Node): boolean { @@ -22537,7 +22537,7 @@ namespace ts { // Return true if the given node is a declaration of a nested block scoped entity with a name that either hides an // existing name or might hide a name when compiled downlevel - function isDeclarationWithCollidingName(node: Node): boolean { + function isDeclarationWithCollidingName(node: Declaration): boolean { node = getParseTreeNode(node, isDeclaration); if (node) { const symbol = getSymbolOfNode(node); diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 4165b0679e1..188da04b36c 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -3748,7 +3748,7 @@ namespace ts { case SyntaxKind.ClassDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.VariableDeclaration: - return (parent).name === node + return (parent).name === node && resolver.isDeclarationWithCollidingName(parent); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index de71fbfdabe..51e9d6717ee 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -603,75 +603,15 @@ namespace ts { export type DeclarationName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | BindingPattern; - export interface DeclarationBase extends Node { + export interface RealDeclaration extends Node { _declarationBrand: any; name?: DeclarationName; } - export type Declaration = - | ArrowFunction - // Binary expressions can be declarations if they are 'exports.foo = bar' expressions in JS files - | BinaryExpression - | BindingElement - | CallExpression - | CallSignatureDeclaration - | ClassDeclaration - | ClassElement - | ClassExpression - | ClassLikeDeclaration - | ConstructSignatureDeclaration - | ConstructorDeclaration - | ConstructorTypeNode - | EnumDeclaration - | EnumMember - | ExportAssignment - | ExportDeclaration - | ExportSpecifier - | FunctionDeclaration - | FunctionExpression - | FunctionTypeNode - | GetAccessorDeclaration - | ImportClause - | ImportEqualsDeclaration - | ImportSpecifier - | IndexSignatureDeclaration - | InterfaceDeclaration - | JSDocFunctionType - | JSDocNamespaceDeclaration - | JSDocPropertyTag - | JSDocTypedefTag - | JsxAttribute - | JsxAttributes - | JsxSpreadAttribute - | MappedTypeNode - | MethodDeclaration - | MethodSignature - | MissingDeclaration - | ModuleDeclaration - | NamespaceDeclaration - | NamespaceExportDeclaration - | NamespaceImport - | NewExpression - | ObjectLiteralExpression - | ParameterDeclaration - | PropertyAccessExpression - | PropertyAssignment - | PropertyDeclaration - | PropertySignature - | SemicolonClassElement - | SetAccessorDeclaration - | ShorthandPropertyAssignment - | SignatureDeclaration - | SourceFile - | SpreadAssignment - | TypeAliasDeclaration - | TypeElement - | TypeLiteralNode - | TypeParameterDeclaration - | VariableDeclaration - | VariableLikeDeclaration; + // Binary expressions can be declarations if they are 'exports.foo = bar' expressions in JS files + export type Declaration = RealDeclaration | BinaryExpression; - export interface DeclarationStatement extends DeclarationBase, Statement { + export interface DeclarationStatement extends RealDeclaration, Statement { name?: Identifier | StringLiteral | NumericLiteral; } @@ -685,7 +625,7 @@ namespace ts { expression: LeftHandSideExpression; } - export interface TypeParameterDeclaration extends DeclarationBase { + export interface TypeParameterDeclaration extends RealDeclaration { kind: SyntaxKind.TypeParameter; parent?: DeclarationWithTypeParameters; name: Identifier; @@ -696,23 +636,7 @@ namespace ts { expression?: Expression; } - export interface SignatureDeclaration extends DeclarationBase { - kind: - | SyntaxKind.CallSignature - | SyntaxKind.ConstructSignature - | SyntaxKind.ConstructorType - | SyntaxKind.MethodSignature - | SyntaxKind.IndexSignature - | SyntaxKind.FunctionType - | SyntaxKind.JSDocFunctionType - | SyntaxKind.FunctionDeclaration - | SyntaxKind.MethodDeclaration - | SyntaxKind.GetAccessor - | SyntaxKind.SetAccessor - | SyntaxKind.Constructor - | SyntaxKind.ArrowFunction - | SyntaxKind.FunctionExpression - + export interface SignatureDeclaration extends RealDeclaration { name?: PropertyName; typeParameters?: NodeArray; parameters: NodeArray; @@ -729,7 +653,7 @@ namespace ts { export type BindingName = Identifier | BindingPattern; - export interface VariableDeclaration extends DeclarationBase { + export interface VariableDeclaration extends RealDeclaration { kind: SyntaxKind.VariableDeclaration; parent?: VariableDeclarationList | CatchClause; name: BindingName; // Declared variable name @@ -743,7 +667,7 @@ namespace ts { declarations: NodeArray; } - export interface ParameterDeclaration extends DeclarationBase { + export interface ParameterDeclaration extends RealDeclaration { kind: SyntaxKind.Parameter; parent?: SignatureDeclaration; dotDotDotToken?: DotDotDotToken; // Present on rest parameter @@ -753,7 +677,7 @@ namespace ts { initializer?: Expression; // Optional initializer } - export interface BindingElement extends DeclarationBase { + export interface BindingElement extends RealDeclaration { kind: SyntaxKind.BindingElement; parent?: BindingPattern; propertyName?: PropertyName; // Binding property name (in object binding pattern) @@ -778,7 +702,7 @@ namespace ts { initializer?: Expression; // Optional initializer } - export interface ObjectLiteralElement extends DeclarationBase { + export interface ObjectLiteralElement extends RealDeclaration { _objectLiteralBrandBrand: any; name?: PropertyName; } @@ -813,24 +737,16 @@ namespace ts { expression: Expression; } - /** - * There aren't any explicit subtypes of VariableLikeDeclaration; - * it's just structurally relatable to a number of types. - * (Maybe it should be an intersection of the below types.) - */ - export interface VariableLikeDeclaration extends DeclarationBase { - kind: - | SyntaxKind.VariableDeclaration - | SyntaxKind.Parameter - | SyntaxKind.BindingElement - | SyntaxKind.PropertyAssignment - | SyntaxKind.PropertyDeclaration - | SyntaxKind.PropertySignature - | SyntaxKind.JsxAttribute - | SyntaxKind.ShorthandPropertyAssignment - | SyntaxKind.EnumMember - | SyntaxKind.JSDocPropertyTag - | SyntaxKind.JSDocRecordMember; + // SyntaxKind.VariableDeclaration + // SyntaxKind.Parameter + // SyntaxKind.BindingElement + // SyntaxKind.Property + // SyntaxKind.PropertyAssignment + // SyntaxKind.JsxAttribute + // SyntaxKind.ShorthandPropertyAssignment + // SyntaxKind.EnumMember + // SyntaxKind.JSDocPropertyTag + export interface VariableLikeDeclaration extends RealDeclaration { propertyName?: PropertyName; dotDotDotToken?: DotDotDotToken; name: DeclarationName; @@ -839,6 +755,10 @@ namespace ts { initializer?: Expression; } + export interface PropertyLikeDeclaration extends RealDeclaration { + name: PropertyName; + } + export interface ObjectBindingPattern extends Node { kind: SyntaxKind.ObjectBindingPattern; parent?: VariableDeclaration | ParameterDeclaration | BindingElement; @@ -984,7 +904,7 @@ namespace ts { } // A TypeLiteral is the declaration node for an anonymous symbol. - export interface TypeLiteralNode extends TypeNode, DeclarationBase { + export interface TypeLiteralNode extends TypeNode, RealDeclaration { kind: SyntaxKind.TypeLiteral; members: NodeArray; } @@ -1028,7 +948,7 @@ namespace ts { indexType: TypeNode; } - export interface MappedTypeNode extends TypeNode, DeclarationBase { + export interface MappedTypeNode extends TypeNode, RealDeclaration { kind: SyntaxKind.MappedType; parent?: TypeAliasDeclaration; readonlyToken?: ReadonlyToken; @@ -1485,7 +1405,7 @@ namespace ts { * JSXAttribute or JSXSpreadAttribute. ObjectLiteralExpression, on the other hand, can only have properties of type * ObjectLiteralElement (e.g. PropertyAssignment, ShorthandPropertyAssignment etc.) */ - export interface ObjectLiteralExpressionBase extends PrimaryExpression, DeclarationBase { + export interface ObjectLiteralExpressionBase extends PrimaryExpression, RealDeclaration { properties: NodeArray; } @@ -1499,7 +1419,7 @@ namespace ts { export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression | ParenthesizedExpression; export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression; - export interface PropertyAccessExpression extends MemberExpression, DeclarationBase { + export interface PropertyAccessExpression extends MemberExpression, RealDeclaration { kind: SyntaxKind.PropertyAccessExpression; expression: LeftHandSideExpression; name: Identifier; @@ -1531,7 +1451,7 @@ namespace ts { | SuperElementAccessExpression ; - export interface CallExpression extends LeftHandSideExpression, DeclarationBase { + export interface CallExpression extends LeftHandSideExpression, RealDeclaration { kind: SyntaxKind.CallExpression; expression: LeftHandSideExpression; typeArguments?: NodeArray; @@ -1550,7 +1470,7 @@ namespace ts { typeArguments?: NodeArray; } - export interface NewExpression extends PrimaryExpression, DeclarationBase { + export interface NewExpression extends PrimaryExpression, RealDeclaration { kind: SyntaxKind.NewExpression; expression: LeftHandSideExpression; typeArguments?: NodeArray; @@ -1608,7 +1528,6 @@ namespace ts { export type JsxTagNameExpression = PrimaryExpression | PropertyAccessExpression; export interface JsxAttributes extends ObjectLiteralExpressionBase { - kind: SyntaxKind.JsxAttributes; parent?: JsxOpeningLikeElement; } @@ -1845,10 +1764,7 @@ namespace ts { export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration; - export interface ClassLikeDeclaration extends DeclarationBase { - kind: - | SyntaxKind.ClassDeclaration - | SyntaxKind.ClassExpression; + export interface ClassLikeDeclaration extends RealDeclaration { name?: Identifier; typeParameters?: NodeArray; heritageClauses?: NodeArray; @@ -1864,30 +1780,12 @@ namespace ts { kind: SyntaxKind.ClassExpression; } - export interface ClassElement extends DeclarationBase { - kind: - | SyntaxKind.PropertyDeclaration - | SyntaxKind.MethodDeclaration - | SyntaxKind.Constructor - | SyntaxKind.SemicolonClassElement - | SyntaxKind.GetAccessor - | SyntaxKind.SetAccessor - | SyntaxKind.IndexSignature - | SyntaxKind.MissingDeclaration; + export interface ClassElement extends RealDeclaration { _classElementBrand: any; name?: PropertyName; } - export interface TypeElement extends DeclarationBase { - kind: - | SyntaxKind.CallSignature - | SyntaxKind.ConstructSignature - | SyntaxKind.PropertySignature - | SyntaxKind.MethodSignature - | SyntaxKind.IndexSignature - | SyntaxKind.MissingDeclaration - | SyntaxKind.JSDocPropertyTag - | SyntaxKind.JSDocRecordMember; + export interface TypeElement extends RealDeclaration { _typeElementBrand: any; name?: PropertyName; questionToken?: QuestionToken; @@ -1915,7 +1813,7 @@ namespace ts { type: TypeNode; } - export interface EnumMember extends DeclarationBase { + export interface EnumMember extends RealDeclaration { kind: SyntaxKind.EnumMember; parent?: EnumDeclaration; // This does include ComputedPropertyName, but the parser will give an error @@ -2004,14 +1902,14 @@ 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}]} - export interface ImportClause extends DeclarationBase { + export interface ImportClause extends RealDeclaration { kind: SyntaxKind.ImportClause; parent?: ImportDeclaration; name?: Identifier; // Default binding namedBindings?: NamedImportBindings; } - export interface NamespaceImport extends DeclarationBase { + export interface NamespaceImport extends RealDeclaration { kind: SyntaxKind.NamespaceImport; parent?: ImportClause; name: Identifier; @@ -2044,14 +1942,14 @@ namespace ts { export type NamedImportsOrExports = NamedImports | NamedExports; - export interface ImportSpecifier extends DeclarationBase { + export interface ImportSpecifier extends RealDeclaration { kind: SyntaxKind.ImportSpecifier; parent?: NamedImports; propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) name: Identifier; // Declared name } - export interface ExportSpecifier extends DeclarationBase { + export interface ExportSpecifier extends RealDeclaration { kind: SyntaxKind.ExportSpecifier; parent?: NamedExports; propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) @@ -2217,7 +2115,7 @@ namespace ts { typeExpression: JSDocTypeExpression; } - export interface JSDocTypedefTag extends JSDocTag, DeclarationBase { + export interface JSDocTypedefTag extends JSDocTag, RealDeclaration { kind: SyntaxKind.JSDocTypedefTag; fullName?: JSDocNamespaceDeclaration | Identifier; name?: Identifier; @@ -2351,7 +2249,7 @@ namespace ts { // Source files are declarations when they are external modules. - export interface SourceFile extends DeclarationBase { + export interface SourceFile extends RealDeclaration { kind: SyntaxKind.SourceFile; statements: NodeArray; endOfFileToken: Token; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 7b92dbf68b5..a3525ee0a70 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -566,7 +566,7 @@ namespace ts { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.TypeAliasDeclaration: - errorNode = (node).name; + errorNode = (node).name; break; case SyntaxKind.ArrowFunction: return getErrorSpanForArrowFunction(sourceFile, node); @@ -1781,7 +1781,7 @@ namespace ts { return undefined; } if (declaration.kind === SyntaxKind.BinaryExpression) { - const kind = getSpecialPropertyAssignmentKind(declaration); + const kind = getSpecialPropertyAssignmentKind(declaration as BinaryExpression); const lhs = (declaration as BinaryExpression).left; switch (kind) { case SpecialPropertyAssignmentKind.None: @@ -1806,7 +1806,6 @@ namespace ts { } } - export function isLiteralComputedPropertyDeclarationName(node: Node) { return (node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NumericLiteral) && node.parent.kind === SyntaxKind.ComputedPropertyName && @@ -1827,7 +1826,7 @@ namespace ts { case SyntaxKind.PropertyAssignment: case SyntaxKind.PropertyAccessExpression: // Name in member declaration or property name in property access - return (parent).name === node; + return (parent).name === node; case SyntaxKind.QualifiedName: // Name on right hand side of dot in a type query if ((parent).right === node) { @@ -4103,7 +4102,7 @@ namespace ts { || kind === SyntaxKind.MergeDeclarationMarker; } - export function isDeclaration(node: Node): node is DeclarationBase { + export function isDeclaration(node: Node): node is RealDeclaration { return isDeclarationKind(node.kind); }