Create symbols for computed properties

This commit is contained in:
Jason Freeman
2015-01-19 16:36:36 -08:00
parent d192fea774
commit ef06879a75
19 changed files with 142 additions and 22 deletions
+16 -11
View File
@@ -118,11 +118,7 @@ module ts {
}
function declareSymbol(symbols: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
// Nodes with computed property names will not get symbols, because the type checker
// does not make properties for them.
if (hasComputedNameButNotSymbol(node)) {
return undefined;
}
Debug.assert(!hasComputedNameButNotSymbol(node));
var name = getDeclarationName(node);
if (name !== undefined) {
@@ -395,14 +391,14 @@ module ts {
break;
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
bindDeclaration(<Declaration>node, SymbolFlags.Property | ((<PropertyDeclaration>node).questionToken ? SymbolFlags.Optional : 0), SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Property | ((<PropertyDeclaration>node).questionToken ? SymbolFlags.Optional : 0), SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.PropertyAssignment:
case SyntaxKind.ShorthandPropertyAssignment:
bindDeclaration(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.EnumMember:
bindDeclaration(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes, /*isBlockScopeContainer*/ false);
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
@@ -415,7 +411,7 @@ module ts {
// as other properties in the object literal. So we use SymbolFlags.PropertyExcludes
// so that it will conflict with any other object literal members with the same
// name.
bindDeclaration(<Declaration>node, SymbolFlags.Method | ((<MethodDeclaration>node).questionToken ? SymbolFlags.Optional : 0),
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Method | ((<MethodDeclaration>node).questionToken ? SymbolFlags.Optional : 0),
isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.FunctionDeclaration:
@@ -425,10 +421,10 @@ module ts {
bindDeclaration(<Declaration>node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0, /*isBlockScopeContainer:*/ true);
break;
case SyntaxKind.GetAccessor:
bindDeclaration(<Declaration>node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes, /*isBlockScopeContainer*/ true);
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.SetAccessor:
bindDeclaration(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes, /*isBlockScopeContainer*/ true);
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.FunctionType:
@@ -510,5 +506,14 @@ module ts {
declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
}
}
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) {
if (hasComputedNameButNotSymbol(node)) {
bindAnonymousDeclaration(node, symbolKind, "__computed", isBlockScopeContainer);
}
else {
bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer);
}
}
}
}
+6 -5
View File
@@ -5405,6 +5405,7 @@ module ts {
for (var i = 0; i < node.properties.length; i++) {
var memberDecl = node.properties[i];
var member = memberDecl.symbol;
if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ||
isObjectLiteralMethod(memberDecl)) {
@@ -5422,7 +5423,6 @@ module ts {
}
typeFlags |= type.flags;
var prop = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.name);
var member = memberDecl.symbol;
prop.declarations = member.declarations;
prop.parent = member.parent;
if (member.valueDeclaration) {
@@ -5431,7 +5431,7 @@ module ts {
prop.type = type;
prop.target = member;
properties[prop.name] = prop;
member = prop;
}
else {
// TypeScript 1.0 spec (April 2014)
@@ -5441,8 +5441,9 @@ module ts {
// as an ordinary function declaration with a single parameter and a Void return type.
Debug.assert(memberDecl.kind === SyntaxKind.GetAccessor || memberDecl.kind === SyntaxKind.SetAccessor);
checkAccessorDeclaration(<AccessorDeclaration>memberDecl);
properties[member.name] = member;
}
properties[member.name] = member;
}
var stringIndexType = getIndexType(IndexKind.String);
@@ -7427,9 +7428,9 @@ module ts {
}
}
}
checkAndStoreTypeOfAccessors(getSymbolOfNode(node));
}
checkAndStoreTypeOfAccessors(getSymbolOfNode(node));
}
checkFunctionLikeDeclaration(node);
@@ -1,7 +1,10 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts(1,11): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts(1,20): error TS2304: Cannot find name 'foo'.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts (1 errors) ====
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts (2 errors) ====
var v = { [yield]: foo }
~~~~~~~
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
~~~
!!! error TS2304: Cannot find name 'foo'.
@@ -1,7 +1,10 @@
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts(1,11): error TS9001: Generators are not currently supported.
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts(1,12): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
==== tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts (1 errors) ====
==== tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts (2 errors) ====
var v = { *[foo()]() { } }
~
!!! error TS9001: Generators are not currently supported.
~~~~~~~
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
@@ -0,0 +1,12 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames1.ts ===
var v = {
>v : {}
>{ get [0 + 1]() { return 0 }, set [0 + 1](v: string) { } //No error} : {}
get [0 + 1]() { return 0 },
>0 + 1 : number
set [0 + 1](v: string) { } //No error
>0 + 1 : number
>v : string
}
@@ -0,0 +1,7 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName12.ts ===
class C {
>C : C
[e]() { }
>e : unknown
}
@@ -0,0 +1,7 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName17.ts ===
var v = { set [e](v) { } }
>v : {}
>{ set [e](v) { } } : {}
>e : unknown
>v : any
@@ -0,0 +1,6 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName2.ts ===
var v = { [e]: 1 };
>v : {}
>{ [e]: 1 } : {}
>e : unknown
@@ -0,0 +1,8 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName24.ts ===
class C {
>C : C
set [e](v) { }
>e : unknown
>v : any
}
@@ -0,0 +1,6 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName3.ts ===
var v = { [e]() { } };
>v : {}
>{ [e]() { } } : {}
>e : unknown
@@ -0,0 +1,9 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName37.ts ===
var v = {
>v : {}
>{ [public]: 0} : {}
[public]: 0
>public : unknown
};
@@ -0,0 +1,7 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName38.ts ===
class C {
>C : C
[public]() { }
>public : unknown
}
@@ -0,0 +1,7 @@
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName4.ts(1,15): error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName4.ts (1 errors) ====
var v = { get [e]() { } };
~~~
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
@@ -0,0 +1,8 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName40.ts ===
class C {
>C : C
[a ? "" : ""]() {}
>a ? "" : "" : string
>a : unknown
}
@@ -0,0 +1,9 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName41.ts ===
var v = {
>v : {}
>{ [0 in []]: true} : {}
[0 in []]: true
>0 in [] : boolean
>[] : undefined[]
}
@@ -0,0 +1,7 @@
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName5.ts(1,22): error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName5.ts (1 errors) ====
var v = { public get [e]() { } };
~~~
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
@@ -0,0 +1,9 @@
=== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName6.ts ===
var v = { [e]: 1, [e + e]: 2 };
>v : {}
>{ [e]: 1, [e + e]: 2 } : {}
>e : unknown
>e + e : any
>e : unknown
>e : unknown
@@ -1,7 +1,10 @@
tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName4.ts(1,15): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName4.ts(1,15): error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
==== tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName4.ts (1 errors) ====
==== tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName4.ts (2 errors) ====
var v = { get [e]() { } };
~~~
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
~~~
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
@@ -1,17 +1,20 @@
tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(4,15): error TS1005: ']' expected.
tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(4,17): error TS2304: Cannot find name 'string'.
tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(4,23): error TS1005: ',' expected.
tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(4,24): error TS1136: Property assignment expected.
tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(4,32): error TS1005: ':' expected.
tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts(5,1): error TS1128: Declaration or statement expected.
==== tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts (5 errors) ====
==== tests/cases/conformance/classes/indexMemberDeclarations/privateIndexer2.ts (6 errors) ====
// private indexers not allowed
var x = {
private [x: string]: string;
~
!!! error TS1005: ']' expected.
~~~~~~
!!! error TS2304: Cannot find name 'string'.
~
!!! error TS1005: ',' expected.
~