Fix for 954635: Clodule declaration ordering

Fix for 955714: Fundule declaration ordering
This commit is contained in:
Anders Hejlsberg 2014-07-16 14:18:33 -07:00
parent 9ecf01b57a
commit e4ea5ef1f9
14 changed files with 243 additions and 5 deletions

View File

@ -5317,8 +5317,31 @@ module ts {
}
}
function getClassOrFunctionBodyDeclaration(symbol: Symbol): Declaration {
var declarations = symbol.declarations;
for (var i = 0; i < declarations.length; i++) {
var declaration = declarations[i];
if ((declaration.kind === SyntaxKind.ClassDeclaration || (declaration.kind === SyntaxKind.FunctionDeclaration && (<FunctionDeclaration>declaration).body)) && !isInAmbientContext(declaration)) {
return declaration;
}
}
// Return undefined
}
function checkModuleDeclaration(node: ModuleDeclaration) {
checkDeclarationModifiers(node);
var symbol = getSymbolOfNode(node);
if (symbol.flags & SymbolFlags.ValueModule && symbol.declarations.length > 1 && !isInAmbientContext(node)) {
var classOrFunc = getClassOrFunctionBodyDeclaration(symbol);
if (classOrFunc) {
if (getSourceFileOfNode(node) !== getSourceFileOfNode(classOrFunc)) {
error(node, Diagnostics.Module_declaration_cannot_be_in_different_file_from_class_or_function_with_which_it_is_merged);
}
else if (node.pos < classOrFunc.pos) {
error(node, Diagnostics.Module_declaration_cannot_be_located_prior_to_class_or_function_with_which_it_is_merged);
}
}
}
if (node.name.kind === SyntaxKind.StringLiteral) {
if (node.parent.kind !== SyntaxKind.SourceFile || node.parent.flags & NodeFlags.ExternalModule) {
error(node, Diagnostics.Ambient_external_modules_cannot_be_nested_in_other_modules);
@ -5326,7 +5349,6 @@ module ts {
if (isExternalModuleNameRelative(node.name.text)) {
error(node, Diagnostics.Ambient_external_module_declaration_cannot_specify_relative_module_name);
}
var symbol = getSymbolOfNode(node);
}
checkSourceElement(node.body);
}

View File

@ -279,6 +279,8 @@ module ts {
Interface_0_incorrectly_extends_interface_1: { code: -9999999, category: DiagnosticCategory.Error, key: "Interface '{0}' incorrectly extends interface '{1}'." },
Ambient_external_modules_cannot_be_nested_in_other_modules: { code: -9999999, category: DiagnosticCategory.Error, key: "Ambient external modules cannot be nested in other modules." },
Import_declarations_in_an_internal_module_cannot_reference_an_external_module: { code: -9999999, category: DiagnosticCategory.Error, key: "Import declarations in an internal module cannot reference an external module." },
Module_declaration_cannot_be_in_different_file_from_class_or_function_with_which_it_is_merged: { code: -9999999, category: DiagnosticCategory.Error, key: "Module declaration cannot be in different file from class or function with which it is merged" },
Module_declaration_cannot_be_located_prior_to_class_or_function_with_which_it_is_merged: { code: -9999999, category: DiagnosticCategory.Error, key: "Module declaration cannot be located prior to class or function with which it is merged" },
Cannot_compile_external_modules_unless_the_module_flag_is_provided: { code: -9999999, category: DiagnosticCategory.Error, key: "Cannot compile external modules unless the '--module' flag is provided." },
Import_declaration_conflicts_with_local_declaration_of_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Import declaration conflicts with local declaration of '{0}'" },
Filename_0_differs_from_already_included_filename_1_only_in_casing: { code: -9999999, category: DiagnosticCategory.Error, key: "Filename '{0}' differs from already included filename '{1}' only in casing" },

View File

@ -1140,6 +1140,14 @@
"category": "Error",
"code": -9999999
},
"Module declaration cannot be in different file from class or function with which it is merged": {
"category": "Error",
"code": -9999999
},
"Module declaration cannot be located prior to class or function with which it is merged": {
"category": "Error",
"code": -9999999
},
"Cannot compile external modules unless the '--module' flag is provided.": {
"category": "Error",
"code": -9999999

View File

@ -0,0 +1,43 @@
==== tests/cases/conformance/internalModules/DeclarationMerging/class.ts (0 errors) ====
module X.Y {
export class Point {
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
x: number;
y: number;
}
}
==== tests/cases/conformance/internalModules/DeclarationMerging/module.ts (1 errors) ====
module X.Y {
export module Point {
~~~~~~~~~~~~~~~~~~~~~
export var Origin = new Point(0, 0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
~~~~~
!!! Module declaration cannot be in different file from class or function with which it is merged
}
==== tests/cases/conformance/internalModules/DeclarationMerging/test.ts (0 errors) ====
//var cl: { x: number; y: number; }
var cl = new X.Y.Point(1,1);
var cl = X.Y.Point.Origin; // error not expected here same as bug 83996 ?
==== tests/cases/conformance/internalModules/DeclarationMerging/simple.ts (0 errors) ====
class A {
id: string;
}
module A {
export var Instance = new A();
}
// ensure merging works as expected
var a = A.Instance;
var a = new A();
var a: { id: string };

View File

@ -5,11 +5,15 @@
}
}
==== tests/cases/conformance/internalModules/DeclarationMerging/module.ts (0 errors) ====
==== tests/cases/conformance/internalModules/DeclarationMerging/module.ts (1 errors) ====
module A {
export module Point {
~~~~~~~~~~~~~~~~~~~~~
export var Origin = { x: 0, y: 0 };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
~~~~~
!!! Module declaration cannot be in different file from class or function with which it is merged
}
==== tests/cases/conformance/internalModules/DeclarationMerging/test.ts (1 errors) ====

View File

@ -0,0 +1,38 @@
==== tests/cases/conformance/internalModules/DeclarationMerging/module.ts (1 errors) ====
module X.Y {
export module Point {
~~~~~~~~~~~~~~~~~~~~~
export var Origin = new Point(0, 0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
~~~~~
!!! Module declaration cannot be in different file from class or function with which it is merged
}
==== tests/cases/conformance/internalModules/DeclarationMerging/classPoint.ts (0 errors) ====
module X.Y {
// duplicate identifier
export class Point {
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
x: number;
y: number;
}
}
==== tests/cases/conformance/internalModules/DeclarationMerging/simple.ts (1 errors) ====
module A {
~~~~~~~~~~
export var Instance = new A();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
~
!!! Module declaration cannot be located prior to class or function with which it is merged
// duplicate identifier
class A {
id: string;
}

View File

@ -0,0 +1,36 @@
==== tests/cases/conformance/internalModules/DeclarationMerging/module.ts (1 errors) ====
module A {
export module Point {
~~~~~~~~~~~~~~~~~~~~~
export var Origin = { x: 0, y: 0 };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
~~~~~
!!! Module declaration cannot be in different file from class or function with which it is merged
}
==== tests/cases/conformance/internalModules/DeclarationMerging/function.ts (0 errors) ====
module A {
// duplicate identifier error
export function Point() {
return { x: 0, y: 0 };
}
}
==== tests/cases/conformance/internalModules/DeclarationMerging/simple.ts (1 errors) ====
module B {
export module Point {
~~~~~~~~~~~~~~~~~~~~~
export var Origin = { x: 0, y: 0 };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
~~~~~
!!! Module declaration cannot be located prior to class or function with which it is merged
// duplicate identifier error
export function Point() {
return { x: 0, y: 0 };
}
}

View File

@ -1,4 +1,4 @@
==== tests/cases/compiler/augmentedTypesModules.ts (3 errors) ====
==== tests/cases/compiler/augmentedTypesModules.ts (6 errors) ====
// module then var
module m1 { }
var m1 = 1; // Should be allowed
@ -30,9 +30,13 @@
function m2() { }; // ok since the module is not instantiated
module m2a { var y = 2; }
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! Module declaration cannot be located prior to class or function with which it is merged
function m2a() { }; // error since the module is instantiated
module m2b { export var y = 2; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! Module declaration cannot be located prior to class or function with which it is merged
function m2b() { }; // error since the module is instantiated
// should be errors to have function first
@ -56,6 +60,8 @@
class m3 { } // ok since the module is not instantiated
module m3a { var y = 2; }
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! Module declaration cannot be located prior to class or function with which it is merged
class m3a { foo() { } } // error, class isn't ambient or declared before the module
class m3b { foo() { } }

View File

@ -0,0 +1,35 @@
==== tests/cases/compiler/augmentedTypesModules2.ts (3 errors) ====
// module then function
module m2 { }
function m2() { }; // ok since the module is not instantiated
module m2a { var y = 2; }
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! Module declaration cannot be located prior to class or function with which it is merged
function m2a() { }; // error since the module is instantiated
module m2b { export var y = 2; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! Module declaration cannot be located prior to class or function with which it is merged
function m2b() { }; // error since the module is instantiated
function m2c() { };
module m2c { export var y = 2; }
module m2cc { export var y = 2; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! Module declaration cannot be located prior to class or function with which it is merged
function m2cc() { }; // error to have module first
module m2d { }
declare function m2d(): void;
declare function m2e(): void;
module m2e { }
function m2f() { };
module m2f { export interface I { foo(): void } }
function m2g() { };
module m2g { export class C { foo() { } } }

View File

@ -0,0 +1,9 @@
==== tests/cases/compiler/augmentedTypesModules3.ts (1 errors) ====
//// module then class
module m3 { }
class m3 { } // ok since the module is not instantiated
module m3a { var y = 2; }
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! Module declaration cannot be located prior to class or function with which it is merged
class m3a { foo() { } } // error, class isn't ambient or declared before the module

View File

@ -0,0 +1,12 @@
==== tests/cases/compiler/cloduleSplitAcrossFiles_class.ts (0 errors) ====
class D { }
==== tests/cases/compiler/cloduleSplitAcrossFiles_module.ts (1 errors) ====
module D {
~~~~~~~~~~
export var y = "hi";
~~~~~~~~~~~~~~~~~~~~~~~~
}
~
!!! Module declaration cannot be in different file from class or function with which it is merged
D.y;

View File

@ -0,0 +1,12 @@
==== tests/cases/compiler/funduleSplitAcrossFiles_function.ts (0 errors) ====
function D() { }
==== tests/cases/compiler/funduleSplitAcrossFiles_module.ts (1 errors) ====
module D {
~~~~~~~~~~
export var y = "hi";
~~~~~~~~~~~~~~~~~~~~~~~~
}
~
!!! Module declaration cannot be in different file from class or function with which it is merged
D.y;

View File

@ -1,10 +1,17 @@
==== tests/cases/conformance/internalModules/moduleDeclarations/invalidNestedModules.ts (1 errors) ====
==== tests/cases/conformance/internalModules/moduleDeclarations/invalidNestedModules.ts (2 errors) ====
module A.B.C {
~~~
export class Point {
~~~~~~~~~~~~~~~~~~~~~~~~
x: number;
~~~~~~~~~~~~~~~~~~
y: number;
~~~~~~~~~~~~~~~~~~
}
~~~~~
}
~
!!! Module declaration cannot be located prior to class or function with which it is merged
module A {
export module B {

View File

@ -1,4 +1,4 @@
==== tests/cases/compiler/nameCollisions.ts (8 errors) ====
==== tests/cases/compiler/nameCollisions.ts (9 errors) ====
module T {
var x = 2;
@ -18,8 +18,12 @@
!!! Duplicate identifier 'z'.
module y {
~~~~~~~~~~
var b;
~~~~~~~~~~~~~~
}
~~~~~
!!! Module declaration cannot be located prior to class or function with which it is merged
class y { } // error