aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
diff options
context:
space:
mode:
authorGravatar John Field <jfield@google.com>2015-09-21 18:59:19 +0000
committerGravatar Laszlo Csomor <laszlocsomor@google.com>2015-09-22 17:05:23 +0000
commit925dc5ce1c6916b43a94fa12017aa4a6390de891 (patch)
tree17da1c801a23290c563bcf4347dd90930f094c12 /src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
parentd256a821f4051273e3be1617c793c6dc5e77d964 (diff)
Use Labels, rather than PathFragments, to represent Skylark loads internally. This should be a semantics-preserving change for users. In a subsequent CL, I'll change the Skylark syntax to allow load statements to use labels as well as paths, with the goal of eventually deprecating the latter.
Also: - Removed the hack for handling relative loads in the prelude file. - Refactored some redundant functionality in PackageFunction and SkylarkImportLookupFunction for handling loads. - Removed the ability to put the BUILD file for the package containing a Skylark file under a different package root than the Skylark file itself. This functionality isn't currently used and is inconsistent with Blaze's handling of the package path elsewhere. - Added BUILD files to a number of tests that load Skylark files; this is consistent with the requirement that all Skylark files need to be part of some package. - Changed the constants used to set the location of the prelude file from paths to labels. -- MOS_MIGRATED_REVID=103567562
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java198
1 files changed, 62 insertions, 136 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
index a7cd395b33..130386793e 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
@@ -14,10 +14,8 @@
package com.google.devtools.build.lib.skyframe;
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.RuleClassProvider;
-import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
import com.google.devtools.build.lib.syntax.BuildFileAST;
import com.google.devtools.build.lib.syntax.Mutability;
import com.google.devtools.build.lib.syntax.Runtime;
@@ -32,167 +30,95 @@ import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;
/**
- * A SkyFunction for {@link ASTFileLookupValue}s. Tries to locate a file and load it as a
- * syntax tree and cache the resulting {@link BuildFileAST}. If the file doesn't exist
- * the function doesn't fail but returns a specific NO_FILE ASTLookupValue.
+ * A SkyFunction for {@link ASTFileLookupValue}s. Given a Label referencing a Skylark file,
+ * attempts to locate the file and load it as a syntax tree ({@link BuildFileAST}). If the file
+ * (or the package containing it) doesn't exist, the function doesn't fail, but instead returns a
+ * specific {@code NO_FILE} {@link ASTFileLookupValue}.
*/
public class ASTFileLookupFunction implements SkyFunction {
- private abstract static class FileLookupResult {
- /** Returns whether the file lookup was successful. */
- public abstract boolean lookupSuccessful();
-
- /** If {@code lookupSuccessful()}, returns the {@link RootedPath} to the file. */
- public abstract RootedPath rootedPath();
-
- /** If {@code lookupSuccessful()}, returns the file's size, in bytes. */
- public abstract long fileSize();
-
- static FileLookupResult noFile() {
- return UnsuccessfulFileResult.INSTANCE;
- }
-
- static FileLookupResult file(RootedPath rootedPath, long fileSize) {
- return new SuccessfulFileResult(rootedPath, fileSize);
- }
-
- private static class SuccessfulFileResult extends FileLookupResult {
- private final RootedPath rootedPath;
- private final long fileSize;
-
- private SuccessfulFileResult(RootedPath rootedPath, long fileSize) {
- this.rootedPath = rootedPath;
- this.fileSize = fileSize;
- }
-
- @Override
- public boolean lookupSuccessful() {
- return true;
- }
-
- @Override
- public RootedPath rootedPath() {
- return rootedPath;
- }
-
- @Override
- public long fileSize() {
- return fileSize;
- }
- }
-
- private static class UnsuccessfulFileResult extends FileLookupResult {
- private static final UnsuccessfulFileResult INSTANCE = new UnsuccessfulFileResult();
- private UnsuccessfulFileResult() {
- }
-
- @Override
- public boolean lookupSuccessful() {
- return false;
- }
-
- @Override
- public RootedPath rootedPath() {
- throw new IllegalStateException("unsuccessful lookup");
- }
-
- @Override
- public long fileSize() {
- throw new IllegalStateException("unsuccessful lookup");
- }
- }
- }
-
- private final AtomicReference<PathPackageLocator> pkgLocator;
private final RuleClassProvider ruleClassProvider;
- public ASTFileLookupFunction(AtomicReference<PathPackageLocator> pkgLocator,
- RuleClassProvider ruleClassProvider) {
- this.pkgLocator = pkgLocator;
+ public ASTFileLookupFunction(RuleClassProvider ruleClassProvider) {
this.ruleClassProvider = ruleClassProvider;
}
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException,
InterruptedException {
- PackageIdentifier key = (PackageIdentifier) skyKey.argument();
- PathFragment astFilePathFragment = key.getPackageFragment();
- FileLookupResult lookupResult = getASTFile(env, key);
- if (lookupResult == null) {
+ Label fileLabel = (Label) skyKey.argument();
+ PathFragment filePathFragment = fileLabel.toPathFragment();
+
+ /*
+ * Determine whether the package designated by fileLabel exists.
+ */
+ SkyKey pkgSkyKey = PackageLookupValue.key(fileLabel.getPackageIdentifier());
+ PackageLookupValue pkgLookupValue = null;
+ pkgLookupValue = (PackageLookupValue) env.getValue(pkgSkyKey);
+ if (pkgLookupValue == null) {
return null;
}
- if (!lookupResult.lookupSuccessful()) {
- return ASTFileLookupValue.noFile();
+ if (!pkgLookupValue.packageExists()) {
+ return ASTFileLookupValue.forBadPackage(fileLabel, pkgLookupValue.getErrorMsg());
}
+
+ /*
+ * Determine whether the file designated by fileLabel exists.
+ */
+ Path packageRoot = pkgLookupValue.getRoot();
+ RootedPath rootedPath = RootedPath.toRootedPath(packageRoot, filePathFragment);
+ SkyKey fileSkyKey = FileValue.key(rootedPath);
+ FileValue fileValue = null;
+ try {
+ fileValue = (FileValue) env.getValueOrThrow(fileSkyKey, IOException.class,
+ FileSymlinkException.class, InconsistentFilesystemException.class);
+ } catch (IOException | FileSymlinkException e) {
+ throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(
+ e.getMessage()), Transience.PERSISTENT);
+ } catch (InconsistentFilesystemException e) {
+ throw new ASTLookupFunctionException(e, Transience.PERSISTENT);
+ }
+ if (fileValue == null) {
+ return null;
+ }
+ if (!fileValue.isFile()) {
+ return ASTFileLookupValue.forBadFile(fileLabel);
+ }
+
+ /*
+ * Both the package and the file exist; load the file and parse it as an AST.
+ */
BuildFileAST ast = null;
- Path path = lookupResult.rootedPath().asPath();
- long fileSize = lookupResult.fileSize();
- // Skylark files end with bzl.
- boolean parseAsSkylark = astFilePathFragment.getPathString().endsWith(".bzl");
+ Path path = rootedPath.asPath();
+ // Skylark files end with bzl
+ boolean parseAsSkylark = filePathFragment.getPathString().endsWith(".bzl");
try {
+ long astFileSize = fileValue.getSize();
if (parseAsSkylark) {
try (Mutability mutability = Mutability.create("validate")) {
- ast = BuildFileAST.parseSkylarkFile(path, fileSize, env.getListener(),
- new ValidationEnvironment(
- ruleClassProvider.createSkylarkRuleClassEnvironment(
- mutability,
- env.getListener(),
- // the two below don't matter for extracting the ValidationEnvironment:
- /*astFileContentHashCode=*/null,
- /*importMap=*/null)
- .setupDynamic(Runtime.PKG_NAME, Runtime.NONE)));
+ ast = BuildFileAST.parseSkylarkFile(path, astFileSize, env.getListener(),
+ new ValidationEnvironment(
+ ruleClassProvider.createSkylarkRuleClassEnvironment(
+ mutability,
+ env.getListener(),
+ // the two below don't matter for extracting the ValidationEnvironment:
+ /*astFileContentHashCode=*/null,
+ /*importMap=*/null)
+ .setupDynamic(Runtime.PKG_NAME, Runtime.NONE)));
}
} else {
- ast = BuildFileAST.parseBuildFile(path, fileSize, env.getListener(), false);
+ ast = BuildFileAST.parseBuildFile(path, astFileSize, env.getListener(), false);
}
} catch (IOException e) {
- throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(
- e.getMessage()), Transience.TRANSIENT);
- }
- return ASTFileLookupValue.withFile(ast);
- }
-
- private FileLookupResult getASTFile(Environment env, PackageIdentifier key)
- throws ASTLookupFunctionException {
- List<Path> candidateRoots;
- if (!key.getRepository().isDefault()) {
- RepositoryValue repository =
- (RepositoryValue) env.getValue(RepositoryValue.key(key.getRepository()));
- if (repository == null) {
- return null;
- }
-
- candidateRoots = ImmutableList.of(repository.getPath());
- } else {
- candidateRoots = pkgLocator.get().getPathEntries();
+ throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(
+ e.getMessage()), Transience.TRANSIENT);
}
- for (Path root : candidateRoots) {
- RootedPath rootedPath = RootedPath.toRootedPath(root, key.getPackageFragment());
- FileValue fileValue;
- try {
- fileValue = (FileValue) env.getValueOrThrow(FileValue.key(rootedPath),
- IOException.class, FileSymlinkException.class, InconsistentFilesystemException.class);
- } catch (IOException | FileSymlinkException e) {
- throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(
- e.getMessage()), Transience.PERSISTENT);
- } catch (InconsistentFilesystemException e) {
- throw new ASTLookupFunctionException(e, Transience.PERSISTENT);
- }
- if (fileValue == null) {
- return null;
- }
- if (fileValue.isFile()) {
- return FileLookupResult.file(rootedPath, fileValue.getSize());
- }
- }
- return FileLookupResult.noFile();
+ return ASTFileLookupValue.withFile(ast);
}
@Nullable