From 3eb0a3abab71f933b8bfb50ca9e94505926b305e Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 14 Apr 2015 23:22:58 -0700 Subject: [PATCH] PR Feedback and updated baselines --- src/compiler/checker.ts | 23 +++--- .../diagnosticInformationMap.generated.ts | 1 - src/compiler/utilities.ts | 5 +- ...uleWithSameNameAndCommonRootES6.errors.txt | 44 ++++++++++ ...ssAndModuleWithSameNameAndCommonRootES6.js | 81 +++++++++++++++++++ 5 files changed, 141 insertions(+), 13 deletions(-) create mode 100644 tests/baselines/reference/ClassAndModuleWithSameNameAndCommonRootES6.errors.txt create mode 100644 tests/baselines/reference/ClassAndModuleWithSameNameAndCommonRootES6.js diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 892c935b2c3..f03629c14db 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10387,10 +10387,12 @@ module ts { } } - function getFirstClassOrFunctionDeclaration(symbol: Symbol, nonAmbientOnly: boolean): Declaration { + function getFirstNonAmbientClassOrFunctionDeclaration(symbol: Symbol): Declaration { let declarations = symbol.declarations; for (let declaration of declarations) { - if ((declaration.kind === SyntaxKind.ClassDeclaration || (declaration.kind === SyntaxKind.FunctionDeclaration && nodeIsPresent((declaration).body))) && !(nonAmbientOnly && isInAmbientContext(declaration))) { + if ((declaration.kind === SyntaxKind.ClassDeclaration || + (declaration.kind === SyntaxKind.FunctionDeclaration && nodeIsPresent((declaration).body))) && + !isInAmbientContext(declaration)) { return declaration; } } @@ -10430,20 +10432,21 @@ module ts { && symbol.declarations.length > 1 && !isInAmbientContext(node) && isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation)) { - let nonAmbientClassOrFunc = getFirstClassOrFunctionDeclaration(symbol, /*nonAmbientOnly*/ true); - if (nonAmbientClassOrFunc) { - if (getSourceFileOfNode(node) !== getSourceFileOfNode(nonAmbientClassOrFunc)) { + let firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol); + if (firstNonAmbientClassOrFunc) { + if (getSourceFileOfNode(node) !== getSourceFileOfNode(firstNonAmbientClassOrFunc)) { error(node.name, Diagnostics.A_module_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged); } - else if (node.pos < nonAmbientClassOrFunc.pos) { + else if (node.pos < firstNonAmbientClassOrFunc.pos) { error(node.name, Diagnostics.A_module_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged); } } - // if the module merges with a class declaration in the same lexical scope, we need to track this - // to ensure the correct emit. - let anyClassOrFunc = getFirstClassOrFunctionDeclaration(symbol, /*nonAmbientOnly*/ false); - if (anyClassOrFunc && anyClassOrFunc.kind === SyntaxKind.ClassDeclaration && inSameLexicalScope(node, anyClassOrFunc)) { + // if the module merges with a class declaration in the same lexical scope, + // we need to track this to ensure the correct emit. + let mergedClass = getDeclarationOfKind(symbol, SyntaxKind.ClassDeclaration); + if (mergedClass && + inSameLexicalScope(node, mergedClass)) { getNodeLinks(node).flags |= NodeCheckFlags.LexicalModuleMergesWithClass; } } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 0271ac73105..6e956889b49 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -1,6 +1,5 @@ // /// -/* @internal */ module ts { export var Diagnostics = { Unterminated_string_literal: { code: 1002, category: DiagnosticCategory.Error, key: "Unterminated string literal." }, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 4c3c5b801cc..7bc1f92395d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -211,8 +211,9 @@ module ts { isCatchClauseVariableDeclaration(declaration); } - // Gets the nearest enclosing block scope container that has the provided node as a descendant, that is not the provided node. - export function getEnclosingBlockScopeContainer(node: Node): Node { + // Gets the nearest enclosing block scope container that has the provided node + // as a descendant, that is not the provided node. + export function getEnclosingBlockScopeContainer(node: Node): Node { let current = node.parent; while (current) { if (isFunctionLike(current)) { diff --git a/tests/baselines/reference/ClassAndModuleWithSameNameAndCommonRootES6.errors.txt b/tests/baselines/reference/ClassAndModuleWithSameNameAndCommonRootES6.errors.txt new file mode 100644 index 00000000000..4c707dfd861 --- /dev/null +++ b/tests/baselines/reference/ClassAndModuleWithSameNameAndCommonRootES6.errors.txt @@ -0,0 +1,44 @@ +tests/cases/conformance/internalModules/DeclarationMerging/module.ts(2,19): error TS2433: A module declaration cannot be in a different file from a class or function with which it is merged + + +==== 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 { + ~~~~~ +!!! error TS2433: A module declaration cannot be in a different file from a class or function with which it is merged + export var Origin = new Point(0, 0); + } + } + +==== 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 }; + \ No newline at end of file diff --git a/tests/baselines/reference/ClassAndModuleWithSameNameAndCommonRootES6.js b/tests/baselines/reference/ClassAndModuleWithSameNameAndCommonRootES6.js new file mode 100644 index 00000000000..71f633a41e3 --- /dev/null +++ b/tests/baselines/reference/ClassAndModuleWithSameNameAndCommonRootES6.js @@ -0,0 +1,81 @@ +//// [tests/cases/conformance/internalModules/DeclarationMerging/ClassAndModuleWithSameNameAndCommonRootES6.ts] //// + +//// [class.ts] +module X.Y { + export class Point { + constructor(x: number, y: number) { + this.x = x; + this.y = y; + } + x: number; + y: number; + } +} + +//// [module.ts] +module X.Y { + export module Point { + export var Origin = new Point(0, 0); + } +} + +//// [test.ts] +//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 ? + + +//// [simple.ts] +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 }; + + +//// [class.js] +var X; +(function (X) { + var Y; + (function (Y) { + class Point { + constructor(x, y) { + this.x = x; + this.y = y; + } + } + Y.Point = Point; + })(Y = X.Y || (X.Y = {})); +})(X || (X = {})); +//// [module.js] +var X; +(function (X) { + var Y; + (function (Y) { + var Point; + (function (Point) { + Point.Origin = new Point(0, 0); + })(Point = Y.Point || (Y.Point = {})); + })(Y = X.Y || (X.Y = {})); +})(X || (X = {})); +//// [test.js] +//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 ? +//// [simple.js] +class A { +} +(function (A) { + A.Instance = new A(); +})(A || (A = {})); +// ensure merging works as expected +var a = A.Instance; +var a = new A(); +var a;