From 22a87fb9cafce07e2701d15a95415349e161154a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Apr 2015 16:24:51 -0700 Subject: [PATCH 1/5] Class declarations should be block scoped. --- src/compiler/binder.ts | 17 +++++++---- .../classDeclarationBlockScoping1.errors.txt | 13 +++++++++ .../classDeclarationBlockScoping1.js | 22 ++++++++++++++ .../classDeclarationBlockScoping2.errors.txt | 18 ++++++++++++ .../classDeclarationBlockScoping2.js | 29 +++++++++++++++++++ .../reference/externModule.errors.txt | 14 ++++++++- .../compiler/classDeclarationBlockScoping1.ts | 7 +++++ .../compiler/classDeclarationBlockScoping2.ts | 9 ++++++ 8 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 tests/baselines/reference/classDeclarationBlockScoping1.errors.txt create mode 100644 tests/baselines/reference/classDeclarationBlockScoping1.js create mode 100644 tests/baselines/reference/classDeclarationBlockScoping2.errors.txt create mode 100644 tests/baselines/reference/classDeclarationBlockScoping2.js create mode 100644 tests/cases/compiler/classDeclarationBlockScoping1.ts create mode 100644 tests/cases/compiler/classDeclarationBlockScoping2.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 0ae33d08fd..494570c85c 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -388,23 +388,28 @@ module ts { bindChildren(node, /*symbolKind:*/ 0, /*isBlockScopeContainer:*/ true); } - function bindBlockScopedVariableDeclaration(node: Declaration) { + function bindBlockScopedDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) { switch (blockScopeContainer.kind) { case SyntaxKind.ModuleDeclaration: - declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); + declareModuleMember(node, symbolKind, symbolExcludes); break; case SyntaxKind.SourceFile: if (isExternalModule(container)) { - declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); + declareModuleMember(node, symbolKind, symbolExcludes); break; } + // fall through. default: if (!blockScopeContainer.locals) { blockScopeContainer.locals = {}; } - declareSymbol(blockScopeContainer.locals, undefined, node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); + declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, symbolExcludes); } - bindChildren(node, SymbolFlags.BlockScopedVariable, /*isBlockScopeContainer*/ false); + bindChildren(node, symbolKind, /*isBlockScopeContainer*/ false); + } + + function bindBlockScopedVariableDeclaration(node: Declaration) { + bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); } function getDestructuringParameterName(node: Declaration) { @@ -493,7 +498,7 @@ module ts { bindCatchVariableDeclaration(node); break; case SyntaxKind.ClassDeclaration: - bindDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes, /*isBlockScopeContainer*/ false); + bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); break; case SyntaxKind.InterfaceDeclaration: bindDeclaration(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes, /*isBlockScopeContainer*/ false); diff --git a/tests/baselines/reference/classDeclarationBlockScoping1.errors.txt b/tests/baselines/reference/classDeclarationBlockScoping1.errors.txt new file mode 100644 index 0000000000..4f15007bb2 --- /dev/null +++ b/tests/baselines/reference/classDeclarationBlockScoping1.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/classDeclarationBlockScoping1.ts(5,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. + + +==== tests/cases/compiler/classDeclarationBlockScoping1.ts (1 errors) ==== + class C { + } + + { + class C { + ~ +!!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/classDeclarationBlockScoping1.js b/tests/baselines/reference/classDeclarationBlockScoping1.js new file mode 100644 index 0000000000..717c2f788c --- /dev/null +++ b/tests/baselines/reference/classDeclarationBlockScoping1.js @@ -0,0 +1,22 @@ +//// [classDeclarationBlockScoping1.ts] +class C { +} + +{ + class C { + } +} + +//// [classDeclarationBlockScoping1.js] +var C = (function () { + function C() { + } + return C; +})(); +{ + var C = (function () { + function C() { + } + return C; + })(); +} diff --git a/tests/baselines/reference/classDeclarationBlockScoping2.errors.txt b/tests/baselines/reference/classDeclarationBlockScoping2.errors.txt new file mode 100644 index 0000000000..2a9885e110 --- /dev/null +++ b/tests/baselines/reference/classDeclarationBlockScoping2.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/classDeclarationBlockScoping2.ts(2,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. +tests/cases/compiler/classDeclarationBlockScoping2.ts(5,15): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. + + +==== tests/cases/compiler/classDeclarationBlockScoping2.ts (2 errors) ==== + function f() { + class C {} + ~ +!!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. + var c1 = C; + { + class C {} + ~ +!!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. + var c2 = C; + } + return C === c1; + } \ No newline at end of file diff --git a/tests/baselines/reference/classDeclarationBlockScoping2.js b/tests/baselines/reference/classDeclarationBlockScoping2.js new file mode 100644 index 0000000000..9e46807711 --- /dev/null +++ b/tests/baselines/reference/classDeclarationBlockScoping2.js @@ -0,0 +1,29 @@ +//// [classDeclarationBlockScoping2.ts] +function f() { + class C {} + var c1 = C; + { + class C {} + var c2 = C; + } + return C === c1; +} + +//// [classDeclarationBlockScoping2.js] +function f() { + var C = (function () { + function C() { + } + return C; + })(); + var c1 = C; + { + var C = (function () { + function C() { + } + return C; + })(); + var c2 = C; + } + return C === c1; +} diff --git a/tests/baselines/reference/externModule.errors.txt b/tests/baselines/reference/externModule.errors.txt index d16c71ab05..8d4126350c 100644 --- a/tests/baselines/reference/externModule.errors.txt +++ b/tests/baselines/reference/externModule.errors.txt @@ -8,9 +8,13 @@ tests/cases/compiler/externModule.ts(18,6): error TS2390: Constructor implementa tests/cases/compiler/externModule.ts(20,13): error TS2391: Function implementation is missing or not immediately following the declaration. tests/cases/compiler/externModule.ts(26,13): error TS2391: Function implementation is missing or not immediately following the declaration. tests/cases/compiler/externModule.ts(28,13): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/compiler/externModule.ts(32,11): error TS2304: Cannot find name 'XDate'. +tests/cases/compiler/externModule.ts(34,7): error TS2304: Cannot find name 'XDate'. +tests/cases/compiler/externModule.ts(36,7): error TS2304: Cannot find name 'XDate'. +tests/cases/compiler/externModule.ts(37,3): error TS2304: Cannot find name 'XDate'. -==== tests/cases/compiler/externModule.ts (10 errors) ==== +==== tests/cases/compiler/externModule.ts (14 errors) ==== declare module { ~~~~~~~ !!! error TS2304: Cannot find name 'declare'. @@ -63,10 +67,18 @@ tests/cases/compiler/externModule.ts(28,13): error TS2391: Function implementati } var d=new XDate(); + ~~~~~ +!!! error TS2304: Cannot find name 'XDate'. d.getDay(); d=new XDate(1978,2); + ~~~~~ +!!! error TS2304: Cannot find name 'XDate'. d.getXDate(); var n=XDate.parse("3/2/2004"); + ~~~~~ +!!! error TS2304: Cannot find name 'XDate'. n=XDate.UTC(1964,2,1); + ~~~~~ +!!! error TS2304: Cannot find name 'XDate'. \ No newline at end of file diff --git a/tests/cases/compiler/classDeclarationBlockScoping1.ts b/tests/cases/compiler/classDeclarationBlockScoping1.ts new file mode 100644 index 0000000000..b6012f785b --- /dev/null +++ b/tests/cases/compiler/classDeclarationBlockScoping1.ts @@ -0,0 +1,7 @@ +class C { +} + +{ + class C { + } +} \ No newline at end of file diff --git a/tests/cases/compiler/classDeclarationBlockScoping2.ts b/tests/cases/compiler/classDeclarationBlockScoping2.ts new file mode 100644 index 0000000000..2a0c4c1213 --- /dev/null +++ b/tests/cases/compiler/classDeclarationBlockScoping2.ts @@ -0,0 +1,9 @@ +function f() { + class C {} + var c1 = C; + { + class C {} + var c2 = C; + } + return C === c1; +} \ No newline at end of file From ba8be9eef4a8e0a17467609f143e741ed8f9317f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Apr 2015 17:20:20 -0700 Subject: [PATCH 2/5] Support classes without names in our AST. Report any issues with this at 'check' time. --- src/compiler/checker.ts | 7 ++++++- src/compiler/diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/parser.ts | 2 +- src/services/navigationBar.ts | 6 +++--- .../reference/anonymousClassExpression1.errors.txt | 9 +++++++++ .../reference/anonymousClassExpression1.js | 13 +++++++++++++ .../classDeclarationBlockScoping1.errors.txt | 4 ++-- .../classDeclarationBlockScoping2.errors.txt | 8 ++++---- .../reference/classExpressionTest1.errors.txt | 4 ++-- .../baselines/reference/classInsideBlock.errors.txt | 4 ++-- .../classWithPredefinedTypesAsNames2.errors.txt | 4 ++-- .../reference/classWithPredefinedTypesAsNames2.js | 6 +++--- ...objectTypesWithPredefinedTypesAsName2.errors.txt | 4 ++-- .../objectTypesWithPredefinedTypesAsName2.js | 6 +++--- ...validIdentifiersInVariableStatements1.errors.txt | 4 ++-- ...parserInvalidIdentifiersInVariableStatements1.js | 6 +++--- tests/cases/compiler/anonymousClassExpression1.ts | 3 +++ .../cases/fourslash/scriptLexicalStructureItems2.ts | 2 +- .../fourslash/scriptLexicalStructureMissingName2.ts | 2 +- 20 files changed, 67 insertions(+), 32 deletions(-) create mode 100644 tests/baselines/reference/anonymousClassExpression1.errors.txt create mode 100644 tests/baselines/reference/anonymousClassExpression1.js create mode 100644 tests/cases/compiler/anonymousClassExpression1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3ce7fe5e1c..f9d91ab083 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9757,7 +9757,12 @@ module ts { function checkClassDeclaration(node: ClassDeclaration) { // Grammar checking if (node.parent.kind !== SyntaxKind.ModuleBlock && node.parent.kind !== SyntaxKind.SourceFile) { - grammarErrorOnNode(node, Diagnostics.class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration); + grammarErrorOnFirstToken(node, Diagnostics.class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration); + } + + // node.flags & NodeFlags.Default || kind === SyntaxKind.ClassExpression + if (!node.name && !(node.flags & NodeFlags.Default)) { + grammarErrorOnNode(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkGrammarClassDeclarationHeritageClauses(node); diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 3e9017786e..b141ce607f 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -167,6 +167,7 @@ module ts { Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: { code: 1207, category: DiagnosticCategory.Error, key: "Decorators cannot be applied to multiple get/set accessors of the same name." }, Cannot_compile_non_external_modules_when_the_separateCompilation_flag_is_provided: { code: 1208, category: DiagnosticCategory.Error, key: "Cannot compile non-external modules when the '--separateCompilation' flag is provided." }, Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided: { code: 1209, category: DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--separateCompilation' flag is provided." }, + A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1210, category: DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f6edb3150b..cafc1f5efa 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -659,6 +659,10 @@ "category": "Error", "code": 1209 }, + "A class declaration without the 'default' modifier must have a name": { + "category": "Error", + "code": 1210 + }, "Duplicate identifier '{0}'.": { "category": "Error", "code": 2300 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 2972fba397..7a28ad0441 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4764,7 +4764,7 @@ module ts { node.decorators = decorators; setModifiers(node, modifiers); parseExpected(SyntaxKind.ClassKeyword); - node.name = node.flags & NodeFlags.Default ? parseOptionalIdentifier() : parseIdentifier(); + node.name = parseOptionalIdentifier(); node.typeParameters = parseTypeParameters(); node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause:*/ true); diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index c6463aba73..e475827837 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -418,10 +418,10 @@ module ts.NavigationBar { } function createFunctionItem(node: FunctionDeclaration) { - if ((node.name || node.flags & NodeFlags.Default) && node.body && node.body.kind === SyntaxKind.Block) { + if (node.body && node.body.kind === SyntaxKind.Block) { let childItems = getItemsWorker(sortNodes((node.body).statements), createChildItem); - return getNavigationBarItem((!node.name && node.flags & NodeFlags.Default) ? "default": node.name.text , + return getNavigationBarItem(!node.name ? "default": node.name.text , ts.ScriptElementKind.functionElement, getNodeModifiers(node), [getNodeSpan(node)], @@ -470,7 +470,7 @@ module ts.NavigationBar { childItems = getItemsWorker(sortNodes(nodes), createChildItem); } - var nodeName = !node.name && (node.flags & NodeFlags.Default) ? "default" : node.name.text; + var nodeName = !node.name ? "default" : node.name.text; return getNavigationBarItem( nodeName, diff --git a/tests/baselines/reference/anonymousClassExpression1.errors.txt b/tests/baselines/reference/anonymousClassExpression1.errors.txt new file mode 100644 index 0000000000..db4c5b4ce3 --- /dev/null +++ b/tests/baselines/reference/anonymousClassExpression1.errors.txt @@ -0,0 +1,9 @@ +tests/cases/compiler/anonymousClassExpression1.ts(2,19): error TS9003: 'class' expressions are not currently supported. + + +==== tests/cases/compiler/anonymousClassExpression1.ts (1 errors) ==== + function f() { + return typeof class {} === "function"; + ~~~~~ +!!! error TS9003: 'class' expressions are not currently supported. + } \ No newline at end of file diff --git a/tests/baselines/reference/anonymousClassExpression1.js b/tests/baselines/reference/anonymousClassExpression1.js new file mode 100644 index 0000000000..a796b126a0 --- /dev/null +++ b/tests/baselines/reference/anonymousClassExpression1.js @@ -0,0 +1,13 @@ +//// [anonymousClassExpression1.ts] +function f() { + return typeof class {} === "function"; +} + +//// [anonymousClassExpression1.js] +function f() { + return typeof (function () { + function () { + } + return ; + })() === "function"; +} diff --git a/tests/baselines/reference/classDeclarationBlockScoping1.errors.txt b/tests/baselines/reference/classDeclarationBlockScoping1.errors.txt index 4f15007bb2..367e53c066 100644 --- a/tests/baselines/reference/classDeclarationBlockScoping1.errors.txt +++ b/tests/baselines/reference/classDeclarationBlockScoping1.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/classDeclarationBlockScoping1.ts(5,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. +tests/cases/compiler/classDeclarationBlockScoping1.ts(5,5): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. ==== tests/cases/compiler/classDeclarationBlockScoping1.ts (1 errors) ==== @@ -7,7 +7,7 @@ tests/cases/compiler/classDeclarationBlockScoping1.ts(5,11): error TS9004: 'clas { class C { - ~ + ~~~~~ !!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. } } \ No newline at end of file diff --git a/tests/baselines/reference/classDeclarationBlockScoping2.errors.txt b/tests/baselines/reference/classDeclarationBlockScoping2.errors.txt index 2a9885e110..a6d320fa41 100644 --- a/tests/baselines/reference/classDeclarationBlockScoping2.errors.txt +++ b/tests/baselines/reference/classDeclarationBlockScoping2.errors.txt @@ -1,16 +1,16 @@ -tests/cases/compiler/classDeclarationBlockScoping2.ts(2,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. -tests/cases/compiler/classDeclarationBlockScoping2.ts(5,15): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. +tests/cases/compiler/classDeclarationBlockScoping2.ts(2,5): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. +tests/cases/compiler/classDeclarationBlockScoping2.ts(5,9): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. ==== tests/cases/compiler/classDeclarationBlockScoping2.ts (2 errors) ==== function f() { class C {} - ~ + ~~~~~ !!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. var c1 = C; { class C {} - ~ + ~~~~~ !!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. var c2 = C; } diff --git a/tests/baselines/reference/classExpressionTest1.errors.txt b/tests/baselines/reference/classExpressionTest1.errors.txt index 4d7e1cda63..2da1f0427c 100644 --- a/tests/baselines/reference/classExpressionTest1.errors.txt +++ b/tests/baselines/reference/classExpressionTest1.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/classExpressionTest1.ts(2,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. +tests/cases/compiler/classExpressionTest1.ts(2,5): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. ==== tests/cases/compiler/classExpressionTest1.ts (1 errors) ==== function M() { class C { - ~ + ~~~~~ !!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. f() { var t: T; diff --git a/tests/baselines/reference/classInsideBlock.errors.txt b/tests/baselines/reference/classInsideBlock.errors.txt index 369e77735e..8fb8e165b1 100644 --- a/tests/baselines/reference/classInsideBlock.errors.txt +++ b/tests/baselines/reference/classInsideBlock.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/classes/classDeclarations/classInsideBlock.ts(2,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. +tests/cases/conformance/classes/classDeclarations/classInsideBlock.ts(2,5): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. ==== tests/cases/conformance/classes/classDeclarations/classInsideBlock.ts (1 errors) ==== function foo() { class C { } - ~ + ~~~~~ !!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. } \ No newline at end of file diff --git a/tests/baselines/reference/classWithPredefinedTypesAsNames2.errors.txt b/tests/baselines/reference/classWithPredefinedTypesAsNames2.errors.txt index 73cb373180..84c258b550 100644 --- a/tests/baselines/reference/classWithPredefinedTypesAsNames2.errors.txt +++ b/tests/baselines/reference/classWithPredefinedTypesAsNames2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/classes/classDeclarations/classWithPredefinedTypesAsNames2.ts(3,7): error TS1003: Identifier expected. +tests/cases/conformance/classes/classDeclarations/classWithPredefinedTypesAsNames2.ts(3,7): error TS1005: '{' expected. ==== tests/cases/conformance/classes/classDeclarations/classWithPredefinedTypesAsNames2.ts (1 errors) ==== @@ -6,4 +6,4 @@ tests/cases/conformance/classes/classDeclarations/classWithPredefinedTypesAsName class void {} ~~~~ -!!! error TS1003: Identifier expected. \ No newline at end of file +!!! error TS1005: '{' expected. \ No newline at end of file diff --git a/tests/baselines/reference/classWithPredefinedTypesAsNames2.js b/tests/baselines/reference/classWithPredefinedTypesAsNames2.js index a47adcbe32..91ff735acc 100644 --- a/tests/baselines/reference/classWithPredefinedTypesAsNames2.js +++ b/tests/baselines/reference/classWithPredefinedTypesAsNames2.js @@ -5,9 +5,9 @@ class void {} //// [classWithPredefinedTypesAsNames2.js] // classes cannot use predefined types as names -var = (function () { - function () { +var default_1 = (function () { + function default_1() { } - return ; + return default_1; })(); void {}; diff --git a/tests/baselines/reference/objectTypesWithPredefinedTypesAsName2.errors.txt b/tests/baselines/reference/objectTypesWithPredefinedTypesAsName2.errors.txt index 32a693abdc..f2dbd67230 100644 --- a/tests/baselines/reference/objectTypesWithPredefinedTypesAsName2.errors.txt +++ b/tests/baselines/reference/objectTypesWithPredefinedTypesAsName2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/specifyingTypes/predefinedTypes/objectTypesWithPredefinedTypesAsName2.ts(3,7): error TS1003: Identifier expected. +tests/cases/conformance/types/specifyingTypes/predefinedTypes/objectTypesWithPredefinedTypesAsName2.ts(3,7): error TS1005: '{' expected. ==== tests/cases/conformance/types/specifyingTypes/predefinedTypes/objectTypesWithPredefinedTypesAsName2.ts (1 errors) ==== @@ -6,4 +6,4 @@ tests/cases/conformance/types/specifyingTypes/predefinedTypes/objectTypesWithPre class void {} // parse error unlike the others ~~~~ -!!! error TS1003: Identifier expected. \ No newline at end of file +!!! error TS1005: '{' expected. \ No newline at end of file diff --git a/tests/baselines/reference/objectTypesWithPredefinedTypesAsName2.js b/tests/baselines/reference/objectTypesWithPredefinedTypesAsName2.js index b47901b2f0..974744f187 100644 --- a/tests/baselines/reference/objectTypesWithPredefinedTypesAsName2.js +++ b/tests/baselines/reference/objectTypesWithPredefinedTypesAsName2.js @@ -5,9 +5,9 @@ class void {} // parse error unlike the others //// [objectTypesWithPredefinedTypesAsName2.js] // it is an error to use a predefined type as a type name -var = (function () { - function () { +var default_1 = (function () { + function default_1() { } - return ; + return default_1; })(); void {}; // parse error unlike the others diff --git a/tests/baselines/reference/parserInvalidIdentifiersInVariableStatements1.errors.txt b/tests/baselines/reference/parserInvalidIdentifiersInVariableStatements1.errors.txt index 35b279b443..d7245fc708 100644 --- a/tests/baselines/reference/parserInvalidIdentifiersInVariableStatements1.errors.txt +++ b/tests/baselines/reference/parserInvalidIdentifiersInVariableStatements1.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInvalidIdentifiersInVariableStatements1.ts(1,5): error TS1134: Variable declaration expected. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInvalidIdentifiersInVariableStatements1.ts(3,5): error TS1134: Variable declaration expected. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInvalidIdentifiersInVariableStatements1.ts(3,10): error TS1003: Identifier expected. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInvalidIdentifiersInVariableStatements1.ts(3,10): error TS1005: '{' expected. ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInvalidIdentifiersInVariableStatements1.ts (3 errors) ==== @@ -12,6 +12,6 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInv ~~~~~ !!! error TS1134: Variable declaration expected. ~ -!!! error TS1003: Identifier expected. +!!! error TS1005: '{' expected. var bar; \ No newline at end of file diff --git a/tests/baselines/reference/parserInvalidIdentifiersInVariableStatements1.js b/tests/baselines/reference/parserInvalidIdentifiersInVariableStatements1.js index 422b012246..e6b9c9fa1b 100644 --- a/tests/baselines/reference/parserInvalidIdentifiersInVariableStatements1.js +++ b/tests/baselines/reference/parserInvalidIdentifiersInVariableStatements1.js @@ -9,10 +9,10 @@ var bar; var ; var foo; var ; -var = (function () { - function () { +var default_1 = (function () { + function default_1() { } - return ; + return default_1; })(); ; var bar; diff --git a/tests/cases/compiler/anonymousClassExpression1.ts b/tests/cases/compiler/anonymousClassExpression1.ts new file mode 100644 index 0000000000..594ac09251 --- /dev/null +++ b/tests/cases/compiler/anonymousClassExpression1.ts @@ -0,0 +1,3 @@ +function f() { + return typeof class {} === "function"; +} \ No newline at end of file diff --git a/tests/cases/fourslash/scriptLexicalStructureItems2.ts b/tests/cases/fourslash/scriptLexicalStructureItems2.ts index 7022c082ce..3b94260ddb 100644 --- a/tests/cases/fourslash/scriptLexicalStructureItems2.ts +++ b/tests/cases/fourslash/scriptLexicalStructureItems2.ts @@ -8,5 +8,5 @@ edit.insertLine("module A"); edit.insert("export class "); // should not crash -verify.getScriptLexicalStructureListCount(1); +verify.getScriptLexicalStructureListCount(2); diff --git a/tests/cases/fourslash/scriptLexicalStructureMissingName2.ts b/tests/cases/fourslash/scriptLexicalStructureMissingName2.ts index b805427ff6..bf0dc03899 100644 --- a/tests/cases/fourslash/scriptLexicalStructureMissingName2.ts +++ b/tests/cases/fourslash/scriptLexicalStructureMissingName2.ts @@ -8,4 +8,4 @@ // The class is unnamed, so its method is not included either. -verify.getScriptLexicalStructureListCount(0); +verify.getScriptLexicalStructureListCount(2); From 189482e730bbb4cc5b5b081923ebefb141ca15c3 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Apr 2015 17:28:59 -0700 Subject: [PATCH 3/5] Produce a name for anonymous class expressions when we perform downlevel emit. --- src/compiler/emitter.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6ec4ea2389..5d4bf9df3e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -262,6 +262,7 @@ module ts { switch (node.kind) { case SyntaxKind.FunctionDeclaration: case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: generateNameForFunctionOrClassDeclaration(node); break; case SyntaxKind.ModuleDeclaration: From 2eddf310dc37c4d4f6982da3c5a65f69bba3dc07 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 1 Apr 2015 18:56:57 -0700 Subject: [PATCH 4/5] Fix error spans for classes. --- src/compiler/checker.ts | 5 ++--- .../reference/classDeclarationBlockScoping1.errors.txt | 4 ++-- .../reference/classDeclarationBlockScoping2.errors.txt | 8 ++++---- tests/baselines/reference/classExpressionTest1.errors.txt | 4 ++-- tests/baselines/reference/classInsideBlock.errors.txt | 4 ++-- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f9d91ab083..f0882a51c4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9757,12 +9757,11 @@ module ts { function checkClassDeclaration(node: ClassDeclaration) { // Grammar checking if (node.parent.kind !== SyntaxKind.ModuleBlock && node.parent.kind !== SyntaxKind.SourceFile) { - grammarErrorOnFirstToken(node, Diagnostics.class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration); + grammarErrorOnNode(node, Diagnostics.class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration); } - // node.flags & NodeFlags.Default || kind === SyntaxKind.ClassExpression if (!node.name && !(node.flags & NodeFlags.Default)) { - grammarErrorOnNode(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); + grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkGrammarClassDeclarationHeritageClauses(node); diff --git a/tests/baselines/reference/classDeclarationBlockScoping1.errors.txt b/tests/baselines/reference/classDeclarationBlockScoping1.errors.txt index 367e53c066..4f15007bb2 100644 --- a/tests/baselines/reference/classDeclarationBlockScoping1.errors.txt +++ b/tests/baselines/reference/classDeclarationBlockScoping1.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/classDeclarationBlockScoping1.ts(5,5): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. +tests/cases/compiler/classDeclarationBlockScoping1.ts(5,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. ==== tests/cases/compiler/classDeclarationBlockScoping1.ts (1 errors) ==== @@ -7,7 +7,7 @@ tests/cases/compiler/classDeclarationBlockScoping1.ts(5,5): error TS9004: 'class { class C { - ~~~~~ + ~ !!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. } } \ No newline at end of file diff --git a/tests/baselines/reference/classDeclarationBlockScoping2.errors.txt b/tests/baselines/reference/classDeclarationBlockScoping2.errors.txt index a6d320fa41..2a9885e110 100644 --- a/tests/baselines/reference/classDeclarationBlockScoping2.errors.txt +++ b/tests/baselines/reference/classDeclarationBlockScoping2.errors.txt @@ -1,16 +1,16 @@ -tests/cases/compiler/classDeclarationBlockScoping2.ts(2,5): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. -tests/cases/compiler/classDeclarationBlockScoping2.ts(5,9): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. +tests/cases/compiler/classDeclarationBlockScoping2.ts(2,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. +tests/cases/compiler/classDeclarationBlockScoping2.ts(5,15): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. ==== tests/cases/compiler/classDeclarationBlockScoping2.ts (2 errors) ==== function f() { class C {} - ~~~~~ + ~ !!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. var c1 = C; { class C {} - ~~~~~ + ~ !!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. var c2 = C; } diff --git a/tests/baselines/reference/classExpressionTest1.errors.txt b/tests/baselines/reference/classExpressionTest1.errors.txt index 2da1f0427c..4d7e1cda63 100644 --- a/tests/baselines/reference/classExpressionTest1.errors.txt +++ b/tests/baselines/reference/classExpressionTest1.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/classExpressionTest1.ts(2,5): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. +tests/cases/compiler/classExpressionTest1.ts(2,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. ==== tests/cases/compiler/classExpressionTest1.ts (1 errors) ==== function M() { class C { - ~~~~~ + ~ !!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. f() { var t: T; diff --git a/tests/baselines/reference/classInsideBlock.errors.txt b/tests/baselines/reference/classInsideBlock.errors.txt index 8fb8e165b1..369e77735e 100644 --- a/tests/baselines/reference/classInsideBlock.errors.txt +++ b/tests/baselines/reference/classInsideBlock.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/classes/classDeclarations/classInsideBlock.ts(2,5): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. +tests/cases/conformance/classes/classDeclarations/classInsideBlock.ts(2,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. ==== tests/cases/conformance/classes/classDeclarations/classInsideBlock.ts (1 errors) ==== function foo() { class C { } - ~~~~~ + ~ !!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration. } \ No newline at end of file From d048d7d3d27a6eb61837b221ad73538a83b29397 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 2 Apr 2015 13:59:53 -0700 Subject: [PATCH 5/5] Fix tests. --- tests/baselines/reference/anonymousClassExpression1.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/anonymousClassExpression1.js b/tests/baselines/reference/anonymousClassExpression1.js index a796b126a0..78cf5b05c5 100644 --- a/tests/baselines/reference/anonymousClassExpression1.js +++ b/tests/baselines/reference/anonymousClassExpression1.js @@ -6,8 +6,8 @@ function f() { //// [anonymousClassExpression1.js] function f() { return typeof (function () { - function () { + function default_1() { } - return ; + return default_1; })() === "function"; }