Make 'load' a keyword RELNOTES[INC]: `load` is now a language keyword, it cannot be used as an identifier PiperOrigin-RevId: 160944121
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java b/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java index e5805f5..61fdb60 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java
@@ -528,6 +528,7 @@ keywordMap.put("in", TokenKind.IN); keywordMap.put("is", TokenKind.IS); keywordMap.put("lambda", TokenKind.LAMBDA); + keywordMap.put("load", TokenKind.LOAD); keywordMap.put("nonlocal", TokenKind.NONLOCAL); keywordMap.put("not", TokenKind.NOT); keywordMap.put("or", TokenKind.OR);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java index f5e5b51..06f0ac9 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
@@ -1091,6 +1091,8 @@ // load '(' STRING (COMMA [IDENTIFIER EQUALS] STRING)* COMMA? ')' private void parseLoad(List<Statement> list) { int start = token.left; + expect(TokenKind.LOAD); + expect(TokenKind.LPAREN); if (token.kind != TokenKind.STRING) { expect(TokenKind.STRING); return; @@ -1165,21 +1167,12 @@ } private void parseTopLevelStatement(List<Statement> list) { - // In Python grammar, there is no "top-level statement" and imports are - // considered as "small statements". We are a bit stricter than Python here. - // Check if there is an include - if (token.kind == TokenKind.IDENTIFIER) { - Token identToken = token; - Identifier ident = parseIdent(); - - if (ident.getName().equals("load") && token.kind == TokenKind.LPAREN) { - expect(TokenKind.LPAREN); - parseLoad(list); - return; - } - pushToken(identToken); // push the ident back to parse it as a statement + // Unlike Python imports, load statements can appear only at top-level. + if (token.kind == TokenKind.LOAD) { + parseLoad(list); + } else { + parseStatement(list, ParsingLevel.TOP_LEVEL); } - parseStatement(list, ParsingLevel.TOP_LEVEL); } // small_stmt | 'pass'
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/TokenKind.java b/src/main/java/com/google/devtools/build/lib/syntax/TokenKind.java index 52acce1..e5098f1 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/TokenKind.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/TokenKind.java
@@ -56,6 +56,7 @@ LBRACKET("["), LESS("<"), LESS_EQUALS("<="), + LOAD("load"), LPAREN("("), MINUS("-"), MINUS_EQUALS("-="),
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java index 04eb664..62e176e 100644 --- a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java +++ b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
@@ -1236,7 +1236,7 @@ public void testLoadNotAtTopLevel() throws Exception { setFailFast(false); parseFileForSkylark("if 1: load(8)\n"); - assertContainsError("name 'load' is not defined"); + assertContainsError("syntax error at 'load': expected expression"); } @Test