Skip to content

Commit a1e18fc

Browse files
Introduce a new HeritageClauseElment type.
This type represents the expression+type arguments you can get in a class or interface heritage clause section. For class-implements clauses, or interface-extends clauses, these expressions can only be identifiers or dotted names. For class extends clauses, these could be any expressions in the future. However, for now, we only support identifiers and dotted names.
1 parent 616f638 commit a1e18fc

68 files changed

Lines changed: 7460 additions & 770 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/compiler/checker.ts

Lines changed: 145 additions & 83 deletions
Large diffs are not rendered by default.

src/compiler/declarationEmitter.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,12 @@ module ts {
314314
}
315315
}
316316

317-
function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type: TypeNode | EntityName, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
317+
function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type: TypeNode | EntityName | HeritageClauseElement, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
318318
writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
319319
emitType(type);
320320
}
321321

322-
function emitType(type: TypeNode | StringLiteralExpression | Identifier | QualifiedName) {
322+
function emitType(type: TypeNode | StringLiteralExpression | Identifier | QualifiedName | HeritageClauseElement) {
323323
switch (type.kind) {
324324
case SyntaxKind.AnyKeyword:
325325
case SyntaxKind.StringKeyword:
@@ -329,6 +329,8 @@ module ts {
329329
case SyntaxKind.VoidKeyword:
330330
case SyntaxKind.StringLiteral:
331331
return writeTextOfNode(currentSourceFile, type);
332+
case SyntaxKind.HeritageClauseElement:
333+
return emitHeritageClauseElement(<HeritageClauseElement>type);
332334
case SyntaxKind.TypeReference:
333335
return emitTypeReference(<TypeReferenceNode>type);
334336
case SyntaxKind.TypeQuery:
@@ -350,27 +352,38 @@ module ts {
350352
return emitEntityName(<Identifier>type);
351353
case SyntaxKind.QualifiedName:
352354
return emitEntityName(<QualifiedName>type);
353-
default:
354-
Debug.fail("Unknown type annotation: " + type.kind);
355355
}
356356

357-
function emitEntityName(entityName: EntityName) {
357+
function emitEntityName(entityName: EntityName | PropertyAccessExpression) {
358358
let visibilityResult = resolver.isEntityNameVisible(entityName,
359359
// Aliases can be written asynchronously so use correct enclosing declaration
360360
entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration ? entityName.parent : enclosingDeclaration);
361361

362362
handleSymbolAccessibilityError(visibilityResult);
363363
writeEntityName(entityName);
364364

365-
function writeEntityName(entityName: EntityName) {
365+
function writeEntityName(entityName: EntityName | Expression) {
366366
if (entityName.kind === SyntaxKind.Identifier) {
367367
writeTextOfNode(currentSourceFile, entityName);
368368
}
369369
else {
370-
let qualifiedName = <QualifiedName>entityName;
371-
writeEntityName(qualifiedName.left);
370+
let left = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).left : (<PropertyAccessExpression>entityName).expression;
371+
let right = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).right : (<PropertyAccessExpression>entityName).name;
372+
writeEntityName(left);
372373
write(".");
373-
writeTextOfNode(currentSourceFile, qualifiedName.right);
374+
writeTextOfNode(currentSourceFile, right);
375+
}
376+
}
377+
}
378+
379+
function emitHeritageClauseElement(node: HeritageClauseElement) {
380+
if (isSupportedHeritageClauseElement(node)) {
381+
Debug.assert(node.expression.kind === SyntaxKind.Identifier || node.expression.kind === SyntaxKind.PropertyAccessExpression);
382+
emitEntityName(<Identifier | PropertyAccessExpression>node.expression);
383+
if (node.typeArguments) {
384+
write("<");
385+
emitCommaList(node.typeArguments, emitType);
386+
write(">");
374387
}
375388
}
376389
}
@@ -827,14 +840,16 @@ module ts {
827840
}
828841
}
829842

830-
function emitHeritageClause(typeReferences: TypeReferenceNode[], isImplementsList: boolean) {
843+
function emitHeritageClause(typeReferences: HeritageClauseElement[], isImplementsList: boolean) {
831844
if (typeReferences) {
832845
write(isImplementsList ? " implements " : " extends ");
833846
emitCommaList(typeReferences, emitTypeOfTypeReference);
834847
}
835848

836-
function emitTypeOfTypeReference(node: TypeReferenceNode) {
837-
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError);
849+
function emitTypeOfTypeReference(node: HeritageClauseElement) {
850+
if (isSupportedHeritageClauseElement(node)) {
851+
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError);
852+
}
838853

839854
function getHeritageClauseVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
840855
let diagnosticMessage: DiagnosticMessage;

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,8 @@ module ts {
351351
The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression: { code: 2496, category: DiagnosticCategory.Error, key: "The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression." },
352352
External_module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct: { code: 2497, category: DiagnosticCategory.Error, key: "External module '{0}' resolves to a non-module entity and cannot be imported using this construct." },
353353
External_module_0_uses_export_and_cannot_be_used_with_export_Asterisk: { code: 2498, category: DiagnosticCategory.Error, key: "External module '{0}' uses 'export =' and cannot be used with 'export *'." },
354+
An_interface_can_only_extend_a_type_reference: { code: 2499, category: DiagnosticCategory.Error, key: "An interface can only extend a type reference." },
355+
A_class_can_only_implement_type_references: { code: 2500, category: DiagnosticCategory.Error, key: "A class can only implement type references." },
354356
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
355357
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
356358
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
@@ -498,5 +500,6 @@ module ts {
498500
You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." },
499501
yield_expressions_are_not_currently_supported: { code: 9000, category: DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." },
500502
Generators_are_not_currently_supported: { code: 9001, category: DiagnosticCategory.Error, key: "Generators are not currently supported." },
503+
Only_type_references_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: DiagnosticCategory.Error, key: "Only type references are currently supported in a class 'extends' clauses." },
501504
};
502505
}

src/compiler/diagnosticMessages.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,14 @@
13961396
"category": "Error",
13971397
"code": 2498
13981398
},
1399+
"An interface can only extend a type reference.": {
1400+
"category": "Error",
1401+
"code": 2499
1402+
},
1403+
"A class can only implement type references.": {
1404+
"category": "Error",
1405+
"code": 2500
1406+
},
13991407

14001408
"Import declaration '{0}' is using private name '{1}'.": {
14011409
"category": "Error",
@@ -1985,5 +1993,9 @@
19851993
"Generators are not currently supported.": {
19861994
"category": "Error",
19871995
"code": 9001
1996+
},
1997+
"Only type references are currently supported in a class 'extends' clauses.": {
1998+
"category": "Error",
1999+
"code": 9002
19882000
}
19892001
}

src/compiler/emitter.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3314,7 +3314,7 @@ module ts {
33143314
}
33153315
}
33163316

3317-
function emitConstructor(node: ClassDeclaration, baseTypeNode: TypeReferenceNode) {
3317+
function emitConstructor(node: ClassDeclaration, baseTypeElement: HeritageClauseElement) {
33183318
let saveTempFlags = tempFlags;
33193319
let saveTempVariables = tempVariables;
33203320
let saveTempParameters = tempParameters;
@@ -3368,7 +3368,7 @@ module ts {
33683368
// Let constructor be the result of parsing the String "constructor(... args){ super (...args);}" using the syntactic grammar with the goal symbol MethodDefinition.
33693369
// Else,
33703370
// Let constructor be the result of parsing the String "constructor( ){ }" using the syntactic grammar with the goal symbol MethodDefinition
3371-
if (baseTypeNode) {
3371+
if (baseTypeElement) {
33723372
write("(...args)");
33733373
}
33743374
else {
@@ -3387,7 +3387,7 @@ module ts {
33873387
if (ctor) {
33883388
emitDefaultValueAssignments(ctor);
33893389
emitRestParameter(ctor);
3390-
if (baseTypeNode) {
3390+
if (baseTypeElement) {
33913391
var superCall = findInitialSuperCall(ctor);
33923392
if (superCall) {
33933393
writeLine();
@@ -3397,16 +3397,16 @@ module ts {
33973397
emitParameterPropertyAssignments(ctor);
33983398
}
33993399
else {
3400-
if (baseTypeNode) {
3400+
if (baseTypeElement) {
34013401
writeLine();
3402-
emitStart(baseTypeNode);
3402+
emitStart(baseTypeElement);
34033403
if (languageVersion < ScriptTarget.ES6) {
34043404
write("_super.apply(this, arguments);");
34053405
}
34063406
else {
34073407
write("super(...args);");
34083408
}
3409-
emitEnd(baseTypeNode);
3409+
emitEnd(baseTypeElement);
34103410
}
34113411
}
34123412
emitMemberAssignments(node, /*staticFlag*/0);
@@ -3525,7 +3525,7 @@ module ts {
35253525
var baseTypeNode = getClassBaseTypeNode(node);
35263526
if (baseTypeNode) {
35273527
write(" extends ");
3528-
emit(baseTypeNode.typeName);
3528+
emit(baseTypeNode.expression);
35293529
}
35303530

35313531
write(" {");
@@ -3639,7 +3639,7 @@ module ts {
36393639
emitStart(node);
36403640
write(")(");
36413641
if (baseTypeNode) {
3642-
emit(baseTypeNode.typeName);
3642+
emit(baseTypeNode.expression);
36433643
}
36443644
write(");");
36453645
emitEnd(node);

0 commit comments

Comments
 (0)