Skip to content

Commit 98f8b2e

Browse files
authored
[8.2.0] Set macro symbol's exported location as MacroFunction's callable location for Starlark stack (#25802)
This ensures Starlark instantiation stack for rule targets defined in a symbolic macro shows both the macro's location and symbol. Requires changing StarlarkThread to track the location of where symbols are exported. As follow-up, we should do the same for rules, providers, and aspects. PiperOrigin-RevId: 745731053 Change-Id: I6732a9762fbc932d823a70d7753a2b6edc140df6 Commit a3e26ed
1 parent 22c782d commit 98f8b2e

File tree

17 files changed

+72
-22
lines changed

17 files changed

+72
-22
lines changed

src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkRuleClassFunctions.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,9 @@ public static final class MacroFunction implements StarlarkExportable, MacroFunc
13981398
// Initially null, then non-null once exported.
13991399
@Nullable private MacroClass macroClass = null;
14001400

1401+
// Initially null, then non-null once exported.
1402+
@Nullable private Location exportedLocation = null;
1403+
14011404
/** A token used for equality that may be mutated by {@link #export}. */
14021405
private Symbol<BzlLoadValue.Key> identityToken;
14031406

@@ -1417,6 +1420,11 @@ public String getName() {
14171420
return macroClass != null ? macroClass.getName() : "unexported macro";
14181421
}
14191422

1423+
@Override
1424+
public Location getLocation() {
1425+
return exportedLocation != null ? exportedLocation : Location.BUILTIN;
1426+
}
1427+
14201428
/**
14211429
* Returns the value of the doc parameter passed to {@code macro()} in Starlark, or an empty
14221430
* Optional if a doc string was not provided.
@@ -1495,7 +1503,8 @@ public Object call(StarlarkThread thread, Tuple args, Dict<String, Object> kwarg
14951503

14961504
/** Export a MacroFunction from a Starlark file with a given name. */
14971505
@Override
1498-
public void export(EventHandler handler, Label starlarkLabel, String exportedName) {
1506+
public void export(
1507+
EventHandler handler, Label starlarkLabel, String exportedName, Location exportedLocation) {
14991508
checkState(builder != null && macroClass == null);
15001509
builder.setName(exportedName);
15011510
builder.setDefiningBzlLabel(starlarkLabel);
@@ -1508,6 +1517,7 @@ public void export(EventHandler handler, Label starlarkLabel, String exportedNam
15081517
starlarkLabel,
15091518
exportedName);
15101519
this.identityToken = identityToken.exportAs(exportedName);
1520+
this.exportedLocation = exportedLocation;
15111521
}
15121522

15131523
/**
@@ -1755,8 +1765,13 @@ private static void validateRulePropagatedAspects(RuleClass ruleClass) throws Ev
17551765
}
17561766

17571767
/** Export a RuleFunction from a Starlark file with a given name. */
1768+
// TODO(bazel-team): use exportedLocation as the callable symbol's location.
17581769
@Override
1759-
public void export(EventHandler handler, Label starlarkLabel, String ruleClassName) {
1770+
public void export(
1771+
EventHandler handler,
1772+
Label starlarkLabel,
1773+
String ruleClassName,
1774+
Location exportedLocation) {
17601775
checkState(ruleClass == null && builder != null);
17611776
var symbolToken = (Symbol<?>) identityToken; // always a Symbol before export
17621777
this.identityToken =

src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkSubrule.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import net.starlark.java.eval.StarlarkSemantics;
6161
import net.starlark.java.eval.StarlarkThread;
6262
import net.starlark.java.eval.Tuple;
63+
import net.starlark.java.syntax.Location;
6364

6465
/**
6566
* Represents a subrule which can be invoked in a Starlark rule's implementation function.
@@ -247,8 +248,10 @@ public boolean isExported() {
247248
return this.extensionLabel != null && this.exportedName != null;
248249
}
249250

251+
// TODO(bazel-team): use exportedLocation as the callable symbol's location.
250252
@Override
251-
public void export(EventHandler handler, Label extensionLabel, String exportedName) {
253+
public void export(
254+
EventHandler handler, Label extensionLabel, String exportedName, Location exportedLocation) {
252255
Preconditions.checkState(!isExported());
253256
this.extensionLabel = extensionLabel;
254257
this.exportedName = exportedName;

src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,10 +554,10 @@ private static ModuleThreadContext execModuleFile(
554554
thread.setPrintHandler(Event.makeDebugPrintHandler(eventHandler));
555555
}
556556
thread.setPostAssignHook(
557-
(name, value) -> {
557+
(name, nameStartLocation, value) -> {
558558
if (value instanceof StarlarkExportable exportable) {
559559
if (!exportable.isExported()) {
560-
exportable.export(eventHandler, null, name);
560+
exportable.export(eventHandler, null, name, nameStartLocation);
561561
}
562562
}
563563
});

src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import net.starlark.java.eval.Structure;
5353
import net.starlark.java.eval.Tuple;
5454
import net.starlark.java.syntax.Identifier;
55+
import net.starlark.java.syntax.Location;
5556

5657
/** A collection of global Starlark build API functions that apply to MODULE.bazel files. */
5758
@GlobalMethods(environment = Environment.MODULE)
@@ -624,7 +625,8 @@ public boolean isExported() {
624625
}
625626

626627
@Override
627-
public void export(EventHandler handler, Label bzlFileLabel, String name) {
628+
public void export(
629+
EventHandler handler, Label bzlFileLabel, String name, Location exportedLocation) {
628630
proxyBuilder.setProxyName(name);
629631
}
630632
}

src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkRepositoryModule.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import net.starlark.java.eval.StarlarkCallable;
5757
import net.starlark.java.eval.StarlarkThread;
5858
import net.starlark.java.eval.Tuple;
59+
import net.starlark.java.syntax.Location;
5960

6061
/**
6162
* The Starlark module containing the definition of {@code repository_rule} function to define a
@@ -138,7 +139,7 @@ public StarlarkCallable repositoryRule(
138139
name = "repository_rule",
139140
category = DocCategory.BUILTIN,
140141
doc =
141-
"""
142+
"""
142143
A callable value that may be invoked during evaluation of the WORKSPACE file or within \
143144
the implementation function of a module extension to instantiate and return a repository \
144145
rule. Created by \
@@ -191,8 +192,13 @@ public boolean isImmutable() {
191192
return true;
192193
}
193194

195+
// TODO(bazel-team): use exportedLocation as the callable symbol's location.
194196
@Override
195-
public void export(EventHandler handler, Label extensionLabel, String exportedName) {
197+
public void export(
198+
EventHandler handler,
199+
Label extensionLabel,
200+
String exportedName,
201+
Location exportedLocation) {
196202
this.extensionLabel = extensionLabel;
197203
this.exportedName = exportedName;
198204
}

src/main/java/com/google/devtools/build/lib/packages/StarlarkDefinedAspect.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import net.starlark.java.eval.StarlarkCallable;
4343
import net.starlark.java.eval.StarlarkInt;
4444
import net.starlark.java.eval.SymbolGenerator.Symbol;
45+
import net.starlark.java.syntax.Location;
4546

4647
/** A Starlark value that is a result of an 'aspect(..)' function call. */
4748
public final class StarlarkDefinedAspect implements StarlarkExportable, StarlarkAspect {
@@ -168,8 +169,10 @@ public ImmutableSet<String> getParamAttributes() {
168169
return paramAttributes;
169170
}
170171

172+
// TODO(bazel-team): use exportedLocation as the callable symbol's location.
171173
@Override
172-
public void export(EventHandler handler, Label extensionLabel, String name) {
174+
public void export(
175+
EventHandler handler, Label extensionLabel, String name, Location exportedLocation) {
173176
Preconditions.checkArgument(!isExported());
174177
@SuppressWarnings("unchecked")
175178
var identityToken = (Symbol<BzlLoadValue.Key>) aspectClassOrIdentityToken;

src/main/java/com/google/devtools/build/lib/packages/StarlarkExportable.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.google.devtools.build.lib.cmdline.Label;
1818
import com.google.devtools.build.lib.events.EventHandler;
1919
import net.starlark.java.eval.StarlarkValue;
20+
import net.starlark.java.syntax.Location;
2021

2122
/**
2223
* {@link StarlarkValue}s that need special handling when they are exported from an extension file.
@@ -31,7 +32,8 @@ public interface StarlarkExportable extends StarlarkValue {
3132

3233
/**
3334
* Notify the value that it is exported from {@code extensionLabel} extension with name {@code
34-
* exportedName}.
35+
* exportedName} at {@code exportedLocation}.
3536
*/
36-
void export(EventHandler handler, Label extensionLabel, String exportedName);
37+
void export(
38+
EventHandler handler, Label extensionLabel, String exportedName, Location exportedLocation);
3739
}

src/main/java/com/google/devtools/build/lib/packages/StarlarkProvider.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,10 @@ public String getErrorMessageForUnknownField(String name) {
394394
"'%s' value has no field or method '%s'", isExported() ? getName() : "struct", name);
395395
}
396396

397+
// TODO(bazel-team): use exportedLocation as the callable symbol's location.
397398
@Override
398-
public void export(EventHandler handler, Label extensionLabel, String exportedName) {
399+
public void export(
400+
EventHandler handler, Label extensionLabel, String exportedName, Location exportedLocation) {
399401
Preconditions.checkState(!isExported());
400402
SymbolGenerator.Symbol<?> identifier = (SymbolGenerator.Symbol<?>) keyOrIdentityToken;
401403
if (identifier.getOwner() instanceof BzlLoadValue.Key bzlKey) {

src/main/java/com/google/devtools/build/lib/packages/TargetDefinitionContext.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ public T intern(T sample) {
216216
pkg, buildFileLabel, Location.fromFile(metadata.buildFilename().asPath().toString())));
217217
}
218218

219+
public Metadata getMetadata() {
220+
return metadata;
221+
}
222+
219223
SymbolGenerator<?> getSymbolGenerator() {
220224
return symbolGenerator;
221225
}

src/main/java/com/google/devtools/build/lib/rules/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ java_library(
9898
"//src/main/java/com/google/devtools/build/lib/util",
9999
"//src/main/java/com/google/devtools/build/lib/vfs",
100100
"//src/main/java/net/starlark/java/eval",
101+
"//src/main/java/net/starlark/java/syntax",
101102
"//src/main/protobuf:test_status_java_proto",
102103
"//third_party:guava",
103104
"//third_party:jsr305",

src/main/java/com/google/devtools/build/lib/rules/test/StarlarkTestingModule.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import net.starlark.java.eval.StarlarkList;
3636
import net.starlark.java.eval.StarlarkThread;
3737
import net.starlark.java.eval.Tuple;
38+
import net.starlark.java.syntax.Location;
3839

3940
/** A class that exposes testing infrastructure to Starlark. */
4041
public class StarlarkTestingModule implements TestingModuleApi {
@@ -158,7 +159,11 @@ public void analysisTest(
158159
// evaluation in BzlLoadFunction#execAndExport.
159160
StoredEventHandler handler = new StoredEventHandler();
160161
starlarkRuleFunction.export(
161-
handler, pkgBuilder.getBuildFileLabel(), name + "_test"); // export in BUILD thread
162+
handler,
163+
pkgBuilder.getBuildFileLabel(),
164+
name + "_test",
165+
Location.fromFile(
166+
pkgBuilder.getMetadata().buildFilename().toString())); // export in BUILD thread
162167
if (handler.hasErrors()) {
163168
StringBuilder errors =
164169
handler.getEvents().stream()

src/main/java/com/google/devtools/build/lib/skyframe/BzlLoadFunction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,10 +1462,10 @@ public static void execAndExport(
14621462
// and "export" any newly assigned exportable globals.
14631463
// TODO(adonovan): change the semantics; see b/65374671.
14641464
thread.setPostAssignHook(
1465-
(name, value) -> {
1465+
(name, nameStartLocation, value) -> {
14661466
if (value instanceof StarlarkExportable exp) {
14671467
if (!exp.isExported()) {
1468-
exp.export(handler, label, name);
1468+
exp.export(handler, label, name, nameStartLocation);
14691469
}
14701470
}
14711471
});

src/main/java/net/starlark/java/eval/Eval.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ private static TokenKind execStatements(
100100
// identifier when available. This enables an name-based lookup on deserialization.
101101
((StarlarkFunction) value).export(fr.thread, id.getName());
102102
} else {
103-
fr.thread.postAssignHook.assign(id.getName(), value);
103+
fr.thread.postAssignHook.assign(id.getName(), id.getStartLocation(), value);
104104
}
105105
}
106106
} else if (stmt instanceof DefStatement) {

src/main/java/net/starlark/java/eval/StarlarkThread.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ public void setPostAssignHook(PostAssignHook postAssignHook) {
475475
/** A hook for notifications of assignments at top level. */
476476
@FunctionalInterface
477477
public interface PostAssignHook {
478-
void assign(String name, Object value);
478+
void assign(String name, Location nameStartLocation, Object value);
479479
}
480480

481481
public StarlarkSemantics getSemantics() {

src/test/java/com/google/devtools/build/lib/analysis/SymbolicMacroTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,7 +2020,8 @@ def _impl(name, visibility, **kwargs):
20202020
assertThat(foo.reconstructParentCallStack())
20212021
.containsExactly(
20222022
StarlarkThread.callStackEntry(StarlarkThread.TOP_LEVEL, foo.getBuildFileLocation()),
2023-
StarlarkThread.callStackEntry("my_macro", Location.BUILTIN))
2023+
StarlarkThread.callStackEntry(
2024+
"my_macro", Location.fromFileLineColumn("/workspace/pkg/my_macro.bzl", 7, 1)))
20242025
.inOrder();
20252026

20262027
Rule fooLib = pkg.getRule("foo_lib");
@@ -2108,7 +2109,8 @@ def outer_legacy_wrapper(name, **kwargs):
21082109
StarlarkThread.callStackEntry(
21092110
"outer_legacy_wrapper",
21102111
Location.fromFileLineColumn("/workspace/pkg/outer.bzl", 9, 16)),
2111-
StarlarkThread.callStackEntry("outer_macro", Location.BUILTIN))
2112+
StarlarkThread.callStackEntry(
2113+
"outer_macro", Location.fromFileLineColumn("/workspace/pkg/outer.bzl", 6, 1)))
21122114
.inOrder();
21132115

21142116
MacroInstance fooInner = getMacroById(pkg, "foo_inner:1");
@@ -2120,7 +2122,8 @@ def outer_legacy_wrapper(name, **kwargs):
21202122
StarlarkThread.callStackEntry(
21212123
"inner_legacy_wrapper",
21222124
Location.fromFileLineColumn("/workspace/pkg/inner.bzl", 7, 16)),
2123-
StarlarkThread.callStackEntry("inner_macro", Location.BUILTIN))
2125+
StarlarkThread.callStackEntry(
2126+
"inner_macro", Location.fromFileLineColumn("/workspace/pkg/inner.bzl", 4, 1)))
21242127
.inOrder();
21252128

21262129
Rule fooLib = pkg.getRule("foo_inner");

src/test/java/com/google/devtools/build/lib/packages/RequiredProvidersTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ private static final class P3 implements TransitiveInfoProvider {}
4747

4848
static {
4949
try {
50-
P_STARLARK.export(ev -> {}, Label.create("foo/bar", "x.bzl"), "p_starlark");
50+
P_STARLARK.export(
51+
ev -> {},
52+
Label.create("foo/bar", "x.bzl"),
53+
"p_starlark",
54+
Location.fromFile("/workspace/foo/bar/x.bzl"));
5155
} catch (LabelSyntaxException e) {
5256
throw new AssertionError(e);
5357
}

src/test/java/net/starlark/java/eval/EvaluationTestCase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ StarlarkThread getStarlarkThread() {
9494
StarlarkThread.create(
9595
mu, semantics, /* contextDescription= */ "", SymbolGenerator.create("test"));
9696
// Sets a post-assign hook to enable global export of StarlarkFunction Symbols.
97-
this.thread.setPostAssignHook((unusedName, unusedValue) -> {});
97+
this.thread.setPostAssignHook((unusedName, unusedLocation, unusedValue) -> {});
9898
}
9999
return this.thread;
100100
}

0 commit comments

Comments
 (0)