Skip to content

Commit 0f74294

Browse files
committed
getNameOfDeclaration uniformly, including JS decls
JS-style assignment declarations have a name, but it's not stored on the name property of the BinaryExpression. This commit adds `getNameOfDeclaration` to uniformly get the name of a declaration. It also reworks the declaration of `Declaration` so that accessing `name` is an error unless the type does *not* include BinaryExpression.
1 parent c10de35 commit 0f74294

File tree

17 files changed

+184
-126
lines changed

17 files changed

+184
-126
lines changed

src/compiler/binder.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,13 @@ namespace ts {
227227
// Should not be called on a declaration with a computed property name,
228228
// unless it is a well known Symbol.
229229
function getDeclarationName(node: Declaration): string {
230-
if (node.name) {
230+
const name = getNameOfDeclaration(node);
231+
if (name) {
231232
if (isAmbientModule(node)) {
232-
return isGlobalScopeAugmentation(<ModuleDeclaration>node) ? "__global" : `"${(<LiteralExpression>node.name).text}"`;
233+
return isGlobalScopeAugmentation(<ModuleDeclaration>node) ? "__global" : `"${(<LiteralExpression>name).text}"`;
233234
}
234-
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
235-
const nameExpression = (<ComputedPropertyName>node.name).expression;
235+
if (name.kind === SyntaxKind.ComputedPropertyName) {
236+
const nameExpression = (<ComputedPropertyName>name).expression;
236237
// treat computed property names where expression is string/numeric literal as just string/numeric literal
237238
if (isStringOrNumericLiteral(nameExpression)) {
238239
return nameExpression.text;
@@ -241,7 +242,7 @@ namespace ts {
241242
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
242243
return getPropertyNameForKnownSymbolName((<PropertyAccessExpression>nameExpression).name.text);
243244
}
244-
return (<Identifier | LiteralExpression>node.name).text;
245+
return (<Identifier | LiteralExpression>name).text;
245246
}
246247
switch (node.kind) {
247248
case SyntaxKind.Constructor:
@@ -303,7 +304,7 @@ namespace ts {
303304
}
304305

305306
function getDisplayName(node: Declaration): string {
306-
return node.name ? declarationNameToString(node.name) : getDeclarationName(node);
307+
return (node as RealDeclaration).name ? declarationNameToString((node as RealDeclaration).name) : getDeclarationName(node);
307308
}
308309

309310
/**
@@ -366,8 +367,8 @@ namespace ts {
366367
symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name));
367368
}
368369
else {
369-
if (node.name) {
370-
node.name.parent = node;
370+
if ((node as RealDeclaration).name) {
371+
(node as RealDeclaration).name.parent = node;
371372
}
372373

373374
// Report errors every position with duplicate declaration
@@ -396,9 +397,9 @@ namespace ts {
396397
}
397398

398399
forEach(symbol.declarations, declaration => {
399-
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
400+
file.bindDiagnostics.push(createDiagnosticForNode(getNameOfDeclaration(declaration) || declaration, message, getDisplayName(declaration)));
400401
});
401-
file.bindDiagnostics.push(createDiagnosticForNode(node.name || node, message, getDisplayName(node)));
402+
file.bindDiagnostics.push(createDiagnosticForNode(getNameOfDeclaration(node) || node, message, getDisplayName(node)));
402403

403404
symbol = createSymbol(SymbolFlags.None, name);
404405
}

src/compiler/checker.ts

Lines changed: 58 additions & 43 deletions
Large diffs are not rendered by default.

src/compiler/declarationEmitter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,7 @@ namespace ts {
11271127
return {
11281128
diagnosticMessage,
11291129
errorNode: node,
1130-
typeName: (<Declaration>node.parent.parent).name
1130+
typeName: getNameOfDeclaration(node.parent.parent)
11311131
};
11321132
}
11331133
}

src/compiler/factory.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,9 +3014,10 @@ namespace ts {
30143014
}
30153015

30163016
function getName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
3017-
if (node.name && isIdentifier(node.name) && !isGeneratedIdentifier(node.name)) {
3018-
const name = getMutableClone(node.name);
3019-
emitFlags |= getEmitFlags(node.name);
3017+
const nodeName = getNameOfDeclaration(node);
3018+
if (nodeName && isIdentifier(nodeName) && !isGeneratedIdentifier(nodeName)) {
3019+
const name = getMutableClone(nodeName);
3020+
emitFlags |= getEmitFlags(nodeName);
30203021
if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap;
30213022
if (!allowComments) emitFlags |= EmitFlags.NoComments;
30223023
if (emitFlags) setEmitFlags(name, emitFlags);

src/compiler/transformers/es2015.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3748,7 +3748,7 @@ namespace ts {
37483748
case SyntaxKind.ClassDeclaration:
37493749
case SyntaxKind.EnumDeclaration:
37503750
case SyntaxKind.VariableDeclaration:
3751-
return (<Declaration>parent).name === node
3751+
return (<RealDeclaration>parent).name === node
37523752
&& resolver.isDeclarationWithCollidingName(<Declaration>parent);
37533753
}
37543754

@@ -3781,7 +3781,7 @@ namespace ts {
37813781
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings && !isInternalName(node)) {
37823782
const declaration = resolver.getReferencedDeclarationWithCollidingName(node);
37833783
if (declaration && !(isClassLike(declaration) && isPartOfClassBody(declaration, node))) {
3784-
return setTextRange(getGeneratedNameForNode(declaration.name), node);
3784+
return setTextRange(getGeneratedNameForNode(getNameOfDeclaration(declaration)), node);
37853785
}
37863786
}
37873787

src/compiler/types.ts

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -603,12 +603,15 @@ namespace ts {
603603

604604
export type DeclarationName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | BindingPattern;
605605

606-
export interface Declaration extends Node {
606+
export interface RealDeclaration extends Node {
607607
_declarationBrand: any;
608608
name?: DeclarationName;
609609
}
610610

611-
export interface DeclarationStatement extends Declaration, Statement {
611+
// Binary expressions can be declarations if they are 'exports.foo = bar' expressions in JS files
612+
export type Declaration = RealDeclaration | BinaryExpression;
613+
614+
export interface DeclarationStatement extends RealDeclaration, Statement {
612615
name?: Identifier | StringLiteral | NumericLiteral;
613616
}
614617

@@ -622,7 +625,7 @@ namespace ts {
622625
expression: LeftHandSideExpression;
623626
}
624627

625-
export interface TypeParameterDeclaration extends Declaration {
628+
export interface TypeParameterDeclaration extends RealDeclaration {
626629
kind: SyntaxKind.TypeParameter;
627630
parent?: DeclarationWithTypeParameters;
628631
name: Identifier;
@@ -633,7 +636,7 @@ namespace ts {
633636
expression?: Expression;
634637
}
635638

636-
export interface SignatureDeclaration extends Declaration {
639+
export interface SignatureDeclaration extends RealDeclaration {
637640
name?: PropertyName;
638641
typeParameters?: NodeArray<TypeParameterDeclaration>;
639642
parameters: NodeArray<ParameterDeclaration>;
@@ -650,7 +653,7 @@ namespace ts {
650653

651654
export type BindingName = Identifier | BindingPattern;
652655

653-
export interface VariableDeclaration extends Declaration {
656+
export interface VariableDeclaration extends RealDeclaration {
654657
kind: SyntaxKind.VariableDeclaration;
655658
parent?: VariableDeclarationList | CatchClause;
656659
name: BindingName; // Declared variable name
@@ -664,7 +667,7 @@ namespace ts {
664667
declarations: NodeArray<VariableDeclaration>;
665668
}
666669

667-
export interface ParameterDeclaration extends Declaration {
670+
export interface ParameterDeclaration extends RealDeclaration {
668671
kind: SyntaxKind.Parameter;
669672
parent?: SignatureDeclaration;
670673
dotDotDotToken?: DotDotDotToken; // Present on rest parameter
@@ -674,7 +677,7 @@ namespace ts {
674677
initializer?: Expression; // Optional initializer
675678
}
676679

677-
export interface BindingElement extends Declaration {
680+
export interface BindingElement extends RealDeclaration {
678681
kind: SyntaxKind.BindingElement;
679682
parent?: BindingPattern;
680683
propertyName?: PropertyName; // Binding property name (in object binding pattern)
@@ -699,7 +702,7 @@ namespace ts {
699702
initializer?: Expression; // Optional initializer
700703
}
701704

702-
export interface ObjectLiteralElement extends Declaration {
705+
export interface ObjectLiteralElement extends RealDeclaration {
703706
_objectLiteralBrandBrand: any;
704707
name?: PropertyName;
705708
}
@@ -743,7 +746,7 @@ namespace ts {
743746
// SyntaxKind.ShorthandPropertyAssignment
744747
// SyntaxKind.EnumMember
745748
// SyntaxKind.JSDocPropertyTag
746-
export interface VariableLikeDeclaration extends Declaration {
749+
export interface VariableLikeDeclaration extends RealDeclaration {
747750
propertyName?: PropertyName;
748751
dotDotDotToken?: DotDotDotToken;
749752
name: DeclarationName;
@@ -752,7 +755,7 @@ namespace ts {
752755
initializer?: Expression;
753756
}
754757

755-
export interface PropertyLikeDeclaration extends Declaration {
758+
export interface PropertyLikeDeclaration extends RealDeclaration {
756759
name: PropertyName;
757760
}
758761

@@ -901,7 +904,7 @@ namespace ts {
901904
}
902905

903906
// A TypeLiteral is the declaration node for an anonymous symbol.
904-
export interface TypeLiteralNode extends TypeNode, Declaration {
907+
export interface TypeLiteralNode extends TypeNode, RealDeclaration {
905908
kind: SyntaxKind.TypeLiteral;
906909
members: NodeArray<TypeElement>;
907910
}
@@ -945,7 +948,7 @@ namespace ts {
945948
indexType: TypeNode;
946949
}
947950

948-
export interface MappedTypeNode extends TypeNode, Declaration {
951+
export interface MappedTypeNode extends TypeNode, RealDeclaration {
949952
kind: SyntaxKind.MappedType;
950953
parent?: TypeAliasDeclaration;
951954
readonlyToken?: ReadonlyToken;
@@ -1216,8 +1219,7 @@ namespace ts {
12161219

12171220
export type BinaryOperatorToken = Token<BinaryOperator>;
12181221

1219-
// Binary expressions can be declarations if they are 'exports.foo = bar' expressions in JS files
1220-
export interface BinaryExpression extends Expression, Declaration {
1222+
export interface BinaryExpression extends Expression {
12211223
kind: SyntaxKind.BinaryExpression;
12221224
left: Expression;
12231225
operatorToken: BinaryOperatorToken;
@@ -1403,7 +1405,7 @@ namespace ts {
14031405
* JSXAttribute or JSXSpreadAttribute. ObjectLiteralExpression, on the other hand, can only have properties of type
14041406
* ObjectLiteralElement (e.g. PropertyAssignment, ShorthandPropertyAssignment etc.)
14051407
*/
1406-
export interface ObjectLiteralExpressionBase<T extends ObjectLiteralElement> extends PrimaryExpression, Declaration {
1408+
export interface ObjectLiteralExpressionBase<T extends ObjectLiteralElement> extends PrimaryExpression, RealDeclaration {
14071409
properties: NodeArray<T>;
14081410
}
14091411

@@ -1417,7 +1419,7 @@ namespace ts {
14171419
export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression | ParenthesizedExpression;
14181420
export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression;
14191421

1420-
export interface PropertyAccessExpression extends MemberExpression, Declaration {
1422+
export interface PropertyAccessExpression extends MemberExpression, RealDeclaration {
14211423
kind: SyntaxKind.PropertyAccessExpression;
14221424
expression: LeftHandSideExpression;
14231425
name: Identifier;
@@ -1449,7 +1451,7 @@ namespace ts {
14491451
| SuperElementAccessExpression
14501452
;
14511453

1452-
export interface CallExpression extends LeftHandSideExpression, Declaration {
1454+
export interface CallExpression extends LeftHandSideExpression, RealDeclaration {
14531455
kind: SyntaxKind.CallExpression;
14541456
expression: LeftHandSideExpression;
14551457
typeArguments?: NodeArray<TypeNode>;
@@ -1468,7 +1470,7 @@ namespace ts {
14681470
typeArguments?: NodeArray<TypeNode>;
14691471
}
14701472

1471-
export interface NewExpression extends PrimaryExpression, Declaration {
1473+
export interface NewExpression extends PrimaryExpression, RealDeclaration {
14721474
kind: SyntaxKind.NewExpression;
14731475
expression: LeftHandSideExpression;
14741476
typeArguments?: NodeArray<TypeNode>;
@@ -1762,7 +1764,7 @@ namespace ts {
17621764

17631765
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration;
17641766

1765-
export interface ClassLikeDeclaration extends Declaration {
1767+
export interface ClassLikeDeclaration extends RealDeclaration {
17661768
name?: Identifier;
17671769
typeParameters?: NodeArray<TypeParameterDeclaration>;
17681770
heritageClauses?: NodeArray<HeritageClause>;
@@ -1778,12 +1780,12 @@ namespace ts {
17781780
kind: SyntaxKind.ClassExpression;
17791781
}
17801782

1781-
export interface ClassElement extends Declaration {
1783+
export interface ClassElement extends RealDeclaration {
17821784
_classElementBrand: any;
17831785
name?: PropertyName;
17841786
}
17851787

1786-
export interface TypeElement extends Declaration {
1788+
export interface TypeElement extends RealDeclaration {
17871789
_typeElementBrand: any;
17881790
name?: PropertyName;
17891791
questionToken?: QuestionToken;
@@ -1811,7 +1813,7 @@ namespace ts {
18111813
type: TypeNode;
18121814
}
18131815

1814-
export interface EnumMember extends Declaration {
1816+
export interface EnumMember extends RealDeclaration {
18151817
kind: SyntaxKind.EnumMember;
18161818
parent?: EnumDeclaration;
18171819
// This does include ComputedPropertyName, but the parser will give an error
@@ -1900,14 +1902,14 @@ namespace ts {
19001902
// import d, * as ns from "mod" => name = d, namedBinding: NamespaceImport = { name: ns }
19011903
// import { a, b as x } from "mod" => name = undefined, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
19021904
// import d, { a, b as x } from "mod" => name = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
1903-
export interface ImportClause extends Declaration {
1905+
export interface ImportClause extends RealDeclaration {
19041906
kind: SyntaxKind.ImportClause;
19051907
parent?: ImportDeclaration;
19061908
name?: Identifier; // Default binding
19071909
namedBindings?: NamedImportBindings;
19081910
}
19091911

1910-
export interface NamespaceImport extends Declaration {
1912+
export interface NamespaceImport extends RealDeclaration {
19111913
kind: SyntaxKind.NamespaceImport;
19121914
parent?: ImportClause;
19131915
name: Identifier;
@@ -1940,14 +1942,14 @@ namespace ts {
19401942

19411943
export type NamedImportsOrExports = NamedImports | NamedExports;
19421944

1943-
export interface ImportSpecifier extends Declaration {
1945+
export interface ImportSpecifier extends RealDeclaration {
19441946
kind: SyntaxKind.ImportSpecifier;
19451947
parent?: NamedImports;
19461948
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
19471949
name: Identifier; // Declared name
19481950
}
19491951

1950-
export interface ExportSpecifier extends Declaration {
1952+
export interface ExportSpecifier extends RealDeclaration {
19511953
kind: SyntaxKind.ExportSpecifier;
19521954
parent?: NamedExports;
19531955
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
@@ -2113,7 +2115,7 @@ namespace ts {
21132115
typeExpression: JSDocTypeExpression;
21142116
}
21152117

2116-
export interface JSDocTypedefTag extends JSDocTag, Declaration {
2118+
export interface JSDocTypedefTag extends JSDocTag, RealDeclaration {
21172119
kind: SyntaxKind.JSDocTypedefTag;
21182120
fullName?: JSDocNamespaceDeclaration | Identifier;
21192121
name?: Identifier;
@@ -2247,7 +2249,7 @@ namespace ts {
22472249

22482250

22492251
// Source files are declarations when they are external modules.
2250-
export interface SourceFile extends Declaration {
2252+
export interface SourceFile extends RealDeclaration {
22512253
kind: SyntaxKind.SourceFile;
22522254
statements: NodeArray<Statement>;
22532255
endOfFileToken: Token<SyntaxKind.EndOfFileToken>;

0 commit comments

Comments
 (0)