Merge pull request #2700 from Microsoft/removeOptionalTypeOnExportDefault

Remove optional type on export default
This commit is contained in:
Mohamed Hegazy 2015-04-10 15:31:31 -07:00
commit f231d6aba8
26 changed files with 88 additions and 155 deletions

View file

@ -539,7 +539,7 @@ module ts {
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.ExportAssignment:
if ((<ExportAssignment>node).expression && (<ExportAssignment>node).expression.kind === SyntaxKind.Identifier) {
if ((<ExportAssignment>node).expression.kind === SyntaxKind.Identifier) {
// An export default clause with an identifier exports all meanings of that identifier
declareSymbol(container.symbol.exports, container.symbol, <Declaration>node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
}

View file

@ -682,7 +682,7 @@ module ts {
}
function getTargetOfExportAssignment(node: ExportAssignment): Symbol {
return node.expression && resolveEntityName(<Identifier>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
return resolveEntityName(<Identifier>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
}
function getTargetOfAliasDeclaration(node: Declaration): Symbol {
@ -748,7 +748,7 @@ module ts {
if (!links.referenced) {
links.referenced = true;
let node = getDeclarationOfAliasSymbol(symbol);
if (node.kind === SyntaxKind.ExportAssignment && (<ExportAssignment>node).expression) {
if (node.kind === SyntaxKind.ExportAssignment) {
// export default <symbol>
checkExpressionCached((<ExportAssignment>node).expression);
}
@ -2287,16 +2287,7 @@ module ts {
}
// Handle export default expressions
if (declaration.kind === SyntaxKind.ExportAssignment) {
var exportAssignment = <ExportAssignment>declaration;
if (exportAssignment.expression) {
return links.type = checkExpression(exportAssignment.expression);
}
else if (exportAssignment.type) {
return links.type = getTypeFromTypeNodeOrHeritageClauseElement(exportAssignment.type);
}
else {
return links.type = anyType;
}
return links.type = checkExpression((<ExportAssignment>declaration).expression);
}
// Handle variable, parameter or property
links.type = resolvingType;
@ -10599,21 +10590,12 @@ module ts {
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers);
}
if (node.expression) {
if (node.expression.kind === SyntaxKind.Identifier) {
markExportAsReferenced(node);
}
else {
checkExpressionCached(node.expression);
}
if (node.expression.kind === SyntaxKind.Identifier) {
markExportAsReferenced(node);
}
if (node.type) {
checkSourceElement(node.type);
if (!isInAmbientContext(node)) {
grammarErrorOnFirstToken(node.type, Diagnostics.A_type_annotation_on_an_export_statement_is_only_allowed_in_an_ambient_external_module_declaration);
}
else {
checkExpressionCached(node.expression);
}
checkExternalModuleExports(container);
if (node.isExportEquals && languageVersion >= ScriptTarget.ES6) {

View file

@ -442,20 +442,41 @@ module ts {
emitLines(node.statements);
}
// Return a temp variable name to be used in `export default` 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 {
let baseName = "_default";
if (!hasProperty(currentSourceFile.identifiers, baseName)) {
return baseName;
}
let count = 0;
while (true) {
let name = baseName + "_" + (++count);
if (!hasProperty(currentSourceFile.identifiers, name)) {
return name;
}
}
}
function emitExportAssignment(node: ExportAssignment) {
write(node.isExportEquals ? "export = " : "export default ");
if (node.expression.kind === SyntaxKind.Identifier) {
write(node.isExportEquals ? "export = " : "export default ");
writeTextOfNode(currentSourceFile, node.expression);
}
else {
// Expression
let tempVarName = getExportDefaultTempVariableName();
write("declare var ");
write(tempVarName);
write(": ");
if (node.type) {
emitType(node.type);
}
else {
writer.getSymbolAccessibilityDiagnostic = getDefaultExportAccessibilityDiagnostic;
resolver.writeTypeOfExpression(node.expression, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction, writer);
}
writer.getSymbolAccessibilityDiagnostic = getDefaultExportAccessibilityDiagnostic;
resolver.writeTypeOfExpression(node.expression, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction, writer);
write(";");
writeLine();
write(node.isExportEquals ? "export = " : "export default ");
write(tempVarName);
}
write(";");
writeLine();

View file

@ -158,7 +158,6 @@ module ts {
An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive: { code: 1198, category: DiagnosticCategory.Error, key: "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive." },
Unterminated_Unicode_escape_sequence: { code: 1199, category: DiagnosticCategory.Error, key: "Unterminated Unicode escape sequence." },
Line_terminator_not_permitted_before_arrow: { code: 1200, category: DiagnosticCategory.Error, key: "Line terminator not permitted before arrow." },
A_type_annotation_on_an_export_statement_is_only_allowed_in_an_ambient_external_module_declaration: { code: 1201, category: DiagnosticCategory.Error, key: "A type annotation on an export statement is only allowed in an ambient external module declaration." },
Import_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_or_import_d_from_mod_instead: { code: 1202, category: DiagnosticCategory.Error, key: "Import assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"' or 'import d from \"mod\"' instead." },
Export_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_export_default_instead: { code: 1203, category: DiagnosticCategory.Error, key: "Export assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'export default' instead." },
Cannot_compile_external_modules_into_amd_or_commonjs_when_targeting_es6_or_higher: { code: 1204, category: DiagnosticCategory.Error, key: "Cannot compile external modules into amd or commonjs when targeting es6 or higher." },

View file

@ -623,10 +623,6 @@
"category": "Error",
"code": 1200
},
"A type annotation on an export statement is only allowed in an ambient external module declaration.": {
"category": "Error",
"code": 1201
},
"Import assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"' or 'import d from \"mod\"' instead.": {
"category": "Error",
"code": 1202

View file

@ -299,8 +299,7 @@ module ts {
case SyntaxKind.ExportAssignment:
return visitNodes(cbNodes, node.decorators) ||
visitNodes(cbNodes, node.modifiers) ||
visitNode(cbNode, (<ExportAssignment>node).expression) ||
visitNode(cbNode, (<ExportAssignment>node).type);
visitNode(cbNode, (<ExportAssignment>node).expression);
case SyntaxKind.TemplateExpression:
return visitNode(cbNode, (<TemplateExpression>node).head) || visitNodes(cbNodes, (<TemplateExpression>node).templateSpans);
case SyntaxKind.TemplateSpan:
@ -5133,17 +5132,11 @@ module ts {
setModifiers(node, modifiers);
if (parseOptional(SyntaxKind.EqualsToken)) {
node.isExportEquals = true;
node.expression = parseAssignmentExpressionOrHigher();
}
else {
parseExpected(SyntaxKind.DefaultKeyword);
if (parseOptional(SyntaxKind.ColonToken)) {
node.type = parseType();
}
else {
node.expression = parseAssignmentExpressionOrHigher();
}
}
node.expression = parseAssignmentExpressionOrHigher();
parseSemicolon();
return finishNode(node);
}

View file

@ -975,8 +975,7 @@ module ts {
export interface ExportAssignment extends Declaration, ModuleElement {
isExportEquals?: boolean;
expression?: Expression;
type?: TypeNode;
expression: Expression;
}
export interface FileReference extends TextRange {

View file

@ -173,10 +173,6 @@ module ts.BreakpointResolver {
return textSpan(node, (<ThrowStatement>node).expression);
case SyntaxKind.ExportAssignment:
if (!(<ExportAssignment>node).expression) {
return undefined;
}
// span on export = id
return textSpan(node, (<ExportAssignment>node).expression);

View file

@ -7,4 +7,5 @@ export default 1 + 2;
//// [declarationEmitDefaultExport5.d.ts]
export default : number;
declare var _default: number;
export default _default;

View file

@ -12,4 +12,5 @@ export default new A();
//// [declarationEmitDefaultExport6.d.ts]
export declare class A {
}
export default : A;
declare var _default: A;
export default _default;

View file

@ -0,0 +1,18 @@
//// [declarationEmitDefaultExport8.ts]
var _default = 1;
export {_default as d}
export default 1 + 2;
//// [declarationEmitDefaultExport8.js]
var _default = 1;
export { _default as d };
export default 1 + 2;
//// [declarationEmitDefaultExport8.d.ts]
declare var _default: number;
export { _default as d };
declare var _default_1: number;
export default _default_1;

View file

@ -0,0 +1,12 @@
=== tests/cases/compiler/declarationEmitDefaultExport8.ts ===
var _default = 1;
>_default : number
export {_default as d}
>_default : number
>d : number
export default 1 + 2;
>1 + 2 : number

View file

@ -8,4 +8,5 @@ exports.default = (1 + 2);
//// [es5ExportDefaultExpression.d.ts]
export default : number;
declare var _default: number;
export default _default;

View file

@ -8,4 +8,5 @@ export default (1 + 2);
//// [es6ExportDefaultExpression.d.ts]
export default : number;
declare var _default: number;
export default _default;

View file

@ -45,5 +45,6 @@ var x1 = m;
export declare var a: number;
export declare var x: number;
export declare var m: number;
export default : {};
declare var _default: {};
export default _default;
//// [es6ImportDefaultBindingFollowedWithNamedImport_1.d.ts]

View file

@ -44,7 +44,8 @@ define(["require", "exports", "server", "server", "server", "server", "server"],
export declare var a: number;
export declare var x: number;
export declare var m: number;
export default : {};
declare var _default: {};
export default _default;
//// [client.d.ts]
export declare var x1: number;
export declare var x1: number;

View file

@ -1,8 +0,0 @@
tests/cases/compiler/exportDefaultTypeAnnoation.ts(2,18): error TS1201: A type annotation on an export statement is only allowed in an ambient external module declaration.
==== tests/cases/compiler/exportDefaultTypeAnnoation.ts (1 errors) ====
export default : number;
~~~~~~
!!! error TS1201: A type annotation on an export statement is only allowed in an ambient external module declaration.

View file

@ -1,6 +0,0 @@
//// [exportDefaultTypeAnnoation.ts]
export default : number;
//// [exportDefaultTypeAnnoation.js]
exports.default = ;

View file

@ -1,7 +0,0 @@
//// [exportDefaultTypeAnnoation2.ts]
declare module "mod" {
export default : number;
}
//// [exportDefaultTypeAnnoation2.js]

View file

@ -1,6 +0,0 @@
=== tests/cases/compiler/exportDefaultTypeAnnoation2.ts ===
No type information for this code.declare module "mod" {
No type information for this code. export default : number;
No type information for this code.}
No type information for this code.

View file

@ -1,21 +0,0 @@
tests/cases/compiler/reference1.ts(2,5): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/reference2.ts(2,5): error TS2322: Type 'number' is not assignable to type 'string'.
==== tests/cases/compiler/mod.d.ts (0 errors) ====
declare module "mod" {
export default : number;
}
==== tests/cases/compiler/reference1.ts (1 errors) ====
import d from "mod";
var s: string = d; // Error
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
==== tests/cases/compiler/reference2.ts (1 errors) ====
import { default as d } from "mod";
var s: string = d; // Error
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.

View file

@ -1,22 +0,0 @@
//// [tests/cases/compiler/exportDefaultTypeAnnoation3.ts] ////
//// [mod.d.ts]
declare module "mod" {
export default : number;
}
//// [reference1.ts]
import d from "mod";
var s: string = d; // Error
//// [reference2.ts]
import { default as d } from "mod";
var s: string = d; // Error
//// [reference1.js]
var mod_1 = require("mod");
var s = mod_1.default; // Error
//// [reference2.js]
var mod_1 = require("mod");
var s = mod_1.default; // Error

View file

@ -0,0 +1,6 @@
// @declaration: true
// @target: es6
var _default = 1;
export {_default as d}
export default 1 + 2;

View file

@ -1,4 +0,0 @@
// @target: es5
// @module: commonjs
export default : number;

View file

@ -1,6 +0,0 @@
// @target: es5
// @module: commonjs
declare module "mod" {
export default : number;
}

View file

@ -1,15 +0,0 @@
// @target: es5
// @module: commonjs
// @fileName: mod.d.ts
declare module "mod" {
export default : number;
}
// @fileName: reference1.ts
import d from "mod";
var s: string = d; // Error
// @fileName: reference2.ts
import { default as d } from "mod";
var s: string = d; // Error