mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 02:33:53 -06:00
Error on emit declaration of extends class w/o symbol
Error when emitting an extends clause for a type that has no symbol. This error only occurs on exported classes. This prevents the emitter from producing types that extend from intersections, which are not parseable right now.
This commit is contained in:
parent
b8d04baf34
commit
57dce1c0bc
@ -20902,6 +20902,9 @@ namespace ts {
|
||||
const classType = <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(node));
|
||||
resolveBaseTypesOfClass(classType);
|
||||
const baseType = classType.resolvedBaseTypes.length ? classType.resolvedBaseTypes[0] : unknownType;
|
||||
if (!baseType.symbol) {
|
||||
writer.reportIllegalExtends();
|
||||
}
|
||||
getSymbolDisplayBuilder().buildTypeDisplay(baseType, writer, enclosingDeclaration, flags);
|
||||
}
|
||||
|
||||
|
||||
@ -190,6 +190,7 @@ namespace ts {
|
||||
const writer = <EmitTextWriterWithSymbolWriter>createTextWriter(newLine);
|
||||
writer.trackSymbol = trackSymbol;
|
||||
writer.reportInaccessibleThisError = reportInaccessibleThisError;
|
||||
writer.reportIllegalExtends = reportIllegalExtends;
|
||||
writer.writeKeyword = writer.write;
|
||||
writer.writeOperator = writer.write;
|
||||
writer.writePunctuation = writer.write;
|
||||
@ -313,6 +314,14 @@ namespace ts {
|
||||
recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
|
||||
}
|
||||
|
||||
function reportIllegalExtends() {
|
||||
if (errorNameNode) {
|
||||
reportedDeclarationError = true;
|
||||
emitterDiagnostics.add(createDiagnosticForNode(errorNameNode, Diagnostics.Extends_clause_of_exported_class_0_refers_to_a_type_with_no_declaration,
|
||||
declarationNameToString(errorNameNode)));
|
||||
}
|
||||
}
|
||||
|
||||
function reportInaccessibleThisError() {
|
||||
if (errorNameNode) {
|
||||
reportedDeclarationError = true;
|
||||
@ -1071,7 +1080,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitHeritageClause(typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) {
|
||||
function emitHeritageClause(className: Identifier, typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) {
|
||||
if (typeReferences) {
|
||||
write(isImplementsList ? " implements " : " extends ");
|
||||
emitCommaList(typeReferences, emitTypeOfTypeReference);
|
||||
@ -1086,7 +1095,9 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
writer.getSymbolAccessibilityDiagnostic = getHeritageClauseVisibilityError;
|
||||
errorNameNode = className;
|
||||
resolver.writeBaseConstructorTypeOfClass(<ClassLikeDeclaration>enclosingDeclaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
errorNameNode = undefined;
|
||||
}
|
||||
|
||||
function getHeritageClauseVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
@ -1136,9 +1147,10 @@ namespace ts {
|
||||
emitTypeParameters(node.typeParameters);
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
||||
if (baseTypeNode) {
|
||||
emitHeritageClause([baseTypeNode], /*isImplementsList*/ false);
|
||||
node.name
|
||||
emitHeritageClause(node.name, [baseTypeNode], /*isImplementsList*/ false);
|
||||
}
|
||||
emitHeritageClause(getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true);
|
||||
emitHeritageClause(node.name, getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true);
|
||||
write(" {");
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
@ -1160,7 +1172,7 @@ namespace ts {
|
||||
emitTypeParameters(node.typeParameters);
|
||||
const interfaceExtendsTypes = filter(getInterfaceBaseTypeNodes(node), base => isEntityNameExpression(base.expression));
|
||||
if (interfaceExtendsTypes && interfaceExtendsTypes.length) {
|
||||
emitHeritageClause(interfaceExtendsTypes, /*isImplementsList*/ false);
|
||||
emitHeritageClause(node.name, interfaceExtendsTypes, /*isImplementsList*/ false);
|
||||
}
|
||||
write(" {");
|
||||
writeLine();
|
||||
|
||||
@ -2356,6 +2356,10 @@
|
||||
"category": "Error",
|
||||
"code": 4092
|
||||
},
|
||||
"Extends clause of exported class '{0}' refers to a type with no declaration.": {
|
||||
"category": "Error",
|
||||
"code": 4093
|
||||
},
|
||||
|
||||
"The current host does not support the '{0}' option.": {
|
||||
"category": "Error",
|
||||
|
||||
@ -2474,6 +2474,7 @@
|
||||
// with import statements it previously saw (but chose not to emit).
|
||||
trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void;
|
||||
reportInaccessibleThisError(): void;
|
||||
reportIllegalExtends(): void;
|
||||
}
|
||||
|
||||
export const enum TypeFormatFlags {
|
||||
|
||||
@ -53,7 +53,8 @@ namespace ts {
|
||||
decreaseIndent: noop,
|
||||
clear: () => str = "",
|
||||
trackSymbol: noop,
|
||||
reportInaccessibleThisError: noop
|
||||
reportInaccessibleThisError: noop,
|
||||
reportIllegalExtends: noop
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1166,7 +1166,8 @@ namespace ts {
|
||||
decreaseIndent: () => { indent--; },
|
||||
clear: resetWriter,
|
||||
trackSymbol: noop,
|
||||
reportInaccessibleThisError: noop
|
||||
reportInaccessibleThisError: noop,
|
||||
reportIllegalExtends: noop
|
||||
};
|
||||
|
||||
function writeIndent() {
|
||||
@ -1386,4 +1387,4 @@ namespace ts {
|
||||
// First token is the open curly, this is where we want to put the 'super' call.
|
||||
return constructor.body.getFirstToken(sourceFile).getEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user