mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 01:49:41 -05:00
Merge pull request #4921 from Microsoft/implementsAsIdentifier
disambiguate: 'implements' starts heritage clause vs 'implements' is …
This commit is contained in:
@@ -4809,7 +4809,7 @@ namespace ts {
|
||||
node.decorators = decorators;
|
||||
setModifiers(node, modifiers);
|
||||
parseExpected(SyntaxKind.ClassKeyword);
|
||||
node.name = parseOptionalIdentifier();
|
||||
node.name = parseNameOfClassDeclarationOrExpression();
|
||||
node.typeParameters = parseTypeParameters();
|
||||
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true);
|
||||
|
||||
@@ -4825,7 +4825,22 @@ namespace ts {
|
||||
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
|
||||
function parseNameOfClassDeclarationOrExpression(): Identifier {
|
||||
// implements is a future reserved word so
|
||||
// 'class implements' might mean either
|
||||
// - class expression with omitted name, 'implements' starts heritage clause
|
||||
// - class with name 'implements'
|
||||
// 'isImplementsClause' helps to disambiguate between these two cases
|
||||
return isIdentifier() && !isImplementsClause()
|
||||
? parseIdentifier()
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function isImplementsClause() {
|
||||
return token === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword)
|
||||
}
|
||||
|
||||
function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray<HeritageClause> {
|
||||
// ClassTail[Yield,Await] : (Modified) See 14.5
|
||||
// ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
|
||||
|
||||
16
tests/baselines/reference/implementsInClassExpression.js
Normal file
16
tests/baselines/reference/implementsInClassExpression.js
Normal file
@@ -0,0 +1,16 @@
|
||||
//// [implementsInClassExpression.ts]
|
||||
interface Foo {
|
||||
doThing(): void;
|
||||
}
|
||||
|
||||
let cls = class implements Foo {
|
||||
doThing() { }
|
||||
}
|
||||
|
||||
//// [implementsInClassExpression.js]
|
||||
var cls = (function () {
|
||||
function class_1() {
|
||||
}
|
||||
class_1.prototype.doThing = function () { };
|
||||
return class_1;
|
||||
})();
|
||||
@@ -0,0 +1,15 @@
|
||||
=== tests/cases/compiler/implementsInClassExpression.ts ===
|
||||
interface Foo {
|
||||
>Foo : Symbol(Foo, Decl(implementsInClassExpression.ts, 0, 0))
|
||||
|
||||
doThing(): void;
|
||||
>doThing : Symbol(doThing, Decl(implementsInClassExpression.ts, 0, 15))
|
||||
}
|
||||
|
||||
let cls = class implements Foo {
|
||||
>cls : Symbol(cls, Decl(implementsInClassExpression.ts, 4, 3))
|
||||
>Foo : Symbol(Foo, Decl(implementsInClassExpression.ts, 0, 0))
|
||||
|
||||
doThing() { }
|
||||
>doThing : Symbol((Anonymous class).doThing, Decl(implementsInClassExpression.ts, 4, 32))
|
||||
}
|
||||
16
tests/baselines/reference/implementsInClassExpression.types
Normal file
16
tests/baselines/reference/implementsInClassExpression.types
Normal file
@@ -0,0 +1,16 @@
|
||||
=== tests/cases/compiler/implementsInClassExpression.ts ===
|
||||
interface Foo {
|
||||
>Foo : Foo
|
||||
|
||||
doThing(): void;
|
||||
>doThing : () => void
|
||||
}
|
||||
|
||||
let cls = class implements Foo {
|
||||
>cls : typeof (Anonymous class)
|
||||
>class implements Foo { doThing() { }} : typeof (Anonymous class)
|
||||
>Foo : Foo
|
||||
|
||||
doThing() { }
|
||||
>doThing : () => void
|
||||
}
|
||||
7
tests/cases/compiler/implementsInClassExpression.ts
Normal file
7
tests/cases/compiler/implementsInClassExpression.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
interface Foo {
|
||||
doThing(): void;
|
||||
}
|
||||
|
||||
let cls = class implements Foo {
|
||||
doThing() { }
|
||||
}
|
||||
Reference in New Issue
Block a user