Bug 1293205 - Part 1: Warn about non-standard for-each regardless of JS version number. r=evilpie

This commit is contained in:
Tooru Fujisawa 2016-09-02 04:16:16 +09:00
parent 6643f35db1
commit af031e202b
5 changed files with 57 additions and 4 deletions

View File

@ -5220,10 +5220,8 @@ Parser<ParseHandler>::forStatement(YieldHandling yieldHandling)
iflags = JSITER_FOREACH;
isForEach = true;
addTelemetry(JSCompartment::DeprecatedForEach);
if (versionNumber() < JSVERSION_LATEST) {
if (!report(ParseWarning, pc->sc()->strict(), null(), JSMSG_DEPRECATED_FOR_EACH))
return null();
}
if (!warnOnceAboutForEach())
return null();
}
}
@ -9032,6 +9030,22 @@ Parser<ParseHandler>::warnOnceAboutExprClosure()
return true;
}
template <typename ParseHandler>
bool
Parser<ParseHandler>::warnOnceAboutForEach()
{
JSContext* cx = context->maybeJSContext();
if (!cx)
return true;
if (!cx->compartment()->warnedAboutForEach) {
if (!report(ParseWarning, false, null(), JSMSG_DEPRECATED_FOR_EACH))
return false;
cx->compartment()->warnedAboutForEach = true;
}
return true;
}
template class Parser<FullParseHandler>;
template class Parser<SyntaxParseHandler>;

View File

@ -1340,6 +1340,7 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
void addTelemetry(JSCompartment::DeprecatedLanguageExtension e);
bool warnOnceAboutExprClosure();
bool warnOnceAboutForEach();
};
} /* namespace frontend */

View File

@ -0,0 +1,36 @@
// for-each should be warned once and only once.
function testWarn(code) {
enableLastWarning();
var g = newGlobal();
g.code = code;
g.eval('eval(code)');
var warning = getLastWarning();
assertEq(warning !== null, true, "warning should be caught for " + code);
assertEq(warning.name, "Warning");
clearLastWarning();
g.eval('eval(code)');
warning = getLastWarning();
assertEq(warning, null, "warning should not be caught for 2nd ocurrence");
clearLastWarning();
g = newGlobal();
g.code = code;
g.eval('Reflect.parse(code);');
warning = getLastWarning();
assertEq(warning !== null, true, "warning should be caught for " + code);
assertEq(warning.name, "Warning");
clearLastWarning();
g.eval('Reflect.parse(code);');
warning = getLastWarning();
assertEq(warning, null, "warning should not be caught for 2nd ocurrence");
disableLastWarning();
}
testWarn("for each (var x in {}) {}");
testWarn("for each (x in {}) {}");
testWarn("for each (let y in {}) {}");
testWarn("for each (const y in {}) {}");
testWarn("for each ([x, y] in {}) {}");

View File

@ -53,6 +53,7 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
isSelfHosting(false),
marked(true),
warnedAboutExprClosure(false),
warnedAboutForEach(false),
#ifdef DEBUG
firedOnNewGlobalObject(false),
#endif

View File

@ -338,6 +338,7 @@ struct JSCompartment
bool isSelfHosting;
bool marked;
bool warnedAboutExprClosure;
bool warnedAboutForEach;
#ifdef DEBUG
bool firedOnNewGlobalObject;