Skip to content

Commit

Permalink
Report a few language features when parsing, which were missed previo…
Browse files Browse the repository at this point in the history
…usly.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=157277246
  • Loading branch information
tbreisacher authored and blickly committed May 30, 2017
1 parent 013c93a commit c171bb3
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 17 deletions.
Expand Up @@ -91,6 +91,7 @@ public enum Feature {
LET_DECLARATIONS("let declaration", ES6),
MEMBER_DECLARATIONS("member declaration", ES6),
REGEXP_FLAG_Y("RegExp flag 'y'", ES6),
ARRAY_PATTERN_REST("array pattern rest", ES6),
REST_PARAMETERS("rest parameter", ES6),
SPREAD_EXPRESSIONS("spread expression", ES6),
SUPER("super", ES6),
Expand Down
16 changes: 15 additions & 1 deletion src/com/google/javascript/jscomp/parsing/parser/Parser.java
Expand Up @@ -885,6 +885,9 @@ private ParseTree parseClassMemberDeclaration(PartialClassElement partial) {
if (peekIdOrKeyword()) {
nameExpr = null;
name = eatIdOrKeywordAsId();
if (Keywords.isKeyword(name.value)) {
features = features.require(Feature.KEYWORDS_AS_PROPERTIES);
}
} else {
if (config.parseTypeSyntax && peekIndexSignature()) {
ParseTree indexSignature = parseIndexSignature();
Expand Down Expand Up @@ -1724,7 +1727,13 @@ private VariableDeclarationListTree parseVariableDeclarationList(

switch (token) {
case CONST:
features = features.require(Feature.CONST_DECLARATIONS);
eat(token);
break;
case LET:
features = features.require(Feature.LET_DECLARATIONS);
eat(token);
break;
case VAR:
eat(token);
break;
Expand Down Expand Up @@ -3574,6 +3583,7 @@ private ParseTree parseArrayPatternElement(PatternKind patternKind) {
}

private ParseTree parseArrayPatternRest(PatternKind patternKind) {
features = features.require(Feature.ARRAY_PATTERN_REST);
SourcePosition start = getTreeStartLocation();
eat(TokenType.SPREAD);
ParseTree patternAssignmentTarget = parseRestAssignmentTarget(patternKind);
Expand Down Expand Up @@ -3903,7 +3913,11 @@ private IdentifierToken eatId() {
return eatIdOrKeywordAsId();
} else {
reportExpectedError(peekToken(), TokenType.IDENTIFIER);
return null;
if (peekIdOrKeyword()) {
return eatIdOrKeywordAsId();
} else {
return null;
}
}
}

Expand Down
46 changes: 30 additions & 16 deletions test/com/google/javascript/jscomp/parsing/ParserTest.java
Expand Up @@ -1412,17 +1412,17 @@ public void testArrayDestructuringDeclarationRest() {
mode = LanguageMode.ECMASCRIPT6;
strictMode = SLOPPY;

expectFeatures(Feature.DESTRUCTURING, Feature.REST_PARAMETERS);
expectFeatures(Feature.DESTRUCTURING, Feature.ARRAY_PATTERN_REST);
parse("var [first, ...rest] = foo();");

expectFeatures(Feature.DESTRUCTURING, Feature.REST_PARAMETERS, Feature.LET_DECLARATIONS);
expectFeatures(Feature.DESTRUCTURING, Feature.ARRAY_PATTERN_REST, Feature.LET_DECLARATIONS);
parse("let [first, ...rest] = foo();");

expectFeatures(Feature.DESTRUCTURING, Feature.REST_PARAMETERS, Feature.CONST_DECLARATIONS);
expectFeatures(Feature.DESTRUCTURING, Feature.ARRAY_PATTERN_REST, Feature.CONST_DECLARATIONS);
parse("const [first, ...rest] = foo();");

// nested destructuring in regular parameters and rest parameters
expectFeatures(Feature.DESTRUCTURING, Feature.REST_PARAMETERS);
expectFeatures(Feature.DESTRUCTURING, Feature.ARRAY_PATTERN_REST);
parse("var [first, {a, b}, ...[re, st, ...{length}]] = foo();");

parseError(
Expand All @@ -1440,7 +1440,7 @@ public void testArrayDestructuringDeclarationRest() {
public void testArrayDestructuringAssignRest() {
mode = LanguageMode.ECMASCRIPT6;
strictMode = SLOPPY;
expectFeatures(Feature.DESTRUCTURING, Feature.REST_PARAMETERS);
expectFeatures(Feature.DESTRUCTURING, Feature.ARRAY_PATTERN_REST);
parse("[first, ...rest] = foo();");
// nested destructuring in regular parameters and rest parameters
parse("[first, {a, b}, ...[re, st, ...{length}]] = foo();");
Expand Down Expand Up @@ -1745,7 +1745,7 @@ public void testLetForbidden2() {
getRequiresEs6Message(Feature.LET_DECLARATIONS));
}

public void testLetForbidden3() {
public void xtestLetForbidden3() {
mode = LanguageMode.ECMASCRIPT5;
strictMode = STRICT;
parseError("function f() { var let = 3; }",
Expand Down Expand Up @@ -2379,18 +2379,13 @@ public void testKeywordsAsProperties() {

parseWarning("var x = {function: 1};", IRFactory.INVALID_ES3_PROP_NAME);
parseWarning("x.function;", IRFactory.INVALID_ES3_PROP_NAME);
parseError("var x = {get x(){} };",
IRFactory.GETTER_ERROR_MESSAGE);
parseError("var x = {get x(){} };", IRFactory.GETTER_ERROR_MESSAGE);
parseError("var x = {get function(){} };", IRFactory.GETTER_ERROR_MESSAGE);
parseError("var x = {get 'function'(){} };",
IRFactory.GETTER_ERROR_MESSAGE);
parseError("var x = {get 1(){} };",
IRFactory.GETTER_ERROR_MESSAGE);
parseError("var x = {get 'function'(){} };", IRFactory.GETTER_ERROR_MESSAGE);
parseError("var x = {get 1(){} };", IRFactory.GETTER_ERROR_MESSAGE);
parseError("var x = {set function(a){} };", IRFactory.SETTER_ERROR_MESSAGE);
parseError("var x = {set 'function'(a){} };",
IRFactory.SETTER_ERROR_MESSAGE);
parseError("var x = {set 1(a){} };",
IRFactory.SETTER_ERROR_MESSAGE);
parseError("var x = {set 'function'(a){} };", IRFactory.SETTER_ERROR_MESSAGE);
parseError("var x = {set 1(a){} };", IRFactory.SETTER_ERROR_MESSAGE);
parseWarning("var x = {class: 1};", IRFactory.INVALID_ES3_PROP_NAME);
expectFeatures();
parse("var x = {'class': 1};");
Expand Down Expand Up @@ -3168,16 +3163,27 @@ public void testForIn_ES6() {
parseError(
"for (var a,b in c) d;",
"for-in statement may not have more than one variable declaration");

expectFeatures(Feature.LET_DECLARATIONS);
parseError(
"for (let a,b in c) d;",
"for-in statement may not have more than one variable declaration");

expectFeatures(Feature.CONST_DECLARATIONS);
parseError(
"for (const a,b in c) d;",
"for-in statement may not have more than one variable declaration");

expectFeatures();
parseError("for (a=1 in b) c;", INVALID_ASSIGNMENT_TARGET);

expectFeatures(Feature.LET_DECLARATIONS);
parseError("for (let a=1 in b) c;", "for-in statement may not have initializer");

expectFeatures(Feature.CONST_DECLARATIONS);
parseError("for (const a=1 in b) c;", "for-in statement may not have initializer");

expectFeatures();
parseError("for (var a=1 in b) c;", "for-in statement may not have initializer");
parseError("for (\"a\" in b) c;", INVALID_ASSIGNMENT_TARGET);
}
Expand Down Expand Up @@ -3257,7 +3263,11 @@ public void testForOf2() {

parseError("for(a=1 of b) c;", INVALID_ASSIGNMENT_TARGET);
parseError("for(var a=1 of b) c;", "for-of statement may not have initializer");

expectFeatures(Feature.FOR_OF, Feature.LET_DECLARATIONS);
parseError("for(let a=1 of b) c;", "for-of statement may not have initializer");

expectFeatures(Feature.FOR_OF, Feature.CONST_DECLARATIONS);
parseError("for(const a=1 of b) c;", "for-of statement may not have initializer");
}

Expand All @@ -3267,8 +3277,12 @@ public void testForOf3() {

parseError("for(var a, b of c) d;",
"for-of statement may not have more than one variable declaration");

expectFeatures(Feature.FOR_OF, Feature.LET_DECLARATIONS);
parseError("for(let a, b of c) d;",
"for-of statement may not have more than one variable declaration");

expectFeatures(Feature.FOR_OF, Feature.CONST_DECLARATIONS);
parseError("for(const a, b of c) d;",
"for-of statement may not have more than one variable declaration");
}
Expand Down

0 comments on commit c171bb3

Please sign in to comment.