diff options
Diffstat (limited to 'src')
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" |