Skip to content

Commit 3834edd

Browse files
committed
Refactor part of getPropertyNameForIndexedAccess into checkSymbolNameIsProperSymbolReference
1 parent 8325862 commit 3834edd

File tree

1 file changed

+42
-15
lines changed

1 file changed

+42
-15
lines changed

src/compiler/checker.ts

+42-15
Original file line numberDiff line numberDiff line change
@@ -5540,6 +5540,14 @@ module ts {
55405540
if (!isTypeOfKind(links.resolvedType, TypeFlags.Any | TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol)) {
55415541
error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
55425542
}
5543+
else if (isWellKnownSymbolSyntactically(node.expression)) {
5544+
// If it's not ES6, error
5545+
// Check that Symbol corresponds to global symbol, and that property exists, and that it's a symbol
5546+
}
5547+
else {
5548+
// Some syntactic forms require that the property name be a well known symbol.
5549+
// Will move the grammar checks here.
5550+
}
55435551
}
55445552

55455553
return links.resolvedType;
@@ -5835,33 +5843,52 @@ module ts {
58355843
/**
58365844
* If indexArgumentExpression is a string literal or number literal, returns its text.
58375845
* If indexArgumentExpression is a well known symbol, returns the property name corresponding
5838-
* to this symbol.
5846+
* to this symbol, as long as it is a proper symbol reference.
58395847
* Otherwise, returns undefined.
58405848
*/
5841-
function getPropertyNameForIndexedAccess(indexArgumentExpression: Expression) {
5849+
function getPropertyNameForIndexedAccess(indexArgumentExpression: Expression): string {
58425850
if (indexArgumentExpression.kind === SyntaxKind.StringLiteral || indexArgumentExpression.kind === SyntaxKind.NumericLiteral) {
58435851
return (<LiteralExpression>indexArgumentExpression).text;
58445852
}
5845-
if (isWellKnownSymbolSyntactically(indexArgumentExpression)) {
5846-
var leftHandSide = (<PropertyAccessExpression>indexArgumentExpression).expression;
5847-
Debug.assert((<Identifier>leftHandSide).text === "Symbol");
5848-
// The name is Symbol.<someName>, so make sure Symbol actually resolves to the
5849-
// global Symbol object
5850-
var leftHandSideSymbol = resolveName(indexArgumentExpression, (<Identifier>leftHandSide).text,
5851-
SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
5852-
if (leftHandSideSymbol === globalESSymbolConstructorSymbol) {
5853-
// Make sure the property type is the primitive symbol type
5853+
if (languageVersion >= ScriptTarget.ES6 && isWellKnownSymbolSyntactically(indexArgumentExpression)) {
5854+
if (checkSymbolNameIsProperSymbolReference(<PropertyAccessExpression>indexArgumentExpression, /*reportError*/ false)) {
58545855
var rightHandSideName = (<Identifier>(<PropertyAccessExpression>indexArgumentExpression).name).text;
5855-
var esSymbolConstructorPropertyType = getTypeOfPropertyOfType(globalESSymbolConstructorType, rightHandSideName);
5856-
if (esSymbolConstructorPropertyType && esSymbolConstructorPropertyType.flags & TypeFlags.ESSymbol) {
5857-
return getPropertyNameForKnownSymbolName(rightHandSideName);
5858-
}
5856+
return getPropertyNameForKnownSymbolName(rightHandSideName);
58595857
}
58605858
}
58615859

58625860
return undefined;
58635861
}
58645862

5863+
/**
5864+
* A proper symbol reference requires the following:
5865+
* 1. The language version is at least ES6
5866+
* 2. The expression is of the form Symbol.<identifier>
5867+
* 3. Symbol in this context resolves to the global Symbol object
5868+
* 4. The property access denotes a property that is present on the global Symbol object
5869+
* 5. The property on the global Symbol object is of the primitive type symbol.
5870+
*/
5871+
function checkSymbolNameIsProperSymbolReference(wellKnownSymbolName: PropertyAccessExpression, reportError: boolean): boolean {
5872+
if (languageVersion < ScriptTarget.ES6) {
5873+
return false;
5874+
}
5875+
5876+
Debug.assert(isWellKnownSymbolSyntactically(wellKnownSymbolName));
5877+
// The name is Symbol.<someName>, so make sure Symbol actually resolves to the
5878+
// global Symbol object
5879+
var leftHandSide = (<PropertyAccessExpression>wellKnownSymbolName).expression;
5880+
var leftHandSideSymbol = resolveName(wellKnownSymbolName, (<Identifier>leftHandSide).text,
5881+
SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
5882+
if (leftHandSideSymbol !== globalESSymbolConstructorSymbol) {
5883+
return false;
5884+
}
5885+
5886+
// Make sure the property type is the primitive symbol type
5887+
var rightHandSideName = (<Identifier>(<PropertyAccessExpression>wellKnownSymbolName).name).text;
5888+
var esSymbolConstructorPropertyType = getTypeOfPropertyOfType(globalESSymbolConstructorType, rightHandSideName);
5889+
return !!(esSymbolConstructorPropertyType && esSymbolConstructorPropertyType.flags & TypeFlags.ESSymbol);
5890+
}
5891+
58655892
function resolveUntypedCall(node: CallLikeExpression): Signature {
58665893
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
58675894
checkExpression((<TaggedTemplateExpression>node).template);

0 commit comments

Comments
 (0)