Bug 1165456 - More name-resolution conversion for arrays and (tagged) template literals. r=shu

This commit is contained in:
Jeff Walden 2015-03-04 13:21:30 -08:00
parent 8545a6d874
commit e44fcf7117

View File

@ -270,6 +270,58 @@ class NameResolver
return pos >= 0 && call(parents[pos]) && parents[pos]->pn_head == cur;
}
bool resolveTemplateLiteral(ParseNode* node, HandleAtom prefix) {
MOZ_ASSERT(node->isKind(PNK_TEMPLATE_STRING_LIST));
ParseNode* element = node->pn_head;
while (true) {
MOZ_ASSERT(element->isKind(PNK_TEMPLATE_STRING));
element = element->pn_next;
if (!element)
return true;
if (!resolve(element, prefix))
return false;
element = element->pn_next;
}
}
bool resolveTaggedTemplate(ParseNode* node, HandleAtom prefix) {
MOZ_ASSERT(node->isKind(PNK_TAGGED_TEMPLATE));
ParseNode* element = node->pn_head;
// The list head is a leading expression, e.g. |tag| in |tag`foo`|,
// that might contain functions.
if (!resolve(element, prefix))
return false;
// Next is the callsite object node. This node only contains
// internal strings and an array -- no user-controlled expressions.
element = element->pn_next;
#ifdef DEBUG
{
MOZ_ASSERT(element->isKind(PNK_CALLSITEOBJ));
ParseNode* array = element->pn_head;
MOZ_ASSERT(array->isKind(PNK_ARRAY));
for (ParseNode* kid = array->pn_head; kid; kid = kid->pn_next)
MOZ_ASSERT(kid->isKind(PNK_TEMPLATE_STRING));
for (ParseNode* next = array->pn_next; next; next = next->pn_next)
MOZ_ASSERT(next->isKind(PNK_TEMPLATE_STRING));
}
#endif
// Next come any interpolated expressions in the tagged template.
ParseNode* interpolated = element->pn_next;
for (; interpolated; interpolated = interpolated->pn_next) {
if (!resolve(interpolated, prefix))
return false;
}
return true;
}
public:
explicit NameResolver(ExclusiveContext* cx) : cx(cx), nparents(0), buf(nullptr) {}
@ -598,6 +650,7 @@ class NameResolver
case PNK_NEW:
case PNK_CALL:
case PNK_GENEXP:
case PNK_ARRAY:
MOZ_ASSERT(cur->isArity(PN_LIST));
for (ParseNode* element = cur->pn_head; element; element = element->pn_next) {
if (!resolve(element, prefix))
@ -605,12 +658,29 @@ class NameResolver
}
goto done;
case PNK_ARRAY:
case PNK_OBJECT:
case PNK_CLASSMETHODLIST:
MOZ_ASSERT(cur->isArity(PN_LIST));
for (ParseNode* element = cur->pn_head; element; element = element->pn_next) {
if (!resolve(element, prefix))
return false;
}
goto done;
// A template string list's contents alternate raw template string
// contents with expressions interpolated into the overall literal.
case PNK_TEMPLATE_STRING_LIST:
MOZ_ASSERT(cur->isArity(PN_LIST));
if (!resolveTemplateLiteral(cur, prefix))
return false;
goto done;
case PNK_TAGGED_TEMPLATE:
case PNK_CALLSITEOBJ:
MOZ_ASSERT(cur->isArity(PN_LIST));
if (!resolveTaggedTemplate(cur, prefix))
return false;
goto done;
case PNK_VAR:
case PNK_CONST:
case PNK_LET:
@ -635,6 +705,9 @@ class NameResolver
return false;
goto done;
case PNK_CALLSITEOBJ:
MOZ_CRASH("should have been handled by a parent PNK_TAGGED_TEMPLATE node");
case PNK_LIMIT: // invalid sentinel value
MOZ_CRASH("invalid node kind");
}