-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Class expressions #3568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Class expressions #3568
Changes from all commits
0fe6049
a264be5
23603a3
b518dc1
413f278
f578ee8
6928bfa
55f195d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -542,6 +542,7 @@ namespace ts { | |
case SyntaxKind.ModuleDeclaration: | ||
case SyntaxKind.TypeAliasDeclaration: | ||
case SyntaxKind.ClassDeclaration: | ||
case SyntaxKind.ClassExpression: | ||
// These are not allowed inside a generator now, but eventually they may be allowed | ||
// as local types. Regardless, any yield statements contained within them should be | ||
// skipped in this traversal. | ||
|
@@ -579,26 +580,15 @@ namespace ts { | |
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
export function isAccessor(node: Node): boolean { | ||
if (node) { | ||
switch (node.kind) { | ||
case SyntaxKind.GetAccessor: | ||
case SyntaxKind.SetAccessor: | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
return node && (node.kind === SyntaxKind.GetAccessor || node.kind === SyntaxKind.SetAccessor); | ||
} | ||
|
||
export function isClassLike(node: Node): boolean { | ||
if (node) { | ||
return node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression; | ||
} | ||
return node && (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you make this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no need to, |
||
} | ||
|
||
export function isFunctionLike(node: Node): boolean { | ||
|
@@ -620,7 +610,6 @@ namespace ts { | |
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
|
@@ -641,6 +630,15 @@ namespace ts { | |
} | ||
} | ||
|
||
export function getContainingClass(node: Node): ClassLikeDeclaration { | ||
while (true) { | ||
node = node.parent; | ||
if (!node || isClassLike(node)) { | ||
return <ClassLikeDeclaration>node; | ||
} | ||
} | ||
} | ||
|
||
export function getThisContainer(node: Node, includeArrowFunctions: boolean): Node { | ||
while (true) { | ||
node = node.parent; | ||
|
@@ -653,7 +651,7 @@ namespace ts { | |
// then the computed property is not a 'this' container. | ||
// A computed property name in a class needs to be a this container | ||
// so that we can error on it. | ||
if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) { | ||
if (isClassLike(node.parent.parent)) { | ||
return node; | ||
} | ||
// If this is a computed property, then the parent should not | ||
|
@@ -708,7 +706,7 @@ namespace ts { | |
// then the computed property is not a 'super' container. | ||
// A computed property name in a class needs to be a super container | ||
// so that we can error on it. | ||
if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) { | ||
if (isClassLike(node.parent.parent)) { | ||
return node; | ||
} | ||
// If this is a computed property, then the parent should not | ||
|
@@ -1087,6 +1085,7 @@ namespace ts { | |
case SyntaxKind.ArrowFunction: | ||
case SyntaxKind.BindingElement: | ||
case SyntaxKind.ClassDeclaration: | ||
case SyntaxKind.ClassExpression: | ||
case SyntaxKind.Constructor: | ||
case SyntaxKind.EnumDeclaration: | ||
case SyntaxKind.EnumMember: | ||
|
@@ -1235,7 +1234,7 @@ namespace ts { | |
return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined; | ||
} | ||
|
||
export function getClassImplementsHeritageClauseElements(node: ClassDeclaration) { | ||
export function getClassImplementsHeritageClauseElements(node: ClassLikeDeclaration) { | ||
let heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ImplementsKeyword); | ||
return heritageClause ? heritageClause.types : undefined; | ||
} | ||
|
@@ -1917,7 +1916,7 @@ namespace ts { | |
export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean { | ||
return node.kind === SyntaxKind.ExpressionWithTypeArguments && | ||
(<HeritageClause>node.parent).token === SyntaxKind.ExtendsKeyword && | ||
node.parent.parent.kind === SyntaxKind.ClassDeclaration; | ||
isClassLike(node.parent.parent); | ||
} | ||
|
||
// Returns false if this heritage clause element's expression contains something unsupported | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
=== tests/cases/compiler/anonymousClassExpression1.ts === | ||
function f() { | ||
>f : Symbol(f, Decl(anonymousClassExpression1.ts, 0, 0)) | ||
|
||
return typeof class {} === "function"; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
=== tests/cases/compiler/anonymousClassExpression1.ts === | ||
function f() { | ||
>f : () => boolean | ||
|
||
return typeof class {} === "function"; | ||
>typeof class {} === "function" : boolean | ||
>typeof class {} : string | ||
>class {} : typeof (Anonymous class) | ||
>"function" : string | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
=== tests/cases/conformance/classes/classExpression.ts === | ||
var x = class C { | ||
>x : Symbol(x, Decl(classExpression.ts, 0, 3)) | ||
>C : Symbol(C, Decl(classExpression.ts, 0, 7)) | ||
} | ||
|
||
var y = { | ||
>y : Symbol(y, Decl(classExpression.ts, 3, 3)) | ||
|
||
foo: class C2 { | ||
>foo : Symbol(foo, Decl(classExpression.ts, 3, 9)) | ||
>C2 : Symbol(C2, Decl(classExpression.ts, 4, 8)) | ||
} | ||
} | ||
|
||
module M { | ||
>M : Symbol(M, Decl(classExpression.ts, 6, 1)) | ||
|
||
var z = class C4 { | ||
>z : Symbol(z, Decl(classExpression.ts, 9, 7)) | ||
>C4 : Symbol(C4, Decl(classExpression.ts, 9, 11)) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
=== tests/cases/conformance/classes/classExpression.ts === | ||
var x = class C { | ||
>x : typeof C | ||
>class C {} : typeof C | ||
>C : typeof C | ||
} | ||
|
||
var y = { | ||
>y : { foo: typeof C2; } | ||
>{ foo: class C2 { }} : { foo: typeof C2; } | ||
|
||
foo: class C2 { | ||
>foo : typeof C2 | ||
>class C2 { } : typeof C2 | ||
>C2 : typeof C2 | ||
} | ||
} | ||
|
||
module M { | ||
>M : typeof M | ||
|
||
var z = class C4 { | ||
>z : typeof C4 | ||
>class C4 { } : typeof C4 | ||
>C4 : typeof C4 | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
=== tests/cases/conformance/classes/classExpressions/classExpression1.ts === | ||
var v = class C {}; | ||
>v : Symbol(v, Decl(classExpression1.ts, 0, 3)) | ||
>C : Symbol(C, Decl(classExpression1.ts, 0, 7)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
=== tests/cases/conformance/classes/classExpressions/classExpression1.ts === | ||
var v = class C {}; | ||
>v : typeof C | ||
>class C {} : typeof C | ||
>C : typeof C | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
=== tests/cases/conformance/classes/classExpressions/classExpression2.ts === | ||
class D { } | ||
>D : Symbol(D, Decl(classExpression2.ts, 0, 0)) | ||
|
||
var v = class C extends D {}; | ||
>v : Symbol(v, Decl(classExpression2.ts, 1, 3)) | ||
>C : Symbol(C, Decl(classExpression2.ts, 1, 7)) | ||
>D : Symbol(D, Decl(classExpression2.ts, 0, 0)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
=== tests/cases/conformance/classes/classExpressions/classExpression2.ts === | ||
class D { } | ||
>D : D | ||
|
||
var v = class C extends D {}; | ||
>v : typeof C | ||
>class C extends D {} : typeof C | ||
>C : typeof C | ||
>D : D | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can now make this return
node is ClassLikeDeclaration