Introduce --incompatible_no_transitive_loads
With flag set, loaded symbols are not automatically re-exported.
#5636
RELNOTES: None.
PiperOrigin-RevId: 214776940
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
index 4236b12..07ec878 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
@@ -319,6 +319,20 @@
public boolean incompatibleNoSupportToolsInActionInputs;
@Option(
+ name = "incompatible_no_transitive_loads",
+ defaultValue = "false",
+ documentationCategory = OptionDocumentationCategory.SKYLARK_SEMANTICS,
+ effectTags = {OptionEffectTag.BUILD_FILE_SEMANTICS},
+ metadataTags = {
+ OptionMetadataTag.INCOMPATIBLE_CHANGE,
+ OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES
+ },
+ help =
+ "If set to true, only symbols explicitly defined in the file can be loaded; "
+ + "symbols introduced by load are not implicitly re-exported.")
+ public boolean incompatibleNoTransitiveLoads;
+
+ @Option(
name = "incompatible_package_name_is_a_function",
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.SKYLARK_SEMANTICS,
@@ -451,6 +465,7 @@
.incompatibleGenerateJavaCommonSourceJar(incompatibleGenerateJavaCommonSourceJar)
.incompatibleNewActionsApi(incompatibleNewActionsApi)
.incompatibleNoSupportToolsInActionInputs(incompatibleNoSupportToolsInActionInputs)
+ .incompatibleNoTransitiveLoads(incompatibleNoTransitiveLoads)
.incompatiblePackageNameIsAFunction(incompatiblePackageNameIsAFunction)
.incompatibleRangeType(incompatibleRangeType)
.incompatibleRemoveNativeGitRepository(incompatibleRemoveNativeGitRepository)
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 3a4f0c9..8e01e89 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
@@ -36,6 +36,7 @@
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -271,12 +272,16 @@
/** Bindings are maintained in order of creation. */
private final LinkedHashMap<String, Object> bindings;
+ /** Set of bindings that are exported (can be loaded from other modules). */
+ private final HashSet<String> exportedBindings;
+
/** Constructs an uninitialized instance; caller must call {@link #initialize} before use. */
public GlobalFrame() {
this.mutability = null;
this.universe = null;
this.label = null;
this.bindings = new LinkedHashMap<>();
+ this.exportedBindings = new HashSet<>();
}
public GlobalFrame(
@@ -298,6 +303,7 @@
if (bindings != null) {
this.bindings.putAll(bindings);
}
+ this.exportedBindings = new HashSet<>();
}
public GlobalFrame(Mutability mutability) {
@@ -399,6 +405,21 @@
return Collections.unmodifiableMap(bindings);
}
+ /**
+ * Returns a map of bindings that are exported (i.e. symbols declared using `=` and
+ * `def`, but not `load`).
+ */
+ public Map<String, Object> getExportedBindings() {
+ checkInitialized();
+ ImmutableMap.Builder<String, Object> result = new ImmutableMap.Builder<>();
+ for (Map.Entry<String, Object> entry : bindings.entrySet()) {
+ if (exportedBindings.contains(entry.getKey())) {
+ result.put(entry);
+ }
+ }
+ return result.build();
+ }
+
@Override
public Map<String, Object> getTransitiveBindings() {
checkInitialized();
@@ -523,7 +544,14 @@
* and that {@code Environment}'s transitive hash code.
*/
public Extension(Environment env) {
- this(ImmutableMap.copyOf(env.globalFrame.bindings), env.getTransitiveContentHashCode());
+ // Legacy behavior: all symbols from the global Frame are exported (including symbols
+ // introduced by load).
+ this(
+ ImmutableMap.copyOf(
+ env.getSemantics().incompatibleNoTransitiveLoads()
+ ? env.globalFrame.getExportedBindings()
+ : env.globalFrame.getBindings()),
+ env.getTransitiveContentHashCode());
}
public String getTransitiveContentHashCode() {
@@ -981,6 +1009,15 @@
}
}
+ /** Modifies a binding in the current Frame. If it is the module Frame, also export it. */
+ public Environment updateAndExport(String varname, Object value) throws EvalException {
+ update(varname, value);
+ if (isGlobal()) {
+ globalFrame.exportedBindings.add(varname);
+ }
+ return this;
+ }
+
/**
* Modifies a binding in the current Frame of this Environment, as would an {@link
* AssignmentStatement}. Does not try to modify an inherited binding. This will shadow any
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Eval.java b/src/main/java/com/google/devtools/build/lib/syntax/Eval.java
index a91ffae..d7e30dd 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Eval.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Eval.java
@@ -121,7 +121,7 @@
throw new EvalException(node.getLocation(), "Keyword-only argument is forbidden.");
}
- env.update(
+ env.updateAndExport(
node.getIdentifier().getName(),
new UserDefinedFunction(
node.getIdentifier().getName(),
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/LValue.java b/src/main/java/com/google/devtools/build/lib/syntax/LValue.java
index 223e192..c37d032 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/LValue.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/LValue.java
@@ -89,7 +89,7 @@
/** Binds a variable to the given value in the environment. */
private static void assignIdentifier(Identifier ident, Object value, Environment env)
throws EvalException {
- env.update(ident.getName(), value);
+ env.updateAndExport(ident.getName(), value);
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
index 686c21e..2d606cc 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
@@ -125,6 +125,8 @@
public abstract boolean incompatibleNoSupportToolsInActionInputs();
+ public abstract boolean incompatibleNoTransitiveLoads();
+
public abstract boolean incompatiblePackageNameIsAFunction();
public abstract boolean incompatibleRangeType();
@@ -175,6 +177,7 @@
.incompatibleGenerateJavaCommonSourceJar(false)
.incompatibleNewActionsApi(false)
.incompatibleNoSupportToolsInActionInputs(false)
+ .incompatibleNoTransitiveLoads(false)
.incompatiblePackageNameIsAFunction(false)
.incompatibleRangeType(false)
.incompatibleRemoveNativeGitRepository(false)
@@ -228,6 +231,8 @@
public abstract Builder incompatibleNoSupportToolsInActionInputs(boolean value);
+ public abstract Builder incompatibleNoTransitiveLoads(boolean value);
+
public abstract Builder incompatiblePackageNameIsAFunction(boolean value);
public abstract Builder incompatibleRangeType(boolean value);