Allow use of Exceptions to exit early out of configured-target creation, instead of passing and checking null in all helpers.
Demonstrates this pattern usage in a few select rules (e.g. AndroidBinary) where this was particularly egregious.
There are many places which can benefit from this pattern -- this change doesn't try to fix them all at once.
--
MOS_MIGRATED_REVID=123012378
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 20ff73c..f7671a2 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -65,6 +65,7 @@
import com.google.devtools.build.lib.packages.RawAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.packages.RuleErrorConsumer;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.TargetUtils;
@@ -289,6 +290,16 @@
public boolean hasErrors() {
return getAnalysisEnvironment().hasErrors();
}
+
+ /**
+ * No-op if {@link #hasErrors} is false, throws {@link RuleErrorException} if it is true.
+ * This provides a convenience to early-exit of configured target creation if there are errors.
+ */
+ public void assertNoErrors() throws RuleErrorException {
+ if (hasErrors()) {
+ throw new RuleErrorException();
+ }
+ }
/**
* Returns an immutable map from attribute name to list of configured targets for that attribute.
@@ -406,6 +417,17 @@
public void ruleError(String message) {
reporter.ruleError(message);
}
+
+ /**
+ * Convenience function to report non-attribute-specific errors in the current rule and then
+ * throw a {@link RuleErrorException}, immediately exiting the build invocation. Alternatively,
+ * invoke {@link #ruleError} instead to collect additional error information before ending the
+ * invocation.
+ */
+ public void throwWithRuleError(String message) throws RuleErrorException {
+ reporter.ruleError(message);
+ throw new RuleErrorException();
+ }
/**
* Convenience function for subclasses to report non-attribute-specific
@@ -429,6 +451,20 @@
}
/**
+ * Convenience function to report attribute-specific errors in the current rule, and then throw a
+ * {@link RuleErrorException}, immediately exiting the build invocation. Alternatively, invoke
+ * {@link #attributeError} instead to collect additional error information before ending the
+ * invocation.
+ *
+ * <p>If the name of the attribute starts with <code>$</code>
+ * it is replaced with a string <code>(an implicit dependency)</code>.
+ */
+ public void throwWithAttributeError(String attrName, String message) throws RuleErrorException {
+ reporter.attributeError(attrName, message);
+ throw new RuleErrorException();
+ }
+
+ /**
* Like attributeError, but does not mark the configured target as errored.
*
* <p>If the name of the attribute starts with <code>$</code>