Allow to not specify the value of variable (in expression "var_name =")
Closes #10753.
PiperOrigin-RevId: 294429500
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/parser/NinjaParserStep.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/parser/NinjaParserStep.java
index 67408d3..c625dc5 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/parser/NinjaParserStep.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/parser/NinjaParserStep.java
@@ -17,7 +17,6 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Ascii;
import com.google.common.base.Preconditions;
-import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -49,17 +48,17 @@
String name = asString(parseExpected(NinjaToken.IDENTIFIER));
parseExpected(NinjaToken.EQUALS);
- NinjaVariableValue value = parseVariableValue(name);
+ NinjaVariableValue value = parseVariableValue();
return Pair.of(name, value);
}
@VisibleForTesting
- public NinjaVariableValue parseVariableValue(String name) throws GenericParsingException {
- return parseVariableValueImpl(() -> String.format("Variable '%s' has no value.", name));
+ public NinjaVariableValue parseVariableValue() throws GenericParsingException {
+ return Preconditions.checkNotNull(parseVariableValueImpl(true));
}
- private NinjaVariableValue parseVariableValueImpl(Supplier<String> messageForNoValue)
- throws GenericParsingException {
+ @Nullable
+ private NinjaVariableValue parseVariableValueImpl(boolean noValueAsEmpty) {
NinjaVariableValue.Builder varBuilder = NinjaVariableValue.builder();
int previous = -1;
while (lexer.hasNextToken()) {
@@ -88,7 +87,12 @@
}
if (previous == -1) {
// We read no value.
- throw new GenericParsingException(messageForNoValue.get());
+ if (noValueAsEmpty) {
+ // Use empty string for value if specified by caller.
+ return NinjaVariableValue.createPlainText("");
+ }
+ // Otherwise, return null to indicate there was no value.
+ return null;
}
return varBuilder.build();
}
@@ -154,9 +158,11 @@
private NinjaVariableValue parseIncludeOrSubNinja(NinjaToken token)
throws GenericParsingException {
parseExpected(token);
- NinjaVariableValue value =
- parseVariableValueImpl(
- () -> String.format("%s statement has no path.", Ascii.toLowerCase(token.name())));
+ NinjaVariableValue value = parseVariableValueImpl(false);
+ if (value == null) {
+ throw new GenericParsingException(
+ String.format("%s statement has no path.", Ascii.toLowerCase(token.name())));
+ }
if (lexer.hasNextToken()) {
parseExpected(NinjaToken.NEWLINE);
lexer.undo();
@@ -178,7 +184,7 @@
parseExpected(NinjaToken.INDENT);
String variableName = asString(parseExpected(NinjaToken.IDENTIFIER));
parseExpected(NinjaToken.EQUALS);
- NinjaVariableValue value = parseVariableValue(variableName);
+ NinjaVariableValue value = parseVariableValue();
NinjaRuleVariable ninjaRuleVariable = NinjaRuleVariable.nullOrValue(variableName);
if (ninjaRuleVariable == null) {
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaParserStepTest.java b/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaParserStepTest.java
index e752ef9..6b6ccfb 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaParserStepTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaParserStepTest.java
@@ -56,7 +56,6 @@
public void testVariableParsingException() {
doTestVariableParsingException(" ", "Expected identifier, but got indent");
doTestVariableParsingException("a", "Expected = after 'a'");
- doTestVariableParsingException("a=", "Variable 'a' has no value.");
doTestVariableParsingException(
"^a=", "Expected identifier, but got error: 'Symbol is not allowed in the identifier.'");
}
@@ -68,7 +67,7 @@
}
@Test
- public void testNoValue() {
+ public void testNoValue() throws Exception {
doTestNoValue("a=");
doTestNoValue("a=\u000018");
doTestNoValue("a = ");
@@ -161,12 +160,26 @@
}
@Test
+ public void testVariableWithoutValue() throws Exception {
+ NinjaParserStep parser =
+ createParser(
+ "rule testRule \n"
+ + " command = executable --flag $TARGET $out && $POST_BUILD\n"
+ + " description =\n");
+ NinjaRule ninjaRule = parser.parseNinjaRule();
+ ImmutableSortedMap<NinjaRuleVariable, NinjaVariableValue> variables = ninjaRule.getVariables();
+ assertThat(variables.keySet())
+ .containsExactly(
+ NinjaRuleVariable.NAME, NinjaRuleVariable.COMMAND, NinjaRuleVariable.DESCRIPTION);
+ assertThat(variables.get(NinjaRuleVariable.NAME).getRawText()).isEqualTo("testRule");
+ assertThat(variables.get(NinjaRuleVariable.DESCRIPTION).getRawText()).isEmpty();
+ }
+
+ @Test
public void testNinjaRuleParsingException() {
doTestNinjaRuleParsingException(
"rule testRule extra-word\n", "Expected newline, but got identifier");
doTestNinjaRuleParsingException(
- "rule testRule\n command =", "Variable 'command' has no value.");
- doTestNinjaRuleParsingException(
"rule testRule\ncommand =", "Expected indent, but got identifier");
doTestNinjaRuleParsingException(
"rule testRule\n ^custom = a",
@@ -300,11 +313,11 @@
assertThat(expander.getRequestedVariables()).isEmpty();
}
- private static void doTestNoValue(String text) {
+ private static void doTestNoValue(String text) throws Exception {
NinjaParserStep parser = createParser(text);
- GenericParsingException exception =
- assertThrows(GenericParsingException.class, parser::parseVariable);
- assertThat(exception).hasMessageThat().isEqualTo("Variable 'a' has no value.");
+ NinjaVariableValue value = parser.parseVariable().getSecond();
+ assertThat(value).isNotNull();
+ assertThat(value.getRawText()).isEmpty();
}
private static void doTestWithVariablesInValue(
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaScopeTest.java b/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaScopeTest.java
index 1033620..15d10af 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaScopeTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaScopeTest.java
@@ -307,6 +307,6 @@
private static NinjaVariableValue parseValue(String text) throws Exception {
ByteBuffer bb = ByteBuffer.wrap(text.getBytes(StandardCharsets.ISO_8859_1));
NinjaLexer lexer = new NinjaLexer(new ByteBufferFragment(bb, 0, bb.limit()));
- return new NinjaParserStep(lexer).parseVariableValue("test");
+ return new NinjaParserStep(lexer).parseVariableValue();
}
}