From 38a54bc0b90f7145abd45e186e74e4dc78ad705c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 18 Jun 2015 14:16:00 -0700 Subject: [PATCH] Fix incremental parsing issue. We were moving a method-declaration called "constructor" into a class. This is incorrect as that same code should be parsed as a constructor-declaration now that it is in the class context. --- src/compiler/parser.ts | 10 +++++++++- tests/cases/unittests/incrementalParser.ts | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a507125d4b..a94341dd9c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1491,12 +1491,20 @@ namespace ts { switch (node.kind) { case SyntaxKind.Constructor: case SyntaxKind.IndexSignature: - case SyntaxKind.MethodDeclaration: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.PropertyDeclaration: case SyntaxKind.SemicolonClassElement: return true; + case SyntaxKind.MethodDeclaration: + // Method declarations are not necessarily reusable. An object-literal + // may have a method calls "constructor(...)" and we must reparse that + // into an actual .ConstructorDeclaration. + let methodDeclaration = node; + let nameIsConstructor = methodDeclaration.name.kind === SyntaxKind.Identifier && + (methodDeclaration.name).originalKeywordKind === SyntaxKind.ConstructorKeyword; + + return !nameIsConstructor; } } diff --git a/tests/cases/unittests/incrementalParser.ts b/tests/cases/unittests/incrementalParser.ts index a0b361a87f..1ef10eaa71 100644 --- a/tests/cases/unittests/incrementalParser.ts +++ b/tests/cases/unittests/incrementalParser.ts @@ -713,6 +713,24 @@ module m3 { }\ compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4); }); + it('Do not move constructors from class to object-literal.', () => { + var source = "class C { public constructor() { } public constructor() { } public constructor() { } }" + + var oldText = ScriptSnapshot.fromString(source); + var newTextAndChange = withChange(oldText, 0, "class C".length, "var v ="); + + compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); + }); + + it('Do not move methods called "constructor" from object literal to class', () => { + var source = "var v = { public constructor() { } public constructor() { } public constructor() { } }" + + var oldText = ScriptSnapshot.fromString(source); + var newTextAndChange = withChange(oldText, 0, "var v =".length, "class C"); + + compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); + }); + it('Moving index signatures from class to interface',() => { var source = "class C { public [a: number]: string; public [a: number]: string; public [a: number]: string }"