Bug 778586: When inferring display names, handle property names that are not valid identifier names. r=acrichto

This commit is contained in:
Jim Blandy 2012-09-06 03:12:18 -07:00
parent e59cf6d57b
commit d8e94e9948
2 changed files with 37 additions and 5 deletions

View File

@ -32,6 +32,25 @@ class NameResolver
return pn && pn->isKind(PNK_LP); return pn && pn->isKind(PNK_LP);
} }
/*
* Append a reference to a property named |name| to |buf|. If |name| is
* a proper identifier name, then we append '.name'; otherwise, we
* append '["name"]'.
*
* Note that we need the IsIdentifier check for atoms from both
* PNK_NAME nodes and PNK_STRING nodes: given code like a["b c"], the
* front end will produce a PNK_DOT with a PNK_NAME child whose name
* contains spaces.
*/
bool appendPropertyReference(JSAtom *name) {
if (IsIdentifier(name))
return buf->append(".") && buf->append(name);
/* Quote the string as needed. */
JSString *source = js_QuoteString(cx, name, '"');
return source && buf->append("[") && buf->append(source) && buf->append("]");
}
/* Append a number to buf. */ /* Append a number to buf. */
bool appendNumber(double n) { bool appendNumber(double n) {
char number[30]; char number[30];
@ -51,9 +70,7 @@ class NameResolver
bool nameExpression(ParseNode *n) { bool nameExpression(ParseNode *n) {
switch (n->getKind()) { switch (n->getKind()) {
case PNK_DOT: case PNK_DOT:
return (nameExpression(n->expr()) && return nameExpression(n->expr()) && appendPropertyReference(n->pn_atom);
buf->append(".") &&
buf->append(n->pn_atom));
case PNK_NAME: case PNK_NAME:
return buf->append(n->pn_atom); return buf->append(n->pn_atom);
@ -204,8 +221,7 @@ class NameResolver
if (node->isKind(PNK_COLON)) { if (node->isKind(PNK_COLON)) {
ParseNode *left = node->pn_left; ParseNode *left = node->pn_left;
if (left->isKind(PNK_NAME) || left->isKind(PNK_STRING)) { if (left->isKind(PNK_NAME) || left->isKind(PNK_STRING)) {
/* Atoms are dot-appended. */ if (!appendPropertyReference(left->pn_atom))
if (!buf.append(".") || !buf.append(left->pn_atom))
return NULL; return NULL;
} else if (left->isKind(PNK_NUMBER)) { } else if (left->isKind(PNK_NUMBER)) {
if (!appendNumericPropertyReference(left->pn_dval)) if (!appendNumericPropertyReference(left->pn_dval))

View File

@ -131,3 +131,19 @@ odeURIL:(function(){})
a = { 1: function () {} }; a = { 1: function () {} };
assertName(a[1], 'a[1]'); assertName(a[1], 'a[1]');
a = {
"embedded spaces": function(){},
"dots.look.like.property.references": function(){},
"\"\'quotes\'\"": function(){},
"!@#$%": function(){}
};
assertName(a["embedded spaces"], 'a["embedded spaces"]');
assertName(a["dots.look.like.property.references"], 'a["dots.look.like.property.references"]');
assertName(a["\"\'quotes\'\""], 'a["\\\"\'quotes\'\\\""]');
assertName(a["!@#$%"], 'a["!@#$%"]');
a.b = {};
a.b.c = {};
a.b["c"]["d e"] = { f: { 1: { "g": { "h i": function() {} } } } };
assertName(a.b.c["d e"].f[1].g["h i"], 'a.b.c["d e"].f[1].g["h i"]');