diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java index 76cdaf3c8f829c..12a8dab85f2b3c 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java @@ -52,8 +52,6 @@ public final class SkyFunctions { static final SkyFunctionName PACKAGE_ERROR = SkyFunctionName.createHermetic("PACKAGE_ERROR"); public static final SkyFunctionName PACKAGE_ERROR_MESSAGE = SkyFunctionName.createHermetic("PACKAGE_ERROR_MESSAGE"); - public static final SkyFunctionName TARGET_MARKER = - SkyFunctionName.createHermetic("TARGET_MARKER"); // Semi-hermetic because accesses package locator public static final SkyFunctionName TARGET_PATTERN = SkyFunctionName.createSemiHermetic("TARGET_PATTERN"); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java index 2fef30232492c2..1056a98e35bf0f 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java @@ -536,7 +536,6 @@ private ImmutableMap skyFunctions(PackageFactory p : IncrementalityIntent.NON_INCREMENTAL)); map.put(SkyFunctions.PACKAGE_ERROR, new PackageErrorFunction()); map.put(SkyFunctions.PACKAGE_ERROR_MESSAGE, new PackageErrorMessageFunction()); - map.put(SkyFunctions.TARGET_MARKER, new TargetMarkerFunction()); map.put(SkyFunctions.TARGET_PATTERN_ERROR, new TargetPatternErrorFunction()); map.put(SkyFunctions.TRANSITIVE_TARGET, new TransitiveTargetFunction(ruleClassProvider)); map.put(Label.TRANSITIVE_TRAVERSAL, new TransitiveTraversalFunction()); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitor.java index 66bc2ee8a3e1e0..082b3a926986c0 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitor.java @@ -84,20 +84,36 @@ public boolean sync( if (!keepGoing) { // We may have multiple errors, but in non keep_going builds, we're obligated to print only // one of them. - Preconditions.checkState(!errors.isEmpty(), result); - Map.Entry error = errors.iterator().next(); - ErrorInfo errorInfo = error.getValue(); - SkyKey topLevel = error.getKey(); - Label topLevelLabel = ((TransitiveTargetKey) topLevel).getLabel(); - if (!Iterables.isEmpty(errorInfo.getCycleInfo())) { - skyframeCyclesReporter.get().reportCycles(errorInfo.getCycleInfo(), topLevel, eventHandler); - errorAboutLoadingFailure(topLevelLabel, null, eventHandler); - } else if (isDirectErrorFromTopLevelLabel(topLevelLabel, labelsToVisit, errorInfo)) { - // An error caused by a non-top-level label has already been reported during error - // bubbling but an error caused by the top-level non-target label itself hasn't been - // reported yet. Note that errors from top-level targets have already been reported - // during target parsing. - errorAboutLoadingFailure(topLevelLabel, errorInfo.getException(), eventHandler); + if (!errors.isEmpty()) { + Map.Entry error = errors.iterator().next(); + ErrorInfo errorInfo = error.getValue(); + SkyKey topLevel = error.getKey(); + Label topLevelLabel = ((TransitiveTargetKey) topLevel).getLabel(); + if (!errorInfo.getCycleInfo().isEmpty()) { + skyframeCyclesReporter + .get() + .reportCycles(errorInfo.getCycleInfo(), topLevel, eventHandler); + errorAboutLoadingFailure(topLevelLabel, null, eventHandler); + } else if (isDirectErrorFromTopLevelLabel(topLevelLabel, labelsToVisit, errorInfo)) { + // An error caused by a non-top-level label has already been reported during error + // bubbling but an error caused by the top-level non-target label itself hasn't been + // reported yet. Note that errors from top-level targets have already been reported + // during target parsing. + errorAboutLoadingFailure(topLevelLabel, errorInfo.getException(), eventHandler); + } + } else { + for (TransitiveTargetKey topLevelTransitiveTargetKey : + result.keyNames()) { + TransitiveTargetValue topLevelTransitiveTargetValue = + result.get(topLevelTransitiveTargetKey); + if (topLevelTransitiveTargetValue.getTransitiveRootCauses() != null) { + errorAboutLoadingFailure( + topLevelTransitiveTargetKey.getLabel(), + topLevelTransitiveTargetValue.getErrorLoadingTarget(), + eventHandler); + break; + } + } } return false; } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TargetMarkerFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TargetMarkerFunction.java deleted file mode 100644 index 234eb6c9ecd07c..00000000000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/TargetMarkerFunction.java +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2014 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.skyframe; - -import com.google.devtools.build.lib.actions.InconsistentFilesystemException; -import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.cmdline.PackageIdentifier; -import com.google.devtools.build.lib.packages.BuildFileNotFoundException; -import com.google.devtools.build.lib.packages.NoSuchPackageException; -import com.google.devtools.build.lib.packages.NoSuchTargetException; -import com.google.devtools.build.lib.packages.Package; -import com.google.devtools.build.lib.packages.Target; -import com.google.devtools.build.lib.vfs.PathFragment; -import com.google.devtools.build.skyframe.SkyFunction; -import com.google.devtools.build.skyframe.SkyFunctionException; -import com.google.devtools.build.skyframe.SkyKey; -import com.google.devtools.build.skyframe.SkyValue; -import javax.annotation.Nullable; - -/** - * A SkyFunction for {@link TargetMarkerValue}s. Returns a {@link - * TargetMarkerValue#TARGET_MARKER_INSTANCE} if the {@link Label} in the {@link SkyKey} - * specifies a {@link Package} that exists and a {@link Target} that exists in that package. The - * package may have errors. - */ -public final class TargetMarkerFunction implements SkyFunction { - - @Override - public SkyValue compute(SkyKey key, Environment env) - throws TargetMarkerFunctionException, InterruptedException { - try { - return computeTargetMarkerValue(key, env); - } catch (NoSuchTargetException e) { - throw new TargetMarkerFunctionException(e); - } catch (NoSuchPackageException e) { - // Re-throw this exception with our key because root causes should be targets, not packages. - throw new TargetMarkerFunctionException(e); - } - } - - @Nullable - static TargetMarkerValue computeTargetMarkerValue(SkyKey key, Environment env) - throws NoSuchTargetException, NoSuchPackageException, InterruptedException { - Label label = (Label) key.argument(); - PathFragment pkgForLabel = label.getPackageFragment(); - - if (label.getName().contains("/")) { - // This target is in a subdirectory, therefore it could potentially be invalidated by - // a new BUILD file appearing in the hierarchy. - PathFragment containingDirectory = getContainingDirectory(label); - ContainingPackageLookupValue containingPackageLookupValue; - try { - PackageIdentifier newPkgId = PackageIdentifier.create( - label.getPackageIdentifier().getRepository(), containingDirectory); - containingPackageLookupValue = (ContainingPackageLookupValue) env.getValueOrThrow( - ContainingPackageLookupValue.key(newPkgId), - BuildFileNotFoundException.class, InconsistentFilesystemException.class); - } catch (InconsistentFilesystemException e) { - throw new NoSuchTargetException(label, e.getMessage()); - } - if (containingPackageLookupValue == null) { - return null; - } - - if (!containingPackageLookupValue.hasContainingPackage()) { - // This means the label's package doesn't exist. E.g. there is no package 'a' and we are - // trying to build the target for label 'a:b/foo'. - throw new BuildFileNotFoundException( - label.getPackageIdentifier(), - "BUILD file not found on package path for '" + pkgForLabel.getPathString() + "'"); - } - if (!containingPackageLookupValue.getContainingPackageName().equals( - label.getPackageIdentifier())) { - throw new NoSuchTargetException( - label, - String.format( - "Label '%s' crosses boundary of subpackage '%s'", - label, - containingPackageLookupValue.getContainingPackageName())); - } - } - - SkyKey pkgSkyKey = PackageValue.key(label.getPackageIdentifier()); - PackageValue value = - (PackageValue) env.getValueOrThrow(pkgSkyKey, NoSuchPackageException.class); - if (value == null) { - return null; - } - - Package pkg = value.getPackage(); - Target target = pkg.getTarget(label.getName()); - if (pkg.containsErrors()) { - // There is a target, but its package is in error. We rethrow so that the root cause is the - // target, not the package. Note that targets are only in error when their package is - // "in error" (because a package is in error if there was an error evaluating the package, or - // if one of its targets was in error). - throw new NoSuchTargetException(target); - } - return TargetMarkerValue.TARGET_MARKER_INSTANCE; - } - - private static PathFragment getContainingDirectory(Label label) { - PathFragment pkg = label.getPackageFragment(); - String name = label.getName(); - return name.equals(".") ? pkg : pkg.getRelative(name).getParentDirectory(); - } - - @Override - public String extractTag(SkyKey skyKey) { - return Label.print((Label) skyKey.argument()); - } - - /** - * Used to declare all the exception types that can be wrapped in the exception thrown by - * {@link TargetMarkerFunction#compute}. - */ - private static final class TargetMarkerFunctionException extends SkyFunctionException { - public TargetMarkerFunctionException(NoSuchTargetException e) { - super(e, Transience.PERSISTENT); - } - - public TargetMarkerFunctionException(NoSuchPackageException e) { - super(e, Transience.PERSISTENT); - } - } -} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TargetMarkerValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/TargetMarkerValue.java deleted file mode 100644 index caf37202c3cb61..00000000000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/TargetMarkerValue.java +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2014 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.skyframe; - -import com.google.common.base.Preconditions; -import com.google.common.collect.Interner; -import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.concurrent.BlazeInterners; -import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; -import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; -import com.google.devtools.build.skyframe.AbstractSkyKey; -import com.google.devtools.build.skyframe.SkyFunctionName; -import com.google.devtools.build.skyframe.SkyValue; - -/** - * Value represents visited target in the Skyframe graph after error checking. - */ -@Immutable -@ThreadSafe -public final class TargetMarkerValue implements SkyValue { - - // Note that this value does not guarantee singleton-like reference equality because we use Java - // deserialization. java deserialization can create other instances. - @AutoCodec public static final TargetMarkerValue TARGET_MARKER_INSTANCE = new TargetMarkerValue(); - - private TargetMarkerValue() { - } - - @Override - public boolean equals(Object o) { - return o instanceof TargetMarkerValue; - } - - @Override - public int hashCode() { - return 42; - } - - @ThreadSafe - public static Key key(Label label) { - Preconditions.checkArgument(!label.getPackageIdentifier().getRepository().isDefault()); - return Key.create(label); - } - - @AutoCodec.VisibleForSerialization - @AutoCodec - static class Key extends AbstractSkyKey