Fix crash with --allow_analysis_failures when RuleClass.ConfiguredTargetFactory.create() returns null
Native implementations of RuleClass.ConfiguredTargetFactory.create() can return
null, either explicitly (e.g. see GenRuleBase.java) or by calling
RuleConfiguredTargetBuilder.build() - which is @Nullable.
This fact was neither documented nor annotated. The natural result was that
ConfiguredTargetFactory misused the API and assumed the returned
ConfiguredTarget was non-null. In fact, it can be null, and requires wrapping
in an erroredConfiguredTarget() - same as for Starlark rule classes.
Fixes e.g. crashes with --allow_analysis_failures (or when using Skylib's
analysistest with expect_falure = True) in genrules with failing make variable
expansion, but the same class of crash could until now have been triggered
using many other native rules. All such rules' create() methods are now
annotated @Nullable for clarity.
PiperOrigin-RevId: 442074108
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BUILD b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
index ff8ac37..449d706 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
@@ -2032,6 +2032,7 @@
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/packages",
"//third_party:guava",
+ "//third_party:jsr305",
],
)
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
index 84e13cb..d160c2d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
@@ -52,6 +52,7 @@
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationConstant;
import com.google.devtools.build.lib.util.FileTypeSet;
+import javax.annotation.Nullable;
import net.starlark.java.eval.StarlarkInt;
/**
@@ -522,6 +523,7 @@
*/
public static class EmptyRuleConfiguredTargetFactory implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext) {
return null;
}
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 a25cab7..34460aa 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
@@ -347,19 +347,21 @@
}
try {
+ ConfiguredTarget target;
if (ruleClass.isStarlark()) {
// TODO(bazel-team): maybe merge with RuleConfiguredTargetBuilder?
- ConfiguredTarget target =
+ target =
StarlarkRuleConfiguredTargetUtil.buildRule(
ruleContext, ruleClass.getAdvertisedProviders());
-
- return target != null ? target : erroredConfiguredTarget(ruleContext);
+ } else {
+ target =
+ Preconditions.checkNotNull(
+ ruleClass.getConfiguredTargetFactory(RuleConfiguredTargetFactory.class),
+ "No configured target factory for %s",
+ ruleClass)
+ .create(ruleContext);
}
- return Preconditions.checkNotNull(
- ruleClass.getConfiguredTargetFactory(RuleConfiguredTargetFactory.class),
- "No configured target factory for %s",
- ruleClass)
- .create(ruleContext);
+ return target != null ? target : erroredConfiguredTarget(ruleContext);
} finally {
ruleContext.close();
}
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 e9c34df..05d7c51 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
@@ -25,6 +25,7 @@
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 javax.annotation.Nullable;
/**
* Implementation for the environment rule.
@@ -32,6 +33,7 @@
public class Environment implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/actions/NinjaBuild.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/actions/NinjaBuild.java
index 7ae0754..fc6a98a 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/actions/NinjaBuild.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/actions/NinjaBuild.java
@@ -40,11 +40,13 @@
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
+import javax.annotation.Nullable;
/** Configured target factory for {@link NinjaBuildRule}. */
public class NinjaBuild implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
Map<String, List<String>> outputGroupsFromAttrs =
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/actions/NinjaGraph.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/actions/NinjaGraph.java
index fb24c7a..5cae7cb 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/actions/NinjaGraph.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/actions/NinjaGraph.java
@@ -53,6 +53,7 @@
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;
+import javax.annotation.Nullable;
/** Configured target factory for {@link NinjaGraphRule}. */
public class NinjaGraph implements RuleConfiguredTargetFactory {
@@ -66,6 +67,7 @@
NinjaGraph.class.getSimpleName());
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
if (!ruleContext
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java
index cdbb686..eba1785 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java
@@ -32,6 +32,7 @@
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.vfs.PathFragment;
+import javax.annotation.Nullable;
/**
* Implementation for the sh_binary rule.
@@ -39,6 +40,7 @@
public class ShBinary implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
ImmutableList<Artifact> srcs = ruleContext.getPrerequisiteArtifacts("srcs").list();
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShLibrary.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShLibrary.java
index 88329cb..6d43682 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShLibrary.java
@@ -24,6 +24,7 @@
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import javax.annotation.Nullable;
/**
* Implementation for the sh_library rule.
@@ -31,6 +32,7 @@
public class ShLibrary implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
NestedSet<Artifact> filesToBuild =
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index 5654d18..46b2716 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -311,12 +311,15 @@
public interface ConfiguredTargetFactory<
TConfiguredTarget, TContext, TActionConflictException extends Throwable> {
/**
- * Returns a fully initialized configured target instance using the given context.
+ * Returns a fully initialized configured target instance using the given context, or {@code
+ * null} on certain rule errors (typically if {@code ruleContext.hasErrors()} becomes {@code
+ * true} while trying to create the target).
*
* @throws RuleErrorException if configured target creation could not be completed due to rule
* errors
* @throws TActionConflictException if there were conflicts during action registration
*/
+ @Nullable
TConfiguredTarget create(TContext ruleContext)
throws InterruptedException, RuleErrorException, TActionConflictException;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/BUILD b/src/main/java/com/google/devtools/build/lib/rules/BUILD
index b27e825..15337da 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/rules/BUILD
@@ -187,6 +187,7 @@
"//src/main/java/com/google/devtools/build/lib/collect",
"//src/main/java/com/google/devtools/build/lib/packages",
"//third_party:guava",
+ "//third_party:jsr305",
],
)
@@ -529,6 +530,7 @@
"//src/main/java/com/google/devtools/build/lib/analysis:rule_definition_environment",
"//src/main/java/com/google/devtools/build/lib/analysis/platform",
"//src/main/java/com/google/devtools/build/lib/packages",
+ "//third_party:jsr305",
],
)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/ToolchainType.java b/src/main/java/com/google/devtools/build/lib/rules/ToolchainType.java
index 6092463..2d682ea 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/ToolchainType.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/ToolchainType.java
@@ -27,6 +27,7 @@
import com.google.devtools.build.lib.analysis.platform.ToolchainTypeInfo;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.ToolchainResolutionMode;
+import javax.annotation.Nullable;
/**
* Implementation of {@code toolchain_type}.
@@ -34,6 +35,7 @@
public class ToolchainType implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws ActionConflictException, InterruptedException {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java
index 51680d4..1486e76 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java
@@ -73,6 +73,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
androidSemantics.checkForMigrationTag(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
index e2c6fca..f6bcde6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -109,6 +109,7 @@
protected abstract CppSemantics createCppSemantics();
@Override
+ @Nullable
public final ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
CppSemantics cppSemantics = createCppSemantics();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java
index 677c489..c13802c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java
@@ -51,6 +51,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import javax.annotation.Nullable;
/** An implementation for the "android_device" rule. */
public class AndroidDevice implements RuleConfiguredTargetFactory {
@@ -88,6 +89,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
androidSemantics.checkForMigrationTag(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixture.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixture.java
index cff3a7e..f2fbf3e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixture.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixture.java
@@ -26,6 +26,7 @@
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.Type;
+import javax.annotation.Nullable;
/** An implementation of the {@code android_device_script_fixture} rule. */
public class AndroidDeviceScriptFixture implements RuleConfiguredTargetFactory {
@@ -37,6 +38,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
androidSemantics.checkForMigrationTag(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidHostServiceFixture.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidHostServiceFixture.java
index ac57111..c8b724a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidHostServiceFixture.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidHostServiceFixture.java
@@ -25,6 +25,7 @@
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.Type;
+import javax.annotation.Nullable;
/** An implementation of the {@code android_host_service_fixture} rule. */
public class AndroidHostServiceFixture implements RuleConfiguredTargetFactory {
@@ -36,6 +37,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
androidSemantics.checkForMigrationTag(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTestBase.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTestBase.java
index eb4ea21..45720b1 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTestBase.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTestBase.java
@@ -68,6 +68,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
androidSemantics.checkForMigrationTag(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
index bb6a791..96677c3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
@@ -35,6 +35,7 @@
import com.google.devtools.build.lib.rules.java.JavaTargetAttributes;
import com.google.devtools.build.lib.rules.java.ProguardLibrary;
import com.google.devtools.build.lib.rules.java.ProguardSpecProvider;
+import javax.annotation.Nullable;
/** An implementation for the "android_library" rule. */
public abstract class AndroidLibrary implements RuleConfiguredTargetFactory {
@@ -107,6 +108,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
// Create semantics objects, which are different between Blaze and Bazel.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
index 8657db8..3d5d97b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
@@ -82,6 +82,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
androidSemantics.checkForMigrationTag(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdkBase.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdkBase.java
index ae63cf6..23c43bf 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdkBase.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdkBase.java
@@ -30,6 +30,7 @@
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.java.BootClassPathInfo;
import com.google.devtools.build.lib.rules.java.JavaConfiguration;
+import javax.annotation.Nullable;
/** Implementation of the {@code android_sdk} rule. */
public class AndroidSdkBase implements RuleConfiguredTargetFactory {
@@ -41,6 +42,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
androidSemantics.checkForMigrationTag(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidToolsDefaultsJar.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidToolsDefaultsJar.java
index b830af9..e9ba83c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidToolsDefaultsJar.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidToolsDefaultsJar.java
@@ -22,6 +22,7 @@
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
+import javax.annotation.Nullable;
/**
* Implementation for the {@code android_tools_defaults_jar} rule.
@@ -40,6 +41,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
androidSemantics.checkForMigrationTag(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AvailableXcodes.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AvailableXcodes.java
index 65358ad..64ebdf3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AvailableXcodes.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AvailableXcodes.java
@@ -21,11 +21,13 @@
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
+import javax.annotation.Nullable;
/** Implementation for the {@code available_xcodes} rule. */
public class AvailableXcodes implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
index 4c09de0..5df2422 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
@@ -40,6 +40,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.annotation.Nullable;
/** Implementation for the {@code xcode_config} rule. */
public class XcodeConfig implements RuleConfiguredTargetFactory {
@@ -57,6 +58,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
AppleConfiguration appleConfig = ruleContext.getFragment(AppleConfiguration.class);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersion.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersion.java
index 6529c5b..63be7d3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersion.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersion.java
@@ -20,6 +20,7 @@
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
+import javax.annotation.Nullable;
/**
* Implementation for the {@code xcode_version} rule.
@@ -27,6 +28,7 @@
public class XcodeVersion implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
XcodeVersionRuleData ruleData =
diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlag.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlag.java
index ccc2a8a..e7641e6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlag.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlag.java
@@ -40,6 +40,7 @@
import com.google.devtools.build.lib.packages.AttributeMap;
import java.util.List;
import java.util.Optional;
+import javax.annotation.Nullable;
import net.starlark.java.eval.Starlark;
/**
@@ -109,6 +110,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
List<String> specifiedValues = ruleContext.attributes().get("allowed_values", STRING_LIST);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java
index 87e0d4a..6cba4b2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java
@@ -66,6 +66,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import javax.annotation.Nullable;
/**
* Implementation for the config_setting rule.
@@ -76,6 +77,7 @@
public final class ConfigSetting implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, ActionConflictException {
AttributeMap attributes = NonconfigurableAttributeMapper.of(ruleContext.getRule());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
index 53429a2..fe390df 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
@@ -87,6 +87,7 @@
import java.util.Map;
import java.util.Queue;
import java.util.Set;
+import javax.annotation.Nullable;
import net.starlark.java.annot.StarlarkBuiltin;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.EvalException;
@@ -308,6 +309,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext context)
throws InterruptedException, RuleErrorException, ActionConflictException {
RuleConfiguredTargetBuilder ruleBuilder = new RuleConfiguredTargetBuilder(context);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcHostToolchainAliasRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcHostToolchainAliasRule.java
index cbcff61..8097512 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcHostToolchainAliasRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcHostToolchainAliasRule.java
@@ -32,6 +32,7 @@
import com.google.devtools.build.lib.analysis.config.ExecutionTransitionFactory;
import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
import com.google.devtools.build.lib.packages.RuleClass;
+import javax.annotation.Nullable;
/** Implementation of the {@code cc_toolchain_alias} rule. */
public class CcHostToolchainAliasRule implements RuleDefinition {
@@ -61,6 +62,7 @@
/** Implementation of cc_host_toolchain_alias. */
public static class CcHostToolchainAlias implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
index 78c95fd..5ba7423 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
@@ -87,6 +87,7 @@
CppFileTypes.SHARED_LIBRARY, CppFileTypes.VERSIONED_SHARED_LIBRARY);
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext context)
throws InterruptedException, RuleErrorException, ActionConflictException {
RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(context);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcTest.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcTest.java
index aca19bf..d9e18b2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcTest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcTest.java
@@ -19,6 +19,7 @@
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
+import javax.annotation.Nullable;
/**
* A configured target class for cc_test rules.
@@ -32,6 +33,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext context)
throws InterruptedException, RuleErrorException, ActionConflictException {
RuleConfiguredTargetBuilder ruleBuilder = new RuleConfiguredTargetBuilder(context);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
index c99d0bc..3b99e5b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
@@ -28,6 +28,7 @@
import com.google.devtools.build.lib.cmdline.Label;
import java.io.Serializable;
import java.util.HashMap;
+import javax.annotation.Nullable;
import net.starlark.java.syntax.Location;
/**
@@ -59,6 +60,7 @@
Label.parseAbsoluteUnchecked(LOOSE_HEADER_CHECK_TARGET);
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
validateToolchain(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainAliasRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainAliasRule.java
index d6f7e6e..ed0ab72 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainAliasRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainAliasRule.java
@@ -35,6 +35,7 @@
import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.ToolchainTransitionMode;
+import javax.annotation.Nullable;
/** Implementation of the {@code cc_toolchain_alias} rule. */
public class CcToolchainAliasRule implements RuleDefinition {
@@ -74,6 +75,7 @@
/** Implementation of cc_toolchain_alias. */
public static class CcToolchainAlias implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuite.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuite.java
index 314a1c4..a7468c7 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuite.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuite.java
@@ -28,6 +28,7 @@
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.BuiltinProvider;
import java.util.Map;
+import javax.annotation.Nullable;
/**
* Implementation of the {@code cc_toolchain_suite} rule.
@@ -39,6 +40,7 @@
public class CcToolchainSuite implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
CppConfiguration cppConfiguration = ruleContext.getFragment(CppConfiguration.class);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHints.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHints.java
index 4122edd..369f19e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHints.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHints.java
@@ -21,11 +21,13 @@
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import javax.annotation.Nullable;
/** Implementation for the {@code fdo_prefetch_hints} rule. */
@Immutable
public final class FdoPrefetchHints implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, ActionConflictException {
FdoInputFile inputFile = FdoInputFile.fromProfileRule(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/BUILD b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/BUILD
index 77de621..a023b77 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/BUILD
@@ -36,6 +36,7 @@
"//src/main/java/com/google/devtools/build/lib/vfs",
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
"//third_party:guava",
+ "//third_party:jsr305",
],
)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibrary.java
index 2cc721f..fe84dd3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibrary.java
@@ -24,10 +24,12 @@
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.rules.cpp.CcStarlarkApiProvider;
+import javax.annotation.Nullable;
/** Part of the implementation of cc_proto_library. */
public class CcProtoLibrary implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
if (ruleContext.getPrerequisites("deps").size() != 1) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/extra/ActionListener.java b/src/main/java/com/google/devtools/build/lib/rules/extra/ActionListener.java
index 9449fbb..f458a30 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/extra/ActionListener.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/extra/ActionListener.java
@@ -30,12 +30,14 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import javax.annotation.Nullable;
/**
* Implementation for the 'action_listener' rule.
*/
public final class ActionListener implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
// This rule doesn't produce any output when listed as a build target.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/genrule/BUILD b/src/main/java/com/google/devtools/build/lib/rules/genrule/BUILD
index d82f963..2465122 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/genrule/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/rules/genrule/BUILD
@@ -33,5 +33,6 @@
"//src/main/java/com/google/devtools/build/lib/util:os",
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
"//third_party:guava",
+ "//third_party:jsr305",
],
)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java
index c3a1579..7bad3db 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java
@@ -55,6 +55,7 @@
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.List;
import java.util.Map;
+import javax.annotation.Nullable;
/**
* A base implementation of genrule, to be used by specific implementing rules which can change some
@@ -115,6 +116,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
NestedSet<Artifact> filesToBuild =
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
index e2b6274..836ba59 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
@@ -74,6 +74,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;
/** An implementation of java_binary. */
@@ -87,6 +88,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
final JavaCommon common = new JavaCommon(ruleContext, semantics);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
index f8f90ad..17cce87 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
@@ -36,6 +36,7 @@
import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.JavaOutput;
import java.util.LinkedHashSet;
import java.util.Set;
+import javax.annotation.Nullable;
/** An implementation for the "java_import" rule. */
public class JavaImport implements RuleConfiguredTargetFactory {
@@ -46,6 +47,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
ImmutableList<Artifact> srcJars = ImmutableList.of();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfiguration.java
index b99fb6c..2ab7c02 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaPackageConfiguration.java
@@ -29,11 +29,13 @@
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
+import javax.annotation.Nullable;
/** Implementation for the java_package_configuration rule. */
public class JavaPackageConfiguration implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
ImmutableList<PackageSpecificationProvider> packages =
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java
index 155e75f..fcfe272 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java
@@ -45,6 +45,7 @@
import com.google.devtools.build.lib.rules.java.JavaToolchainProvider.JspecifyInfo;
import java.util.List;
import java.util.Map;
+import javax.annotation.Nullable;
/** Implementation for the {@code java_toolchain} rule. */
public class JavaToolchain implements RuleConfiguredTargetFactory {
@@ -56,6 +57,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
ImmutableList<String> javacopts = getJavacOpts(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java
index f0c41f2..7a04d8a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoLibrary.java
@@ -35,11 +35,13 @@
import com.google.devtools.build.lib.rules.java.JavaInfo;
import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider;
import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
+import javax.annotation.Nullable;
/** Implementation of the java_proto_library rule. */
public class JavaProtoLibrary implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(final RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java
index e3bf170..e39eed9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java
@@ -30,6 +30,7 @@
import com.google.devtools.build.lib.rules.cpp.CcInfo;
import com.google.devtools.build.lib.rules.cpp.CppSemantics;
import java.util.List;
+import javax.annotation.Nullable;
/**
* Implementation for the "j2objc_library" rule, which exports ObjC source files translated from
@@ -59,6 +60,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
checkAttributes(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/platform/ConstraintValue.java b/src/main/java/com/google/devtools/build/lib/rules/platform/ConstraintValue.java
index 8004743..694975d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/platform/ConstraintValue.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/platform/ConstraintValue.java
@@ -25,11 +25,13 @@
import com.google.devtools.build.lib.analysis.platform.ConstraintSettingInfo;
import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo;
import com.google.devtools.build.lib.analysis.platform.PlatformProviderUtils;
+import javax.annotation.Nullable;
/** Defines a potential value of a constraint. */
public class ConstraintValue implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD b/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD
index 338e62e..aca070a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD
@@ -25,7 +25,6 @@
"//src/main/java/com/google/devtools/build/docgen/annot",
"//src/main/java/com/google/devtools/build/lib/actions",
"//src/main/java/com/google/devtools/build/lib/actions:artifacts",
- "//src/main/java/com/google/devtools/build/lib/actions:localhost_capacity",
"//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster",
"//src/main/java/com/google/devtools/build/lib/analysis:config/build_options",
"//src/main/java/com/google/devtools/build/lib/analysis:config/core_option_converters",
@@ -36,7 +35,6 @@
"//src/main/java/com/google/devtools/build/lib/analysis:rule_definition_environment",
"//src/main/java/com/google/devtools/build/lib/analysis:starlark/args",
"//src/main/java/com/google/devtools/build/lib/analysis:transitive_info_collection",
- "//src/main/java/com/google/devtools/build/lib/analysis:transitive_info_provider",
"//src/main/java/com/google/devtools/build/lib/analysis/starlark/annotations",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
@@ -45,7 +43,6 @@
"//src/main/java/com/google/devtools/build/lib/starlarkbuildapi",
"//src/main/java/com/google/devtools/build/lib/starlarkbuildapi/proto",
"//src/main/java/com/google/devtools/build/lib/util:filetype",
- "//src/main/java/com/google/devtools/build/lib/util:os",
"//src/main/java/com/google/devtools/build/lib/vfs",
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
"//src/main/java/com/google/devtools/common/options",
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java
index e4abfe9..fc3004f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java
@@ -27,10 +27,12 @@
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.Type;
+import javax.annotation.Nullable;
/** Implements {code proto_lang_toolchain}. */
public class ProtoLangToolchain implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
NestedSetBuilder<ProtoSource> providedProtoSources = NestedSetBuilder.stableOrder();
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/AnalysisFailureInfoTest.java b/src/test/java/com/google/devtools/build/lib/analysis/AnalysisFailureInfoTest.java
new file mode 100644
index 0000000..502ca63
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/analysis/AnalysisFailureInfoTest.java
@@ -0,0 +1,126 @@
+// Copyright 2022 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.analysis;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.test.AnalysisFailure;
+import com.google.devtools.build.lib.analysis.test.AnalysisFailureInfo;
+import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import com.google.devtools.build.lib.analysis.util.MockRule;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.collect.nestedset.Depset;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
+import javax.annotation.Nullable;
+import net.starlark.java.eval.Starlark;
+import net.starlark.java.eval.StarlarkSemantics;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests verifying analysis failure propagation via {@link AnalysisFailureInfo} when {@code
+ * --allow_analysis_failures=true}.
+ */
+// TODO(arostovtsev): move all other `--allow_analysis_failures`-related test cases here.
+@RunWith(JUnit4.class)
+public final class AnalysisFailureInfoTest extends BuildViewTestCase {
+
+ @Before
+ public void setUp() throws Exception {
+ useConfiguration("--allow_analysis_failures=true");
+ }
+
+ @Test
+ public void analysisFailureInfoStarlarkApi() throws Exception {
+ Label label = Label.create("test", "test");
+ AnalysisFailure failure = new AnalysisFailure(label, "ErrorMessage");
+ assertThat(getattr(failure, "label")).isSameInstanceAs(label);
+ assertThat(getattr(failure, "message")).isEqualTo("ErrorMessage");
+
+ AnalysisFailureInfo info = AnalysisFailureInfo.forAnalysisFailures(ImmutableList.of(failure));
+ // info.causes.to_list()[0] == failure
+ NestedSet<AnalysisFailure> causes =
+ Depset.cast(getattr(info, "causes"), AnalysisFailure.class, "causes");
+ assertThat(causes.toList().get(0)).isSameInstanceAs(failure);
+ }
+
+ private static Object getattr(Object x, String name) throws Exception {
+ return Starlark.getattr(/*mu=*/ null, StarlarkSemantics.DEFAULT, x, name, null);
+ }
+
+ // Regression test for b/154007057
+ @Test
+ public void nativeRuleExpanderFailure() throws Exception {
+ scratch.file(
+ "test/BUILD", //
+ "genrule(",
+ " name = 'bad_variable',",
+ " outs = ['bad.out'],",
+ " cmd = 'cp $< $@', # Error to use $< with no srcs",
+ ")");
+
+ ConfiguredTarget target = getConfiguredTarget("//test:bad_variable");
+ AnalysisFailureInfo info =
+ (AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());
+ AnalysisFailure failure = info.getCauses().getSet(AnalysisFailure.class).toList().get(0);
+ assertThat(failure.getMessage()).contains("variable '$<' : no input file");
+ assertThat(failure.getLabel()).isEqualTo(Label.parseAbsoluteUnchecked("//test:bad_variable"));
+ }
+
+ // Regression test for b/154007057
+ @Test
+ public void nativeRuleConfiguredTargetFactoryCreateReturningNull() throws Exception {
+ scratch.file(
+ "test/BUILD", //
+ "native_rule_with_failing_configured_target_factory(",
+ " name = 'bad_factory',",
+ ")");
+
+ ConfiguredTarget target = getConfiguredTarget("//test:bad_factory");
+ AnalysisFailureInfo info =
+ (AnalysisFailureInfo) target.get(AnalysisFailureInfo.STARLARK_CONSTRUCTOR.getKey());
+ AnalysisFailure failure = info.getCauses().getSet(AnalysisFailure.class).toList().get(0);
+ assertThat(failure.getMessage()).contains("FailingRuleConfiguredTargetFactory.create() fails");
+ assertThat(failure.getLabel()).isEqualTo(Label.parseAbsoluteUnchecked("//test:bad_factory"));
+ }
+
+ /** Dummy factory whose {@code create()} method always returns {@code null}. */
+ public static final class FailingRuleConfiguredTargetFactory
+ implements RuleConfiguredTargetFactory {
+ @Override
+ @Nullable
+ public ConfiguredTarget create(RuleContext ruleContext) {
+ ruleContext.ruleError("FailingRuleConfiguredTargetFactory.create() fails");
+ return null;
+ }
+ }
+
+ @Override
+ protected ConfiguredRuleClassProvider createRuleClassProvider() {
+ ConfiguredRuleClassProvider.Builder builder =
+ new ConfiguredRuleClassProvider.Builder()
+ .addRuleDefinition(
+ ((MockRule)
+ () ->
+ MockRule.factory(FailingRuleConfiguredTargetFactory.class)
+ .define("native_rule_with_failing_configured_target_factory")));
+ TestRuleClassProvider.addStandardRules(builder);
+ return builder.build();
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/AnalysisFailureReportingTest.java b/src/test/java/com/google/devtools/build/lib/analysis/AnalysisFailureReportingTest.java
index 16a335d..7bcba8d 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/AnalysisFailureReportingTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/AnalysisFailureReportingTest.java
@@ -114,6 +114,31 @@
Code.BUILD_FILE_MISSING)));
}
+ @Test
+ public void testExpanderFailure() throws Exception {
+ scratch.file(
+ "test/BUILD",
+ "genrule(",
+ " name = 'bad',",
+ " outs = ['bad.out'],",
+ " cmd = 'cp $< $@', # Error to use $< with no srcs",
+ ")");
+ AnalysisResult result = update(eventBus, defaultFlags().with(Flag.KEEP_GOING), "//test:bad");
+ assertThat(result.hasError()).isTrue();
+ Label topLevel = Label.parseAbsoluteUnchecked("//test:bad");
+ assertThat(collector.events.keySet()).containsExactly(topLevel);
+ assertThat(collector.events)
+ .valuesForKey(topLevel)
+ .containsExactly(
+ new AnalysisFailedCause(
+ topLevel,
+ toId(
+ Iterables.getOnlyElement(result.getTopLevelTargetsWithConfigs())
+ .getConfiguration()),
+ createAnalysisDetailedExitCode(
+ "in cmd attribute of genrule rule //test:bad: variable '$<' : no input file")));
+ }
+
/**
* This error gets reported twice - once when we try to analyze the //cycles1 target, and the
* other time when we analyze the //c target (which depends on //cycles1). This test checks that
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/BUILD b/src/test/java/com/google/devtools/build/lib/analysis/BUILD
index ab43b53..8f031ac 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/analysis/BUILD
@@ -36,6 +36,7 @@
"PackageGroupBuildViewTest.java",
"RuleConfiguredTargetTest.java",
"SourceManifestActionTest.java",
+ "AnalysisFailureInfoTest.java",
],
),
deps = [
@@ -107,11 +108,8 @@
"//src/main/java/com/google/devtools/build/lib/analysis:rule_definition_environment",
"//src/main/java/com/google/devtools/build/lib/analysis:server_directories",
"//src/main/java/com/google/devtools/build/lib/analysis:starlark/args",
- "//src/main/java/com/google/devtools/build/lib/analysis:starlark/function_transition_util",
"//src/main/java/com/google/devtools/build/lib/analysis:starlark/starlark_custom_command_line",
"//src/main/java/com/google/devtools/build/lib/analysis:target_and_configuration",
- "//src/main/java/com/google/devtools/build/lib/analysis:test/analysis_failure",
- "//src/main/java/com/google/devtools/build/lib/analysis:test/analysis_failure_info",
"//src/main/java/com/google/devtools/build/lib/analysis:test/instrumented_files_info",
"//src/main/java/com/google/devtools/build/lib/analysis:test/test_configuration",
"//src/main/java/com/google/devtools/build/lib/analysis:test/test_trimming_transition_factory",
@@ -214,6 +212,26 @@
)
java_test(
+ name = "AnalysisFailureInfoTest",
+ srcs = ["AnalysisFailureInfoTest.java"],
+ deps = [
+ "//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster",
+ "//src/main/java/com/google/devtools/build/lib/analysis:configured_target",
+ "//src/main/java/com/google/devtools/build/lib/analysis:test/analysis_failure",
+ "//src/main/java/com/google/devtools/build/lib/analysis:test/analysis_failure_info",
+ "//src/main/java/com/google/devtools/build/lib/cmdline",
+ "//src/main/java/com/google/devtools/build/lib/collect/nestedset",
+ "//src/main/java/net/starlark/java/eval",
+ "//src/test/java/com/google/devtools/build/lib/analysis/util",
+ "//src/test/java/com/google/devtools/build/lib/testutil",
+ "//third_party:guava",
+ "//third_party:jsr305",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
+java_test(
name = "AnalysisUtilsTest",
srcs = ["AnalysisUtilsTest.java"],
deps = [
@@ -345,6 +363,7 @@
"//src/test/java/com/google/devtools/build/lib/actions/util",
"//src/test/java/com/google/devtools/build/lib/analysis/util",
"//src/test/java/com/google/devtools/build/lib/testutil",
+ "//third_party:jsr305",
"//third_party:junit4",
"//third_party:truth",
],
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/RequiredConfigFragmentsTest.java b/src/test/java/com/google/devtools/build/lib/analysis/RequiredConfigFragmentsTest.java
index e60a2d1..7803f6c 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/RequiredConfigFragmentsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/RequiredConfigFragmentsTest.java
@@ -35,6 +35,7 @@
import com.google.devtools.build.lib.util.FileTypeSet;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
+import javax.annotation.Nullable;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -199,6 +200,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws ActionConflictException, InterruptedException {
return new RuleConfiguredTargetBuilder(ruleContext)
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/TransitiveValidationPropagationTest.java b/src/test/java/com/google/devtools/build/lib/analysis/TransitiveValidationPropagationTest.java
index 01ae22a..de0afb1 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/TransitiveValidationPropagationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/TransitiveValidationPropagationTest.java
@@ -29,6 +29,7 @@
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.util.List;
+import javax.annotation.Nullable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -57,6 +58,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
Artifact valid = ruleContext.createOutputArtifact();
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/allowlisting/AllowlistDummyRule.java b/src/test/java/com/google/devtools/build/lib/analysis/allowlisting/AllowlistDummyRule.java
index 1a3d607..ff2bf71 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/allowlisting/AllowlistDummyRule.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/allowlisting/AllowlistDummyRule.java
@@ -25,6 +25,7 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
+import javax.annotation.Nullable;
/** Definition of a test rule that uses allowlists. */
public final class AllowlistDummyRule {
@@ -41,6 +42,7 @@
/** Has to be public to make factory initialization logic happy. **/
public static class RuleFactory implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
if (!Allowlist.isAvailable(ruleContext, "dummy")) {
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/allowlisting/BUILD b/src/test/java/com/google/devtools/build/lib/analysis/allowlisting/BUILD
index ffed992..607c121 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/allowlisting/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/analysis/allowlisting/BUILD
@@ -27,6 +27,7 @@
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
"//src/main/java/com/google/devtools/build/lib/packages",
"//src/test/java/com/google/devtools/build/lib/analysis/util",
+ "//third_party:jsr305",
],
)
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/test/TrimTestConfigurationTest.java b/src/test/java/com/google/devtools/build/lib/analysis/test/TrimTestConfigurationTest.java
index 9ec1c08..82a42ae 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/test/TrimTestConfigurationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/test/TrimTestConfigurationTest.java
@@ -20,7 +20,6 @@
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static org.junit.Assert.assertThrows;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultiset;
import com.google.devtools.build.lib.actions.ActionLookupKey;
@@ -42,8 +41,6 @@
import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.collect.nestedset.Depset;
-import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
@@ -52,8 +49,7 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import net.starlark.java.eval.Starlark;
-import net.starlark.java.eval.StarlarkSemantics;
+import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -66,6 +62,7 @@
/** Simple native test rule. */
public static final class NativeTest implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext context)
throws ActionConflictException, InterruptedException {
Artifact executable = context.getBinArtifact(context.getLabel().getName());
@@ -866,23 +863,4 @@
ConfiguredTarget top = getConfiguredTarget("//test:starlark_dep");
assertThat(getConfiguration(top).hasFragment(TestConfiguration.class)).isTrue();
}
-
- // Test Starlark API of AnalysisFailure{,Info}.
- @Test
- public void testAnalysisFailureInfo() throws Exception {
- Label label = Label.create("test", "test");
- AnalysisFailure failure = new AnalysisFailure(label, "ErrorMessage");
- assertThat(getattr(failure, "label")).isSameInstanceAs(label);
- assertThat(getattr(failure, "message")).isEqualTo("ErrorMessage");
-
- AnalysisFailureInfo info = AnalysisFailureInfo.forAnalysisFailures(ImmutableList.of(failure));
- // info.causes.to_list()[0] == failure
- NestedSet<AnalysisFailure> causes =
- Depset.cast(getattr(info, "causes"), AnalysisFailure.class, "causes");
- assertThat(causes.toList().get(0)).isSameInstanceAs(failure);
- }
-
- private static Object getattr(Object x, String name) throws Exception {
- return Starlark.getattr(/*mu=*/ null, StarlarkSemantics.DEFAULT, x, name, null);
- }
}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BUILD b/src/test/java/com/google/devtools/build/lib/analysis/util/BUILD
index f8ae7ab..cc5d5ff 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BUILD
@@ -136,10 +136,8 @@
"//src/test/java/com/google/devtools/build/lib/testutil",
"//src/test/java/com/google/devtools/build/lib/testutil:SkyframeExecutorTestHelper",
"//src/test/java/com/google/devtools/build/lib/testutil:TestConstants",
- "//src/test/java/com/google/devtools/build/lib/testutil:TestUtils",
"//src/test/java/com/google/devtools/build/skyframe:testutil",
"//third_party:auto_value",
- "//third_party:error_prone_annotations",
"//third_party:guava",
"//third_party:jsr305",
"//third_party:junit4",
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/MockRuleDefaults.java b/src/test/java/com/google/devtools/build/lib/analysis/util/MockRuleDefaults.java
index adf3ab3..65e4827 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/MockRuleDefaults.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/MockRuleDefaults.java
@@ -38,6 +38,7 @@
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.util.FileTypeSet;
+import javax.annotation.Nullable;
/**
* Default behaviors for {@link MockRule}.
@@ -81,6 +82,7 @@
* */
public static class DefaultConfiguredTargetFactory implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
NestedSet<Artifact> filesToBuild =
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java b/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
index 521271f..199611b 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/TestAspects.java
@@ -162,6 +162,7 @@
*/
public static class DummyRuleFactory implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/config/BUILD b/src/test/java/com/google/devtools/build/lib/rules/config/BUILD
index 3dad786..fa09baf 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/config/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/rules/config/BUILD
@@ -46,6 +46,7 @@
"//src/test/java/com/google/devtools/build/lib/testutil:TestConstants",
"//third_party:guava",
"//third_party:guava-testlib",
+ "//third_party:jsr305",
"//third_party:junit4",
"//third_party:truth",
],
diff --git a/src/test/java/com/google/devtools/build/lib/rules/config/FeatureFlagSetterRule.java b/src/test/java/com/google/devtools/build/lib/rules/config/FeatureFlagSetterRule.java
index e75f84b..91613c6 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/config/FeatureFlagSetterRule.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/config/FeatureFlagSetterRule.java
@@ -34,6 +34,7 @@
import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.RuleClass;
+import javax.annotation.Nullable;
/** Rule introducing a transition to set feature flags for itself and dependencies. */
public final class FeatureFlagSetterRule implements RuleDefinition, RuleConfiguredTargetFactory {
@@ -68,6 +69,7 @@
}
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
TransitiveInfoCollection exportedFlag = ruleContext.getPrerequisite("exports_flag");
diff --git a/src/test/java/com/google/devtools/build/lib/testutil/TestRuleClassProvider.java b/src/test/java/com/google/devtools/build/lib/testutil/TestRuleClassProvider.java
index a475a1c..c5a6cc4 100644
--- a/src/test/java/com/google/devtools/build/lib/testutil/TestRuleClassProvider.java
+++ b/src/test/java/com/google/devtools/build/lib/testutil/TestRuleClassProvider.java
@@ -49,6 +49,7 @@
import com.google.devtools.build.lib.util.FileTypeSet;
import java.lang.reflect.Method;
import java.util.Map;
+import javax.annotation.Nullable;
import net.starlark.java.syntax.Location;
/** Helper class to provide a RuleClassProvider for tests. */
@@ -176,6 +177,7 @@
public static final class MakeVariableTester implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException, ActionConflictException {
Map<String, String> variables = ruleContext.attributes().get("variables", Type.STRING_DICT);
diff --git a/src/test/java/com/google/devtools/build/lib/testutil/UnknownRuleConfiguredTarget.java b/src/test/java/com/google/devtools/build/lib/testutil/UnknownRuleConfiguredTarget.java
index ea0bed6..2bd4116 100644
--- a/src/test/java/com/google/devtools/build/lib/testutil/UnknownRuleConfiguredTarget.java
+++ b/src/test/java/com/google/devtools/build/lib/testutil/UnknownRuleConfiguredTarget.java
@@ -29,6 +29,7 @@
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.server.FailureDetails.FailAction.Code;
+import javax.annotation.Nullable;
/**
* A null implementation of ConfiguredTarget for rules we don't know how to build.
@@ -36,6 +37,7 @@
public class UnknownRuleConfiguredTarget implements RuleConfiguredTargetFactory {
@Override
+ @Nullable
public ConfiguredTarget create(RuleContext context)
throws InterruptedException, RuleErrorException, ActionConflictException {
// TODO(bazel-team): (2009) why isn't this an error? It would stop the build more promptly...