aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/analysis
diff options
context:
space:
mode:
authorGravatar Chris Parsons <cparsons@google.com>2016-05-23 17:39:42 +0000
committerGravatar Yue Gan <yueg@google.com>2016-05-24 11:56:43 +0000
commit4dfb22c4bad3dfa4dba46426c8587c0aa148d8d9 (patch)
tree5b09b10bef0e0ca634d237af86b6e9da7160f846 /src/main/java/com/google/devtools/build/lib/analysis
parentfe206a490a2aa48c789c0edd35383407f44bc49b (diff)
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
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/analysis')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java36
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/config/ConfigSetting.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/constraints/Environment.java3
4 files changed, 51 insertions, 3 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
index 368f373d27..c979b440ac 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
@@ -45,6 +45,7 @@ import com.google.devtools.build.lib.packages.PackageGroupsRuleVisibility;
import com.google.devtools.build.lib.packages.PackageSpecification;
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.RuleVisibility;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.rules.SkylarkRuleConfiguredTargetBuilder;
@@ -266,7 +267,15 @@ public final class ConfiguredTargetFactory {
RuleClass.ConfiguredTargetFactory<ConfiguredTarget, RuleContext> factory =
rule.getRuleClassObject().<ConfiguredTarget, RuleContext>getConfiguredTargetFactory();
Preconditions.checkNotNull(factory, rule.getRuleClassObject());
- return factory.create(ruleContext);
+ try {
+ return factory.create(ruleContext);
+ } catch (RuleErrorException ruleErrorException) {
+ // Returning null in this method is an indication an error occurred. Exceptions are not
+ // propagated, as this would show a nasty stack trace to users, and only provide info
+ // on one specific failure with poor messaging. By returning null, the caller can
+ // inspect ruleContext for multiple errors and output thorough messaging on each.
+ return null;
+ }
}
}
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 20ff73c903..f7671a2655 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.PackageSpecification;
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 final class RuleContext extends TargetContext
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 final class RuleContext extends TargetContext
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 @@ public final class RuleContext extends TargetContext
}
/**
+ * 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>
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigSetting.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigSetting.java
index 331c47eba4..99f998c1d4 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigSetting.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigSetting.java
@@ -23,6 +23,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
+import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.Preconditions;
@@ -44,7 +45,8 @@ import java.util.Map;
public class ConfigSetting implements RuleConfiguredTargetFactory {
@Override
- public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException {
+ public ConfiguredTarget create(RuleContext ruleContext)
+ throws InterruptedException, RuleErrorException {
// Get the required flag=value settings for this rule.
Map<String, String> settings = NonconfigurableAttributeMapper.of(ruleContext.getRule())
.get(ConfigRuleClasses.ConfigSettingRule.SETTINGS_ATTRIBUTE, Type.STRING_DICT);
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/constraints/Environment.java b/src/main/java/com/google/devtools/build/lib/analysis/constraints/Environment.java
index c8be4087a5..52e10c8e48 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/constraints/Environment.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/constraints/Environment.java
@@ -22,6 +22,7 @@ import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.EnvironmentGroup;
+import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
/**
@@ -30,7 +31,7 @@ import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
public class Environment implements RuleConfiguredTargetFactory {
@Override
- public ConfiguredTarget create(RuleContext ruleContext) {
+ public ConfiguredTarget create(RuleContext ruleContext) throws RuleErrorException {
// The main analysis work to do here is to simply fill in SupportedEnvironmentsProvider to
// pass the environment itself to depending rules.