mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-07 05:41:22 -06:00
Declare synthetic var for class extends expression
Classes that extend expressions will get a synthetic var declaration for the expression. This is required for classes that extend an expression that return an intersection type.
This commit is contained in:
parent
88f9a978dd
commit
f61ec7fb60
@ -22645,7 +22645,7 @@ namespace ts {
|
||||
const classType = <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(node));
|
||||
resolveBaseTypesOfClass(classType);
|
||||
const baseType = classType.resolvedBaseTypes.length ? classType.resolvedBaseTypes[0] : unknownType;
|
||||
if (!baseType.symbol) {
|
||||
if (!baseType.symbol && !(baseType.flags & TypeFlags.Intersection)) {
|
||||
writer.reportIllegalExtends();
|
||||
}
|
||||
getSymbolDisplayBuilder().buildTypeDisplay(baseType, writer, enclosingDeclaration, flags);
|
||||
|
||||
@ -594,12 +594,11 @@ namespace ts {
|
||||
emitLines(node.statements);
|
||||
}
|
||||
|
||||
// Return a temp variable name to be used in `export default` statements.
|
||||
// Return a temp variable name to be used in `export default`/`export class ... extends` statements.
|
||||
// The temp name will be of the form _default_counter.
|
||||
// Note that export default is only allowed at most once in a module, so we
|
||||
// do not need to keep track of created temp names.
|
||||
function getExportDefaultTempVariableName(): string {
|
||||
const baseName = "_default";
|
||||
function getExportTempVariableName(baseName: string): string {
|
||||
if (!currentIdentifiers.has(baseName)) {
|
||||
return baseName;
|
||||
}
|
||||
@ -613,24 +612,31 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitTempVariableDeclaration(expr: Expression, baseName: string, diagnostic: SymbolAccessibilityDiagnostic): string {
|
||||
const tempVarName = getExportTempVariableName(baseName);
|
||||
if (!noDeclare) {
|
||||
write("declare ");
|
||||
}
|
||||
write("var ");
|
||||
write(tempVarName);
|
||||
write(": ");
|
||||
writer.getSymbolAccessibilityDiagnostic = () => diagnostic;
|
||||
resolver.writeTypeOfExpression(expr, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
write(";");
|
||||
writeLine();
|
||||
return tempVarName;
|
||||
}
|
||||
|
||||
function emitExportAssignment(node: ExportAssignment) {
|
||||
if (node.expression.kind === SyntaxKind.Identifier) {
|
||||
write(node.isExportEquals ? "export = " : "export default ");
|
||||
writeTextOfNode(currentText, node.expression);
|
||||
}
|
||||
else {
|
||||
// Expression
|
||||
const tempVarName = getExportDefaultTempVariableName();
|
||||
if (!noDeclare) {
|
||||
write("declare ");
|
||||
}
|
||||
write("var ");
|
||||
write(tempVarName);
|
||||
write(": ");
|
||||
writer.getSymbolAccessibilityDiagnostic = getDefaultExportAccessibilityDiagnostic;
|
||||
resolver.writeTypeOfExpression(node.expression, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
write(";");
|
||||
writeLine();
|
||||
const tempVarName = emitTempVariableDeclaration(node.expression, "_default", {
|
||||
diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
|
||||
errorNode: node
|
||||
});
|
||||
write(node.isExportEquals ? "export = " : "export default ");
|
||||
write(tempVarName);
|
||||
}
|
||||
@ -644,13 +650,6 @@ namespace ts {
|
||||
// write each of these declarations asynchronously
|
||||
writeAsynchronousModuleElements(nodes);
|
||||
}
|
||||
|
||||
function getDefaultExportAccessibilityDiagnostic(): SymbolAccessibilityDiagnostic {
|
||||
return {
|
||||
diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
|
||||
errorNode: node
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function isModuleElementVisible(node: Declaration) {
|
||||
@ -1113,7 +1112,11 @@ namespace ts {
|
||||
else {
|
||||
writer.getSymbolAccessibilityDiagnostic = getHeritageClauseVisibilityError;
|
||||
errorNameNode = className;
|
||||
resolver.writeBaseConstructorTypeOfClass(<ClassLikeDeclaration>enclosingDeclaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
resolver.writeBaseConstructorTypeOfClass(
|
||||
enclosingDeclaration as ClassLikeDeclaration,
|
||||
enclosingDeclaration,
|
||||
TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue,
|
||||
writer);
|
||||
errorNameNode = undefined;
|
||||
}
|
||||
|
||||
@ -1151,21 +1154,39 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const prevEnclosingDeclaration = enclosingDeclaration;
|
||||
enclosingDeclaration = node;
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
||||
let tempVarName: string;
|
||||
if (isNonNullExpression(baseTypeNode)) {
|
||||
tempVarName = emitTempVariableDeclaration(baseTypeNode.expression, `_${node.name.text}_intersection_base`, {
|
||||
diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
|
||||
errorNode: baseTypeNode,
|
||||
typeName: node.name
|
||||
});
|
||||
}
|
||||
|
||||
emitJsDocComments(node);
|
||||
emitModuleElementDeclarationFlags(node);
|
||||
if (hasModifier(node, ModifierFlags.Abstract)) {
|
||||
write("abstract ");
|
||||
}
|
||||
|
||||
write("class ");
|
||||
writeTextOfNode(currentText, node.name);
|
||||
const prevEnclosingDeclaration = enclosingDeclaration;
|
||||
enclosingDeclaration = node;
|
||||
emitTypeParameters(node.typeParameters);
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
||||
if (baseTypeNode) {
|
||||
node.name;
|
||||
emitHeritageClause(node.name, [baseTypeNode], /*isImplementsList*/ false);
|
||||
if (isNonNullExpression(baseTypeNode)) {
|
||||
write(" extends ");
|
||||
write(tempVarName);
|
||||
if (baseTypeNode.typeArguments) {
|
||||
write("<");
|
||||
emitCommaList(baseTypeNode.typeArguments, emitType);
|
||||
write(">");
|
||||
}
|
||||
}
|
||||
else {
|
||||
emitHeritageClause(node.name, [baseTypeNode], /*isImplementsList*/ false);
|
||||
}
|
||||
}
|
||||
emitHeritageClause(node.name, getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true);
|
||||
write(" {");
|
||||
@ -1201,6 +1222,10 @@ namespace ts {
|
||||
enclosingDeclaration = prevEnclosingDeclaration;
|
||||
}
|
||||
|
||||
function isNonNullExpression(node: ExpressionWithTypeArguments) {
|
||||
return node && !isEntityNameExpression(node.expression) && node.expression.kind !== SyntaxKind.NullKeyword;
|
||||
}
|
||||
|
||||
function emitPropertyDeclaration(node: Declaration) {
|
||||
if (hasDynamicName(node)) {
|
||||
return;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user