mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Parsing, binding, checking of export default with function/class
This commit is contained in:
@@ -112,10 +112,13 @@ module ts {
|
||||
return "__new";
|
||||
case SyntaxKind.IndexSignature:
|
||||
return "__index";
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return "default";
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return "__export";
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return "default";
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return node.flags & NodeFlags.Default ? "default" : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +129,7 @@ module ts {
|
||||
function declareSymbol(symbols: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
|
||||
Debug.assert(!hasDynamicName(node));
|
||||
|
||||
var name = getDeclarationName(node);
|
||||
var name = node.flags & NodeFlags.Default && parent ? "default" : getDeclarationName(node);
|
||||
if (name !== undefined) {
|
||||
var symbol = hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(0, name));
|
||||
if (symbol.flags & excludes) {
|
||||
|
||||
+29
-8
@@ -8268,7 +8268,7 @@ module ts {
|
||||
// Do not use hasDynamicName here, because that returns false for well known symbols.
|
||||
// We want to perform checkComputedPropertyName for all computed properties, including
|
||||
// well known symbols.
|
||||
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
if (node.name && node.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
// This check will account for methods in class/interface declarations,
|
||||
// as well as accessors in classes/object literals
|
||||
checkComputedPropertyName(<ComputedPropertyName>node.name);
|
||||
@@ -8998,10 +8998,12 @@ module ts {
|
||||
// Grammar checking
|
||||
checkGrammarClassDeclarationHeritageClauses(node);
|
||||
|
||||
checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0);
|
||||
if (node.name) {
|
||||
checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0);
|
||||
checkCollisionWithCapturedThisVariable(node, node.name);
|
||||
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
|
||||
}
|
||||
checkTypeParameters(node.typeParameters);
|
||||
checkCollisionWithCapturedThisVariable(node, node.name);
|
||||
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
|
||||
checkExportsOnMergedDeclarations(node);
|
||||
var symbol = getSymbolOfNode(node);
|
||||
var type = <InterfaceType>getDeclaredTypeOfSymbol(symbol);
|
||||
@@ -9014,9 +9016,9 @@ module ts {
|
||||
if (type.baseTypes.length) {
|
||||
if (produceDiagnostics) {
|
||||
var baseType = type.baseTypes[0];
|
||||
checkTypeAssignableTo(type, baseType, node.name, Diagnostics.Class_0_incorrectly_extends_base_class_1);
|
||||
checkTypeAssignableTo(type, baseType, node.name || node, Diagnostics.Class_0_incorrectly_extends_base_class_1);
|
||||
var staticBaseType = getTypeOfSymbol(baseType.symbol);
|
||||
checkTypeAssignableTo(staticType, getTypeWithoutConstructors(staticBaseType), node.name,
|
||||
checkTypeAssignableTo(staticType, getTypeWithoutConstructors(staticBaseType), node.name || node,
|
||||
Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1);
|
||||
if (baseType.symbol !== resolveEntityName(baseTypeNode.typeName, SymbolFlags.Value)) {
|
||||
error(baseTypeNode, Diagnostics.Type_name_0_in_extends_clause_does_not_reference_constructor_function_for_0, typeToString(baseType));
|
||||
@@ -9038,7 +9040,7 @@ module ts {
|
||||
if (t !== unknownType) {
|
||||
var declaredType = (t.flags & TypeFlags.Reference) ? (<TypeReference>t).target : t;
|
||||
if (declaredType.flags & (TypeFlags.Class | TypeFlags.Interface)) {
|
||||
checkTypeAssignableTo(type, t, node.name, Diagnostics.Class_0_incorrectly_implements_interface_1);
|
||||
checkTypeAssignableTo(type, t, node.name || node, Diagnostics.Class_0_incorrectly_implements_interface_1);
|
||||
}
|
||||
else {
|
||||
error(typeRefNode, Diagnostics.A_class_may_only_implement_another_class_or_interface);
|
||||
@@ -10414,6 +10416,10 @@ module ts {
|
||||
|
||||
function generateNames(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
generateNameForFunctionOrClassDeclaration(<Declaration>node);
|
||||
break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
generateNameForModuleOrEnum(<ModuleDeclaration>node);
|
||||
generateNames((<ModuleDeclaration>node).body);
|
||||
@@ -10427,6 +10433,9 @@ module ts {
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
generateNameForExportDeclaration(<ExportDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
generateNameForExportAssignment(<ExportAssignment>node);
|
||||
break;
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
forEach((<SourceFile | ModuleBlock>node).statements, generateNames);
|
||||
@@ -10464,6 +10473,12 @@ module ts {
|
||||
getNodeLinks(node).generatedName = unescapeIdentifier(name);
|
||||
}
|
||||
|
||||
function generateNameForFunctionOrClassDeclaration(node: Declaration) {
|
||||
if (!node.name) {
|
||||
assignGeneratedName(node, makeUniqueName("default"));
|
||||
}
|
||||
}
|
||||
|
||||
function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) {
|
||||
if (node.name.kind === SyntaxKind.Identifier) {
|
||||
var name = node.name.text;
|
||||
@@ -10490,9 +10505,15 @@ module ts {
|
||||
generateNameForImportOrExportDeclaration(node);
|
||||
}
|
||||
}
|
||||
|
||||
function generateNameForExportAssignment(node: ExportAssignment) {
|
||||
if (node.expression.kind !== SyntaxKind.Identifier) {
|
||||
assignGeneratedName(node, makeUniqueName("default"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getGeneratedNameForNode(node: ModuleDeclaration | EnumDeclaration | ImportDeclaration | ExportDeclaration) {
|
||||
function getGeneratedNameForNode(node: Node) {
|
||||
var links = getNodeLinks(node);
|
||||
if (!links.generatedName) {
|
||||
getGeneratedNamesForSourceFile(getSourceFile(node));
|
||||
|
||||
+15
-8
@@ -1580,7 +1580,7 @@ module ts {
|
||||
var tempParameters: Identifier[];
|
||||
var externalImports: ExternalImportInfo[];
|
||||
var exportSpecifiers: Map<ExportSpecifier[]>;
|
||||
var exportDefault: ExportAssignment | ExportSpecifier;
|
||||
var exportDefault: FunctionDeclaration | ClassDeclaration | ExportAssignment | ExportSpecifier;
|
||||
|
||||
/** write emitted output to disk*/
|
||||
var writeEmittedFiles = writeJavaScriptFile;
|
||||
@@ -3912,7 +3912,7 @@ module ts {
|
||||
emitExpressionFunctionBody(node, <Expression>node.body);
|
||||
}
|
||||
|
||||
if (node.flags & NodeFlags.Export) {
|
||||
if (node.flags & NodeFlags.Export && !(node.flags & NodeFlags.Default)) {
|
||||
writeLine();
|
||||
emitStart(node);
|
||||
emitModuleMemberName(node);
|
||||
@@ -4243,11 +4243,10 @@ module ts {
|
||||
emitMemberFunctions(node);
|
||||
emitMemberAssignments(node, NodeFlags.Static);
|
||||
writeLine();
|
||||
function emitClassReturnStatement() {
|
||||
emitToken(SyntaxKind.CloseBraceToken, node.members.end, () => {
|
||||
write("return ");
|
||||
emitNode(node.name);
|
||||
}
|
||||
emitToken(SyntaxKind.CloseBraceToken, node.members.end, emitClassReturnStatement);
|
||||
});
|
||||
write(";");
|
||||
decreaseIndent();
|
||||
writeLine();
|
||||
@@ -4260,7 +4259,7 @@ module ts {
|
||||
}
|
||||
write(");");
|
||||
emitEnd(node);
|
||||
if (node.flags & NodeFlags.Export) {
|
||||
if (node.flags & NodeFlags.Export && !(node.flags & NodeFlags.Default)) {
|
||||
writeLine();
|
||||
emitStart(node);
|
||||
emitModuleMemberName(node);
|
||||
@@ -4269,7 +4268,7 @@ module ts {
|
||||
emitEnd(node);
|
||||
write(";");
|
||||
}
|
||||
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) {
|
||||
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile && node.name) {
|
||||
emitExportMemberAssignments(node.name);
|
||||
}
|
||||
|
||||
@@ -4680,6 +4679,11 @@ module ts {
|
||||
else if (node.kind === SyntaxKind.ExportAssignment) {
|
||||
exportDefault = exportDefault || <ExportAssignment>node;
|
||||
}
|
||||
else if (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.ClassDeclaration) {
|
||||
if (node.flags & NodeFlags.Export && node.flags & NodeFlags.Default) {
|
||||
exportDefault = exportDefault || <FunctionDeclaration | ClassDeclaration>node;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var info = createExternalImportInfo(node);
|
||||
if (info) {
|
||||
@@ -4788,9 +4792,12 @@ module ts {
|
||||
if (exportDefault.kind === SyntaxKind.ExportAssignment) {
|
||||
emit((<ExportAssignment>exportDefault).expression);
|
||||
}
|
||||
else {
|
||||
else if (exportDefault.kind === SyntaxKind.ExportSpecifier) {
|
||||
emit((<ExportSpecifier>exportDefault).propertyName);
|
||||
}
|
||||
else {
|
||||
emit((<Declaration>exportDefault).name);
|
||||
}
|
||||
write(";");
|
||||
emitEnd(exportDefault);
|
||||
}
|
||||
|
||||
+12
-4
@@ -358,6 +358,7 @@ module ts {
|
||||
case SyntaxKind.ExportKeyword: return NodeFlags.Export;
|
||||
case SyntaxKind.DeclareKeyword: return NodeFlags.Ambient;
|
||||
case SyntaxKind.ConstKeyword: return NodeFlags.Const;
|
||||
case SyntaxKind.DefaultKeyword: return NodeFlags.Default;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1501,11 +1502,13 @@ module ts {
|
||||
if (token === SyntaxKind.ExportKeyword) {
|
||||
nextToken();
|
||||
if (token === SyntaxKind.DefaultKeyword) {
|
||||
nextToken();
|
||||
return token === SyntaxKind.ClassKeyword || token === SyntaxKind.FunctionKeyword;
|
||||
return lookAhead(nextTokenIsClassOrFunction);
|
||||
}
|
||||
return token !== SyntaxKind.AsteriskToken && token !== SyntaxKind.OpenBraceToken && canFollowModifier();
|
||||
}
|
||||
if (token === SyntaxKind.DefaultKeyword) {
|
||||
return nextTokenIsClassOrFunction();
|
||||
}
|
||||
nextToken();
|
||||
return canFollowModifier();
|
||||
}
|
||||
@@ -1517,6 +1520,11 @@ module ts {
|
||||
|| isLiteralPropertyName();
|
||||
}
|
||||
|
||||
function nextTokenIsClassOrFunction(): boolean {
|
||||
nextToken();
|
||||
return token === SyntaxKind.ClassKeyword || token === SyntaxKind.FunctionKeyword;
|
||||
}
|
||||
|
||||
// True if positioned at the start of a list element
|
||||
function isListElement(parsingContext: ParsingContext, inErrorRecovery: boolean): boolean {
|
||||
var node = currentNode(parsingContext);
|
||||
@@ -4323,7 +4331,7 @@ module ts {
|
||||
setModifiers(node, modifiers);
|
||||
parseExpected(SyntaxKind.FunctionKeyword);
|
||||
node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
|
||||
node.name = parseIdentifier();
|
||||
node.name = node.flags & NodeFlags.Default ? parseOptionalIdentifier() : parseIdentifier();
|
||||
fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext:*/ !!node.asteriskToken, /*requireCompleteParameterList:*/ false, node);
|
||||
node.body = parseFunctionBlockOrSemicolon(!!node.asteriskToken, Diagnostics.or_expected);
|
||||
return finishNode(node);
|
||||
@@ -4499,7 +4507,7 @@ module ts {
|
||||
var node = <ClassDeclaration>createNode(SyntaxKind.ClassDeclaration, fullStart);
|
||||
setModifiers(node, modifiers);
|
||||
parseExpected(SyntaxKind.ClassKeyword);
|
||||
node.name = parseIdentifier();
|
||||
node.name = node.flags & NodeFlags.Default ? parseOptionalIdentifier() : parseIdentifier();
|
||||
node.typeParameters = parseTypeParameters();
|
||||
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause:*/ true);
|
||||
|
||||
|
||||
@@ -298,14 +298,15 @@ module ts {
|
||||
Private = 0x00000020, // Property/Method
|
||||
Protected = 0x00000040, // Property/Method
|
||||
Static = 0x00000080, // Property/Method
|
||||
MultiLine = 0x00000100, // Multi-line array or object literal
|
||||
Synthetic = 0x00000200, // Synthetic node (for full fidelity)
|
||||
DeclarationFile = 0x00000400, // Node is a .d.ts file
|
||||
Let = 0x00000800, // Variable declaration
|
||||
Const = 0x00001000, // Variable declaration
|
||||
OctalLiteral = 0x00002000,
|
||||
Default = 0x00000100, // Function/Class (export default declaration)
|
||||
MultiLine = 0x00000200, // Multi-line array or object literal
|
||||
Synthetic = 0x00000400, // Synthetic node (for full fidelity)
|
||||
DeclarationFile = 0x00000800, // Node is a .d.ts file
|
||||
Let = 0x00001000, // Variable declaration
|
||||
Const = 0x00002000, // Variable declaration
|
||||
OctalLiteral = 0x00004000,
|
||||
|
||||
Modifier = Export | Ambient | Public | Private | Protected | Static,
|
||||
Modifier = Export | Ambient | Public | Private | Protected | Static | Default,
|
||||
AccessibilityModifier = Public | Private | Protected,
|
||||
BlockScoped = Let | Const
|
||||
}
|
||||
@@ -1185,7 +1186,7 @@ module ts {
|
||||
}
|
||||
|
||||
export interface EmitResolver {
|
||||
getGeneratedNameForNode(node: ModuleDeclaration | EnumDeclaration | ImportDeclaration | ExportDeclaration): string;
|
||||
getGeneratedNameForNode(node: Node): string;
|
||||
getExpressionNameSubstitution(node: Identifier): string;
|
||||
hasExportDefaultValue(node: SourceFile): boolean;
|
||||
isReferencedImportDeclaration(node: Node): boolean;
|
||||
|
||||
@@ -901,6 +901,7 @@ module ts {
|
||||
case SyntaxKind.ExportKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user