Use Labels, rather than PathFragments, to represent Skylark loads internally. The load location for a Skylark Aspect is specified via a PathFragment, for consistency with current non-Aspect Skylark loads.
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=107741568
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
index 670380c..67ca431 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
@@ -31,8 +31,6 @@
*/
public final class LoadStatement extends Statement {
- public static final String PATH_ERROR_MSG = "Path '%s' is not valid. "
- + "It should either start with a slash or refer to a file in the current directory.";
private final ImmutableMap<Identifier, String> symbols;
private final ImmutableList<Identifier> cachedSymbols; // to save time
private final PathFragment importPath;
@@ -41,10 +39,9 @@
/**
* Constructs an import statement.
*
- * <p>Symbols maps a symbol to its original name under which it was defined in
- * the bzl file that should be loaded.
- * If aliasing is used, the value differs from it's key's symbol#getName().
- * Otherwise, both values are identical.
+ * <p>{@code symbols} maps a symbol to the original name under which it was defined in
+ * the bzl file that should be loaded. If aliasing is used, the value differs from its key's
+ * {@code symbol.getName()}. Otherwise, both values are identical.
*/
LoadStatement(StringLiteral path, Map<Identifier, String> symbols) {
this.symbols = ImmutableMap.copyOf(symbols);
@@ -77,7 +74,7 @@
getLocation(), "symbol '" + current + "' is private and cannot be imported.");
}
// The key is the original name that was used to define the symbol
- // in the loaded bzl file
+ // in the loaded bzl file.
env.importSymbol(getImportPath(), current, entry.getValue());
} catch (Environment.NoSuchVariableException | Environment.LoadFailedException e) {
throw new EvalException(getLocation(), e.getMessage());
@@ -93,10 +90,6 @@
@Override
void validate(ValidationEnvironment env) throws EvalException {
validatePath();
-
- if (!importPath.isAbsolute() && importPath.segmentCount() > 1) {
- throw new EvalException(getLocation(), String.format(PATH_ERROR_MSG, importPath));
- }
for (Identifier symbol : cachedSymbols) {
env.declare(symbol.getName(), getLocation());
}
@@ -119,6 +112,11 @@
error =
"First argument of load() is a path, not a label. "
+ "It should start with a single slash if it is an absolute path.";
+ } else if (!importPath.isAbsolute() && importPath.segmentCount() > 1) {
+ error = String.format(
+ "Path '%s' is not valid. "
+ + "It should either start with a slash or refer to a file in the current directory.",
+ importPath);
}
if (error != null) {
@@ -133,4 +131,8 @@
"load statements should never appear in method bodies and"
+ " should never be compiled in general");
}
+
+ public boolean isAbsolute() {
+ return getImportPath().isAbsolute();
+ }
}