aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar brandjon <brandjon@google.com>2017-04-29 16:03:32 +0200
committerGravatar Vladimir Moskva <vladmos@google.com>2017-04-30 23:14:25 +0200
commitb712f335a945c81a6b77fd48e96103ff09c8967b (patch)
treeb8ac0e5aa200cf19717aa22e51cb9abc457be572
parente7fe50aa727df9ef0a3d37fa258d017971035515 (diff)
Make Skylark interpreter read Skylark command-line flags
This is the second of two CLs for making command line options able to affect the Skylark interpreter. For the main kinds of evaluation contexts -- package loading, .bzl loading, rule analysis, aspect analysis, and computed defaults -- the SkylarkSemanticsOptions object is retrieved from Skyframe and passed along to the Environment builder. For other contexts such as tests, default values of builtin functions, and standalone Skylark, flags are currently not processed. In the future, we may want to split into separate files the options that affect "pure" Skylark vs the options that affect Bazel-flavored Skylark. One possibility is to subclass SkylarkSemanticsOptions into SkylarkBazelSemanticsOptions, and go through an indirection in SkylarkUtils. We could also pass SkylarkSemanticsOptions to the parser, to support --incompatible_* changes that alter Skylark's syntax. I don't think that's needed at the moment. RELNOTES: None PiperOrigin-RevId: 154628391
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/AnalysisEnvironment.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java23
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java20
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java18
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/Environment.java22
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemanticsOptions.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java1
-rw-r--r--src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java11
-rw-r--r--src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java5
-rw-r--r--src/test/java/com/google/devtools/build/lib/packages/util/PackageFactoryApparatus.java3
-rw-r--r--src/test/shell/integration/BUILD7
-rwxr-xr-xsrc/test/shell/integration/skylark_flag_test.sh104
23 files changed, 269 insertions, 16 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisEnvironment.java b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisEnvironment.java
index 70b8e51967..f97f14afe8 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisEnvironment.java
@@ -25,6 +25,7 @@ import com.google.devtools.build.lib.actions.Root;
import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory.BuildInfoKey;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
+import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.skyframe.SkyFunction;
import java.util.List;
@@ -118,6 +119,12 @@ public interface AnalysisEnvironment extends ActionRegistry {
SkyFunction.Environment getSkyframeEnv();
/**
+ * Returns the options that affect the Skylark interpreter used for evaluating Skylark rule
+ * implementation functions.
+ */
+ SkylarkSemanticsOptions getSkylarkSemantics() throws InterruptedException;
+
+ /**
* Returns the Artifact that is used to hold the non-volatile workspace status for the current
* build request.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java b/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java
index ddf5b99fe4..4198e0ca45 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java
@@ -33,6 +33,7 @@ import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.skyframe.BuildInfoCollectionValue;
import com.google.devtools.build.lib.skyframe.PrecomputedValue;
import com.google.devtools.build.lib.skyframe.WorkspaceStatusValue;
+import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.skyframe.SkyFunction;
@@ -280,6 +281,11 @@ public class CachingAnalysisEnvironment implements AnalysisEnvironment {
}
@Override
+ public SkylarkSemanticsOptions getSkylarkSemantics() throws InterruptedException {
+ return PrecomputedValue.SKYLARK_SEMANTICS.get(skyframeEnv);
+ }
+
+ @Override
public Artifact getStableWorkspaceStatusArtifact() throws InterruptedException {
return ((WorkspaceStatusValue) skyframeEnv.getValue(WorkspaceStatusValue.SKY_KEY))
.getStableArtifact();
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
index 568e773d81..7c2b34c7c7 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
@@ -54,8 +54,10 @@ import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.Environment.Extension;
import com.google.devtools.build.lib.syntax.Environment.Phase;
import com.google.devtools.build.lib.syntax.Mutability;
+import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
import com.google.devtools.build.lib.syntax.SkylarkUtils;
import com.google.devtools.build.lib.syntax.Type;
+import com.google.devtools.common.options.Options;
import com.google.devtools.common.options.OptionsClassProvider;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
@@ -717,7 +719,12 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider {
ImmutableList<Class<?>> modules) {
try (Mutability mutability = Mutability.create("ConfiguredRuleClassProvider globals")) {
Environment env = createSkylarkRuleClassEnvironment(
- mutability, SkylarkModules.getGlobals(modules), null, null, null);
+ mutability,
+ SkylarkModules.getGlobals(modules),
+ Options.getDefaults(SkylarkSemanticsOptions.class),
+ /*eventHandler=*/ null,
+ /*astFileContentHashCode=*/ null,
+ /*importMap=*/ null);
for (Map.Entry<String, Object> entry : skylarkAccessibleToplLevels.entrySet()) {
env.setup(entry.getKey(), entry.getValue());
}
@@ -728,12 +735,14 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider {
private Environment createSkylarkRuleClassEnvironment(
Mutability mutability,
Environment.Frame globals,
+ SkylarkSemanticsOptions skylarkSemantics,
EventHandler eventHandler,
String astFileContentHashCode,
Map<String, Extension> importMap) {
Environment env =
Environment.builder(mutability)
.setGlobals(globals)
+ .setSemantics(skylarkSemantics)
.setEventHandler(eventHandler)
.setFileContentHashCode(astFileContentHashCode)
.setImportedExtensions(importMap)
@@ -745,13 +754,19 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider {
@Override
public Environment createSkylarkRuleClassEnvironment(
- Label extensionLabel, Mutability mutability,
+ Label extensionLabel,
+ Mutability mutability,
+ SkylarkSemanticsOptions skylarkSemantics,
EventHandler eventHandler,
String astFileContentHashCode,
Map<String, Extension> importMap) {
return createSkylarkRuleClassEnvironment(
- mutability, globals.setLabel(extensionLabel),
- eventHandler, astFileContentHashCode, importMap);
+ mutability,
+ globals.setLabel(extensionLabel),
+ skylarkSemantics,
+ eventHandler,
+ astFileContentHashCode,
+ importMap);
}
@Override
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 f5344d1daa..d560923c8d 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
@@ -269,6 +269,7 @@ public final class ConfiguredTargetFactory {
return SkylarkRuleConfiguredTargetBuilder.buildRule(
ruleContext,
rule.getRuleClassObject().getConfiguredTargetFunction(),
+ env.getSkylarkSemantics(),
ruleClassProvider.getRegisteredSkylarkProviders());
} else {
RuleClass.ConfiguredTargetFactory<ConfiguredTarget, RuleContext> factory =
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java
index 497a7d7d5f..b1c0992f6b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java
@@ -76,6 +76,7 @@ public class SkylarkRepositoryFunction extends RepositoryFunction {
return null;
}
try (Mutability mutability = Mutability.create("skylark repository")) {
+ // This Skylark environment ignores command line flags.
com.google.devtools.build.lib.syntax.Environment buildEnv =
com.google.devtools.build.lib.syntax.Environment.builder(mutability)
.setGlobals(rule.getRuleClassObject().getRuleDefinitionEnvironment().getGlobals())
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index e237d9af8e..a6a6614012 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -59,6 +59,7 @@ import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
+import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
import com.google.devtools.build.lib.syntax.SkylarkUtils;
import com.google.devtools.build.lib.syntax.Statement;
@@ -69,6 +70,7 @@ import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.UnixGlob;
+import com.google.devtools.common.options.Options;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -294,7 +296,7 @@ public final class PackageFactory {
public Token runAsync(List<String> includes, List<String> excludes, boolean excludeDirs)
throws BadGlobException {
for (String pattern : Iterables.concat(includes, excludes)) {
- @SuppressWarnings("unused")
+ @SuppressWarnings("unused")
Future<?> possiblyIgnoredError = globCache.getGlobUnsortedAsync(pattern, excludeDirs);
}
return new Token(includes, excludes, excludeDirs);
@@ -350,14 +352,14 @@ public final class PackageFactory {
public final PackageFactory create(RuleClassProvider ruleClassProvider, FileSystem fs) {
return create(ruleClassProvider, null, ImmutableList.<EnvironmentExtension>of(), fs);
}
-
+
public final PackageFactory create(
RuleClassProvider ruleClassProvider,
EnvironmentExtension environmentExtension,
FileSystem fs) {
return create(ruleClassProvider, null, ImmutableList.of(environmentExtension), fs);
}
-
+
public final PackageFactory create(
RuleClassProvider ruleClassProvider,
Map<String, String> platformSetRegexps,
@@ -371,7 +373,7 @@ public final class PackageFactory {
"test",
fs);
}
-
+
protected abstract PackageFactory create(
RuleClassProvider ruleClassProvider,
Map<String, String> platformSetRegexps,
@@ -1288,6 +1290,7 @@ public final class PackageFactory {
Map<String, Extension> imports,
ImmutableList<Label> skylarkFileDependencies,
RuleVisibility defaultVisibility,
+ SkylarkSemanticsOptions skylarkSemantics,
Globber globber)
throws InterruptedException {
StoredEventHandler localReporterForParsing = new StoredEventHandler();
@@ -1305,6 +1308,7 @@ public final class PackageFactory {
imports,
skylarkFileDependencies,
defaultVisibility,
+ skylarkSemantics,
globber);
}
@@ -1325,6 +1329,7 @@ public final class PackageFactory {
Map<String, Extension> imports,
ImmutableList<Label> skylarkFileDependencies,
RuleVisibility defaultVisibility,
+ SkylarkSemanticsOptions skylarkSemantics,
Globber globber) throws InterruptedException {
MakeEnvironment.Builder makeEnv = new MakeEnvironment.Builder();
if (platformSetRegexps != null) {
@@ -1339,6 +1344,7 @@ public final class PackageFactory {
buildFile,
globber,
defaultVisibility,
+ skylarkSemantics,
makeEnv,
imports);
return evaluateBuildFile(
@@ -1349,6 +1355,7 @@ public final class PackageFactory {
globber,
astAfterPreprocessing.allEvents,
defaultVisibility,
+ skylarkSemantics,
false /* containsError */,
makeEnv,
imports,
@@ -1421,6 +1428,7 @@ public final class PackageFactory {
/*imports=*/ ImmutableMap.<String, Extension>of(),
/*skylarkFileDependencies=*/ ImmutableList.<Label>of(),
/*defaultVisibility=*/ ConstantRuleVisibility.PUBLIC,
+ Options.getDefaults(SkylarkSemanticsOptions.class),
globber)
.build();
Event.replayEventsOn(eventHandler, result.getEvents());
@@ -1647,6 +1655,7 @@ public final class PackageFactory {
Globber globber,
Iterable<Event> pastEvents,
RuleVisibility defaultVisibility,
+ SkylarkSemanticsOptions skylarkSemantics,
boolean containsError,
MakeEnvironment.Builder pkgMakeEnv,
Map<String, Extension> imports,
@@ -1660,6 +1669,7 @@ public final class PackageFactory {
Environment pkgEnv =
Environment.builder(mutability)
.setGlobals(BazelLibrary.GLOBALS)
+ .setSemantics(skylarkSemantics)
.setEventHandler(eventHandler)
.setImportedExtensions(imports)
.setPhase(Phase.LOADING)
@@ -1719,6 +1729,7 @@ public final class PackageFactory {
Path buildFilePath,
Globber globber,
RuleVisibility defaultVisibility,
+ SkylarkSemanticsOptions skylarkSemantics,
MakeEnvironment.Builder pkgMakeEnv,
Map<String, Extension> imports)
throws InterruptedException {
@@ -1731,6 +1742,7 @@ public final class PackageFactory {
Environment pkgEnv =
Environment.builder(mutability)
.setGlobals(BazelLibrary.GLOBALS)
+ .setSemantics(skylarkSemantics)
.setEventHandler(NullEventHandler.INSTANCE)
.setImportedExtensions(imports)
.setPhase(Phase.LOADING)
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
index f5cf092fc4..ba7fb2ff90 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
@@ -19,9 +19,8 @@ import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.Environment.Extension;
import com.google.devtools.build.lib.syntax.Mutability;
-
+import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
import java.util.Map;
-
import javax.annotation.Nullable;
/**
@@ -51,6 +50,7 @@ public interface RuleClassProvider {
*
* @param label the location of the rule.
* @param mutability the Mutability for the current evaluation context
+ * @param skylarkSemantics the semantics options that modify the interpreter
* @param eventHandler the EventHandler for warnings, errors, etc.
* @param astFileContentHashCode the hash code identifying this environment.
* @return an Environment, in which to evaluate load time skylark forms.
@@ -58,6 +58,7 @@ public interface RuleClassProvider {
Environment createSkylarkRuleClassEnvironment(
Label label,
Mutability mutability,
+ SkylarkSemanticsOptions skylarkSemantics,
EventHandler eventHandler,
@Nullable String astFileContentHashCode,
@Nullable Map<String, Extension> importMap);
diff --git a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
index abe66c67bb..03a1050b0e 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
@@ -183,6 +183,7 @@ public class WorkspaceFactory {
private void execute(BuildFileAST ast, @Nullable Map<String, Extension> importedExtensions,
StoredEventHandler localReporter)
throws InterruptedException {
+ // Note that this Skylark environment ignores command line flags.
Environment.Builder environmentBuilder =
Environment.builder(mutability)
.setGlobals(BazelLibrary.GLOBALS)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
index b9c705739f..51295707de 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
@@ -46,6 +46,7 @@ import com.google.devtools.build.lib.syntax.Mutability;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
import com.google.devtools.build.lib.syntax.SkylarkType;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.FileType;
@@ -68,6 +69,7 @@ public final class SkylarkRuleConfiguredTargetBuilder {
public static ConfiguredTarget buildRule(
RuleContext ruleContext,
BaseFunction ruleImplementation,
+ SkylarkSemanticsOptions skylarkSemantics,
Map<String, Class<? extends TransitiveInfoProvider>> registeredProviderTypes)
throws InterruptedException {
String expectFailure = ruleContext.attributes().get("expect_failure", Type.STRING);
@@ -78,6 +80,7 @@ public final class SkylarkRuleConfiguredTargetBuilder {
.setCallerLabel(ruleContext.getLabel())
.setGlobals(
ruleContext.getRule().getRuleClassObject().getRuleDefinitionEnvironment().getGlobals())
+ .setSemantics(skylarkSemantics)
.setEventHandler(ruleContext.getAnalysisEnvironment().getEventHandler())
.build(); // NB: loading phase functions are not available: this is analysis already,
// so we do *not* setLoadingPhase().
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 e6b3a958a3..d3a75d8cfd 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
@@ -20,6 +20,7 @@ import com.google.devtools.build.lib.packages.RuleClassProvider;
import com.google.devtools.build.lib.syntax.BuildFileAST;
import com.google.devtools.build.lib.syntax.Mutability;
import com.google.devtools.build.lib.syntax.Runtime;
+import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
import com.google.devtools.build.lib.syntax.ValidationEnvironment;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -97,6 +98,10 @@ public class ASTFileLookupFunction implements SkyFunction {
if (!fileValue.isFile()) {
return ASTFileLookupValue.forBadFile(fileLabel);
}
+ SkylarkSemanticsOptions skylarkSemantics = PrecomputedValue.SKYLARK_SEMANTICS.get(env);
+ if (skylarkSemantics == null) {
+ return null;
+ }
//
// Both the package and the file exist; load the file and parse it as an AST.
@@ -112,6 +117,7 @@ public class ASTFileLookupFunction implements SkyFunction {
.createSkylarkRuleClassEnvironment(
fileLabel,
mutability,
+ skylarkSemantics,
env.getListener(),
// the two below don't matter for extracting the ValidationEnvironment:
/*astFileContentHashCode=*/ null,
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
index 0b7afce7b6..00da7e78da 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
@@ -50,6 +50,7 @@ import com.google.devtools.build.lib.syntax.Environment.Extension;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.ParserInputSource;
import com.google.devtools.build.lib.syntax.SkylarkImport;
+import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
import com.google.devtools.build.lib.syntax.Statement;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.Preconditions;
@@ -482,6 +483,11 @@ public class PackageFunction implements SkyFunction {
return null;
}
+ SkylarkSemanticsOptions skylarkSemantics = PrecomputedValue.SKYLARK_SEMANTICS.get(env);
+ if (skylarkSemantics == null) {
+ return null;
+ }
+
SkyKey astLookupKey = ASTFileLookupValue.key(preludeLabel);
ASTFileLookupValue astLookupValue = null;
try {
@@ -508,6 +514,7 @@ public class PackageFunction implements SkyFunction {
buildFilePath,
buildFileValue,
defaultVisibility,
+ skylarkSemantics,
preludeStatements,
packageLookupValue.getRoot(),
env);
@@ -1113,6 +1120,7 @@ public class PackageFunction implements SkyFunction {
Path buildFilePath,
@Nullable FileValue buildFileValue,
RuleVisibility defaultVisibility,
+ SkylarkSemanticsOptions skylarkSemantics,
List<Statement> preludeStatements,
Path packageRoot,
Environment env)
@@ -1206,8 +1214,15 @@ public class PackageFunction implements SkyFunction {
SkyframeHybridGlobber skyframeGlobber = new SkyframeHybridGlobber(packageId, packageRoot,
env, legacyGlobber);
Package.Builder pkgBuilder = packageFactory.createPackageFromPreprocessingAst(
- workspaceName, packageId, buildFilePath, astAfterPreprocessing, importResult.importMap,
- importResult.fileDependencies, defaultVisibility, skyframeGlobber);
+ workspaceName,
+ packageId,
+ buildFilePath,
+ astAfterPreprocessing,
+ importResult.importMap,
+ importResult.fileDependencies,
+ defaultVisibility,
+ skylarkSemantics,
+ skyframeGlobber);
Set<SkyKey> globDepsRequested = ImmutableSet.<SkyKey>builder()
.addAll(globDepsRequestedDuringPreprocessing)
.addAll(skyframeGlobber.getGlobDepsRequested())
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
index 0c01e20c64..3e9d31edf3 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
@@ -15,6 +15,7 @@ package com.google.devtools.build.lib.skyframe;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
import com.google.devtools.build.lib.analysis.ConfiguredAspect;
import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
@@ -61,10 +62,12 @@ public class SkylarkAspectFactory implements ConfiguredAspectFactory {
ruleContext.ruleError(e.getMessage());
return null;
}
+ AnalysisEnvironment analysisEnv = ruleContext.getAnalysisEnvironment();
Environment env =
Environment.builder(mutability)
.setGlobals(skylarkAspect.getFuncallEnv().getGlobals())
- .setEventHandler(ruleContext.getAnalysisEnvironment().getEventHandler())
+ .setSemantics(analysisEnv.getSkylarkSemantics())
+ .setEventHandler(analysisEnv.getEventHandler())
.build(); // NB: loading phase functions are not available: this is analysis already,
// so we do *not* setLoadingPhase().
Object aspectSkylarkObject;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java
index 08c6cf5395..e5952f8be2 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java
@@ -41,6 +41,7 @@ import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.LoadStatement;
import com.google.devtools.build.lib.syntax.Mutability;
import com.google.devtools.build.lib.syntax.SkylarkImport;
+import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
import com.google.devtools.build.lib.syntax.Statement;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -119,6 +120,11 @@ public class SkylarkImportLookupFunction implements SkyFunction {
throws InconsistentFilesystemException, SkylarkImportFailedException, InterruptedException {
PathFragment filePath = fileLabel.toPathFragment();
+ SkylarkSemanticsOptions skylarkSemantics = PrecomputedValue.SKYLARK_SEMANTICS.get(env);
+ if (skylarkSemantics == null) {
+ return null;
+ }
+
// Load the AST corresponding to this file.
ASTFileLookupValue astLookupValue;
try {
@@ -210,7 +216,13 @@ public class SkylarkImportLookupFunction implements SkyFunction {
// Skylark UserDefinedFunction-s in that file will share this function definition Environment,
// which will be frozen by the time it is returned by createExtension.
- Extension extension = createExtension(ast, fileLabel, extensionsForImports, env, inWorkspace);
+ Extension extension = createExtension(
+ ast,
+ fileLabel,
+ extensionsForImports,
+ skylarkSemantics,
+ env,
+ inWorkspace);
SkylarkImportLookupValue result =
new SkylarkImportLookupValue(
extension, new SkylarkFileDependency(fileLabel, fileDependencies.build()));
@@ -355,6 +367,7 @@ public class SkylarkImportLookupFunction implements SkyFunction {
BuildFileAST ast,
Label extensionLabel,
Map<String, Extension> importMap,
+ SkylarkSemanticsOptions skylarkSemantics,
Environment env,
boolean inWorkspace)
throws SkylarkImportFailedException, InterruptedException {
@@ -368,7 +381,8 @@ public class SkylarkImportLookupFunction implements SkyFunction {
com.google.devtools.build.lib.syntax.Environment extensionEnv =
ruleClassProvider
.createSkylarkRuleClassEnvironment(
- extensionLabel, mutability, eventHandler, ast.getContentHashCode(), importMap)
+ extensionLabel, mutability, skylarkSemantics,
+ eventHandler, ast.getContentHashCode(), importMap)
.setupOverride("native", packageFactory.getNativeModule(inWorkspace));
execAndExport(ast, extensionLabel, eventHandler, extensionEnv);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
index 9ac47891e3..6550ca2187 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
@@ -27,6 +27,7 @@ import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.util.SpellChecker;
+import com.google.devtools.common.options.Options;
import java.io.Serializable;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -306,6 +307,11 @@ public final class Environment implements Freezable {
private final Frame dynamicFrame;
/**
+ * The semantics options that affect how Skylark code is evaluated.
+ */
+ private final SkylarkSemanticsOptions semantics;
+
+ /**
* An EventHandler for errors and warnings. This is not used in the BUILD language,
* however it might be used in Skylark code called from the BUILD language, so shouldn't be null.
*/
@@ -472,6 +478,7 @@ public final class Environment implements Freezable {
private Environment(
Frame globalFrame,
Frame dynamicFrame,
+ SkylarkSemanticsOptions semantics,
EventHandler eventHandler,
Map<String, Extension> importedExtensions,
@Nullable String fileContentHashCode,
@@ -481,6 +488,7 @@ public final class Environment implements Freezable {
this.dynamicFrame = Preconditions.checkNotNull(dynamicFrame);
Preconditions.checkArgument(globalFrame.mutability().isMutable());
Preconditions.checkArgument(dynamicFrame.mutability().isMutable());
+ this.semantics = semantics;
this.eventHandler = eventHandler;
this.importedExtensions = importedExtensions;
this.phase = phase;
@@ -496,6 +504,7 @@ public final class Environment implements Freezable {
private final Mutability mutability;
private Phase phase = Phase.ANALYSIS;
@Nullable private Frame parent;
+ @Nullable private SkylarkSemanticsOptions semantics;
@Nullable private EventHandler eventHandler;
@Nullable private Map<String, Extension> importedExtensions;
@Nullable private String fileContentHashCode;
@@ -527,6 +536,11 @@ public final class Environment implements Freezable {
return this;
}
+ public Builder setSemantics(SkylarkSemanticsOptions semantics) {
+ this.semantics = semantics;
+ return this;
+ }
+
/** Sets an EventHandler for errors and warnings. */
public Builder setEventHandler(EventHandler eventHandler) {
Preconditions.checkState(this.eventHandler == null);
@@ -555,12 +569,16 @@ public final class Environment implements Freezable {
}
Frame globalFrame = new Frame(mutability, parent);
Frame dynamicFrame = new Frame(mutability, null);
+ if (semantics == null) {
+ semantics = Options.getDefaults(SkylarkSemanticsOptions.class);
+ }
if (importedExtensions == null) {
importedExtensions = ImmutableMap.of();
}
return new Environment(
globalFrame,
dynamicFrame,
+ semantics,
eventHandler,
importedExtensions,
fileContentHashCode,
@@ -723,6 +741,10 @@ public final class Environment implements Freezable {
return knownGlobalVariables != null && knownGlobalVariables.contains(varname);
}
+ public SkylarkSemanticsOptions getSemantics() {
+ return semantics;
+ }
+
public void handleEvent(Event event) {
eventHandler.handle(event);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
index b3f1e6b758..d84fbc4bfb 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
@@ -2080,6 +2080,12 @@ public class MethodLibrary {
public String apply(Object input) {
return Printer.str(input);
}}));
+ // As part of the integration test "skylark_flag_test.sh", if the
+ // "--internal_skylark_flag_test_canary" flag is enabled, append an extra marker string to the
+ // output.
+ if (env.getSemantics().skylarkFlagTestCanary) {
+ msg += "<== skylark flag test ==>";
+ }
env.handleEvent(Event.warn(loc, msg));
return Runtime.NONE;
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java
index 6eb95ff727..4d04ebddde 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java
@@ -40,6 +40,7 @@ public class SkylarkCallbackFunction {
throws EvalException, InterruptedException {
try (Mutability mutability = Mutability.create("callback %s", callback)) {
Environment env = Environment.builder(mutability)
+ .setSemantics(funcallEnv.getSemantics())
.setEventHandler(funcallEnv.getEventHandler())
.setGlobals(funcallEnv.getGlobals())
.build();
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemanticsOptions.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemanticsOptions.java
index 32a15fc0ae..eb1fd0de31 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemanticsOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemanticsOptions.java
@@ -14,7 +14,9 @@
package com.google.devtools.build.lib.syntax;
+import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;
+import com.google.devtools.common.options.OptionsParser.OptionUsageRestrictions;
import com.google.devtools.common.options.UsesOnlyCoreTypes;
import java.io.Serializable;
@@ -33,5 +35,11 @@ import java.io.Serializable;
*/
@UsesOnlyCoreTypes
public class SkylarkSemanticsOptions extends OptionsBase implements Serializable {
-
+ // Used in an integration test to confirm that flags are visible to the interpreter.
+ @Option(
+ name = "internal_skylark_flag_test_canary",
+ defaultValue = "false",
+ optionUsageRestrictions = OptionUsageRestrictions.UNDOCUMENTED
+ )
+ public boolean skylarkFlagTestCanary;
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
index add8601855..6e76520a75 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
@@ -175,6 +175,7 @@ public class SkylarkSignatureProcessor {
return Runtime.NONE;
} else {
try (Mutability mutability = Mutability.create("initialization")) {
+ // Note that this Skylark environment ignores command line flags.
Environment env =
Environment.builder(mutability)
.setGlobals(Environment.CONSTANTS_ONLY)
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java
index eb25ec3318..c93cdb814d 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java
@@ -46,6 +46,7 @@ import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollectio
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
+import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -157,6 +158,11 @@ public final class AnalysisTestUtil {
}
@Override
+ public SkylarkSemanticsOptions getSkylarkSemantics() throws InterruptedException {
+ return original.getSkylarkSemantics();
+ }
+
+ @Override
public Artifact getStableWorkspaceStatusArtifact() throws InterruptedException {
return original.getStableWorkspaceStatusArtifact();
}
@@ -339,6 +345,11 @@ public final class AnalysisTestUtil {
}
@Override
+ public SkylarkSemanticsOptions getSkylarkSemantics() throws InterruptedException {
+ return null;
+ }
+
+ @Override
public Artifact getFilesetArtifact(PathFragment rootRelativePath, Root root) {
return null;
}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
index 4379623d2a..a41b3b6c20 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
@@ -1704,6 +1704,11 @@ public abstract class BuildViewTestCase extends FoundationTestCase {
}
@Override
+ public SkylarkSemanticsOptions getSkylarkSemantics() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public Artifact getFilesetArtifact(PathFragment rootRelativePath, Root root) {
throw new UnsupportedOperationException();
}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/PackageFactoryApparatus.java b/src/test/java/com/google/devtools/build/lib/packages/util/PackageFactoryApparatus.java
index 4211ce4ef3..6a4b12cd59 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/util/PackageFactoryApparatus.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/util/PackageFactoryApparatus.java
@@ -32,10 +32,12 @@ import com.google.devtools.build.lib.packages.RuleClassProvider;
import com.google.devtools.build.lib.syntax.BuildFileAST;
import com.google.devtools.build.lib.syntax.Environment.Extension;
import com.google.devtools.build.lib.syntax.ParserInputSource;
+import com.google.devtools.build.lib.syntax.SkylarkSemanticsOptions;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.testutil.TestUtils;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.common.options.Options;
import java.io.IOException;
/**
@@ -136,6 +138,7 @@ public class PackageFactoryApparatus {
globber,
ImmutableList.<Event>of(),
ConstantRuleVisibility.PUBLIC,
+ Options.getDefaults(SkylarkSemanticsOptions.class),
false,
new MakeEnvironment.Builder(),
ImmutableMap.<String, Extension>of(),
diff --git a/src/test/shell/integration/BUILD b/src/test/shell/integration/BUILD
index ad448df623..cdce926014 100644
--- a/src/test/shell/integration/BUILD
+++ b/src/test/shell/integration/BUILD
@@ -181,6 +181,13 @@ sh_test(
)
sh_test(
+ name = "skylark_flag_test",
+ size = "small",
+ srcs = ["skylark_flag_test.sh"],
+ data = [":test-deps"],
+)
+
+sh_test(
name = "ui_test",
size = "medium",
srcs = ["ui_test.sh"],
diff --git a/src/test/shell/integration/skylark_flag_test.sh b/src/test/shell/integration/skylark_flag_test.sh
new file mode 100755
index 0000000000..df12d71259
--- /dev/null
+++ b/src/test/shell/integration/skylark_flag_test.sh
@@ -0,0 +1,104 @@
+#!/bin/bash
+#
+# Copyright 2017 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.
+
+# Tests that the Skylark interpreter is reading flags passed in on the command
+# line, in several different evaluation contexts.
+#
+# The --internal_skylark_flag_test_canary flag is built into
+# SkylarkSemanticsOptions specifically for this test suite.
+
+# Load the test setup defined in the parent directory
+CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+source "${CURRENT_DIR}/../integration_test_setup.sh" \
+ || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
+
+MARKER="<== skylark flag test ==>"
+
+function setup_package() {
+ mkdir -p test
+ cat > test/BUILD <<'EOF'
+load(":test.bzl", "macro")
+
+print("In BUILD: ")
+
+macro()
+EOF
+ cat >test/test.bzl <<'EOF'
+print("In bzl: ")
+
+def _rule_impl(ctx):
+ print("In rule: ")
+
+some_rule = rule(
+ implementation = _rule_impl,
+)
+
+def _aspect_impl(target, ctx):
+ print("In aspect: ")
+ return []
+
+some_aspect = aspect(
+ implementation = _aspect_impl,
+)
+
+def macro():
+ print("In macro: ")
+ some_rule(name="some_target")
+EOF
+}
+
+function test_sanity() {
+ # Control test: Make sure the print strings appear, and the marker string
+ # doesn't appear, when we don't pass the flag.
+ setup_package
+ bazel build //test:some_target --aspects test/test.bzl%some_aspect \
+ &>"$TEST_log" || fail "bazel build failed";
+ fail_msg="Marker string '$MARKER' was seen even though "
+ fail_msg+="--internal_skylark_flag_test_canary wasn't passed"
+ expect_not_log "$MARKER" "$fail_msg"
+ expect_log "In BUILD: " "Did not find BUILD print output"
+ expect_log "In bzl: " "Did not find .bzl print output"
+ expect_log "In macro: " "Did not find macro print output"
+ expect_log "In rule: " "Did not find rule print output"
+ # TODO(brandjon): If we add computed default functions as per below, add a
+ # sanity check for it here too.
+ expect_log "In aspect: " "Did not find aspect print output"
+}
+
+function test_skylark_flags() {
+ # Check that the marker string appears when we pass the flag.
+ setup_package
+ bazel build //test:some_target --aspects test/test.bzl%some_aspect \
+ --internal_skylark_flag_test_canary \
+ &>"$TEST_log" || fail "bazel build failed";
+ expect_log "In BUILD: $MARKER" \
+ "Skylark flags are not propagating to BUILD file evaluation"
+ expect_log "In bzl: $MARKER" \
+ "Skylark flags are not propagating to .bzl file evaluation"
+ expect_log "In macro: $MARKER" \
+ "Skylark flags are not propagating to macro evaluation"
+ expect_log "In rule: $MARKER" \
+ "Skylark flags are not propagating to rule implementation function evaluation"
+ # TODO(brandjon): Once we're no long dropping print() output in computed
+ # default functions, also test that we're propagating flags there.
+ # Alternatively, this could be tested by having conditional code that crashes
+ # while evaluating the Skylark function iff the flag is set.
+ expect_log "In aspect: $MARKER" \
+ "Skylark flags are not propagating to aspect implementation function evaluation"
+}
+
+
+run_suite "skylark_flag_test"