diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java index 7c00f8201975fa..dc48b15b520077 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java @@ -611,7 +611,7 @@ private JavaCompilationHelper initAttributes( ruleContext, semantics, javaCommon.getJavacOpts(), attributes, additionalArtifacts); helper.addLibrariesToAttributes(javaCommon.targetsTreatedAsDeps(ClasspathType.COMPILE_ONLY)); - attributes.setTargetLabel(ruleContext.getLabel()); + attributes.setTargetLabel(JavaCommon.getLabelForTooling(ruleContext)); ruleContext.checkSrcsSamePackage(true); return helper; diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java index 47976dff3c5652..75610fd302433d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java @@ -37,6 +37,8 @@ import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.cmdline.LabelSyntaxException; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; @@ -199,6 +201,26 @@ public static ImmutableList getConstraints(RuleContext ruleContext) { : ImmutableList.of(); } + /** + * Use this method rather than {@link RuleContext#getLabel()} when generating a label meant to be + * consumed by BUILD file tooling such as buildozer. + * + * @param ruleContext the rule context + * @return the label of the current rule if it hasn't been generated by a macro, or a label for + * the macro (valid on the level of parsed, but unevaluated BUILD files) if it has. + */ + public static Label getLabelForTooling(RuleContext ruleContext) { + String generatorName = ruleContext.attributes().get("generator_name", Type.STRING); + if (generatorName != null && !ruleContext.getLabel().getName().equals(generatorName)) { + try { + return Label.create(ruleContext.getLabel().getPackageIdentifier(), generatorName); + } catch (LabelSyntaxException unused) { + // Tooling label creation is best-effort, fall back to the rule label. + } + } + return ruleContext.getLabel(); + } + public void setClassPathFragment(ClasspathConfiguredFragment classpathFragment) { this.classpathFragment = classpathFragment; } @@ -584,7 +606,7 @@ public JavaTargetAttributes.Builder initCommon( addPlugins(javaTargetAttributes); - javaTargetAttributes.setTargetLabel(ruleContext.getLabel()); + javaTargetAttributes.setTargetLabel(getLabelForTooling(ruleContext)); return javaTargetAttributes; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java index c241c8f75d36fa..187029d81600c4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java @@ -313,8 +313,7 @@ && getJavaConfiguration().experimentalEnableJspecify() JavaClasspathMode classpathMode = getJavaConfiguration().getReduceJavaClasspath(); builder.setClasspathMode(classpathMode); builder.setAdditionalInputs(additionalInputsForDatabinding); - Label label = ruleContext.getLabel(); - builder.setTargetLabel(label); + builder.setTargetLabel(JavaCommon.getLabelForTooling(ruleContext)); Artifact coverageArtifact = maybeCreateCoverageArtifact(outputs.output()); builder.setCoverageArtifact(coverageArtifact); BootClassPathInfo bootClassPathInfo = getBootclasspathOrDefault(); @@ -366,7 +365,8 @@ && getJavaConfiguration().experimentalEnableJspecify() builder.setFixDepsTool(getJavaConfiguration().getFixDepsTool()); builder.setCompileTimeDependencyArtifacts(attributes.getCompileTimeDependencyArtifacts()); builder.setTargetLabel( - attributes.getTargetLabel() == null ? label : attributes.getTargetLabel()); + attributes.getTargetLabel() == null ? JavaCommon.getLabelForTooling(ruleContext) + : attributes.getTargetLabel()); builder.setInjectingRuleKind(attributes.getInjectingRuleKind()); if (coverageArtifact != null) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java index 41bba1b73f433d..7647ac1deedd6d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java @@ -272,7 +272,7 @@ public JavaCompilationArtifacts build( addDepsToAttributes(attributes); attributes.addClassPathResources(classpathResources); attributes.setStrictJavaDeps(strictDepsMode); - attributes.setTargetLabel(ruleContext.getLabel()); + attributes.setTargetLabel(JavaCommon.getLabelForTooling(ruleContext)); attributes.setInjectingRuleKind(injectingRuleKind); attributes.setSourcePath(sourcePathEntries); JavaCommon.addPlugins(attributes, plugins); diff --git a/src/test/shell/bazel/bazel_java_test.sh b/src/test/shell/bazel/bazel_java_test.sh index a30ba12f961930..5efeb3f4712396 100755 --- a/src/test/shell/bazel/bazel_java_test.sh +++ b/src/test/shell/bazel/bazel_java_test.sh @@ -1956,4 +1956,83 @@ EOF } +function test_macro_strict_deps_warning() { + mkdir -p a b x + + cat > a/defs.bzl <<'EOF' +def my_java_binary(name, **kwargs): + bin_name = name + "_bin" + native.java_binary(name = bin_name, **kwargs) + native.genrule( + name = name, + srcs = [":" + bin_name + "_deploy.jar"], + outs = [name], + cmd = "cp $< > $@", + ) +EOF + cat > a/A.java <<'EOF' +package a; + +import x.X; + +public class A { + public static void main(String args[]) { + X.print(); + } +} +EOF + cat > a/BUILD <<'EOF' +load(":defs.bzl", "my_java_binary") +my_java_binary( + name = "a", + main_class = "a.A", + srcs = ["A.java"], + deps = ["//b"], +) +EOF + + + cat > b/B.java <<'EOF' +package b; + +public class B { + public static void print() { + System.out.println("B"); + } +} +EOF + cat > b/BUILD <<'EOF' +java_library( + name = "b", + srcs = ["B.java"], + deps = ["//x"], + visibility = ["//visibility:public"], +) +EOF + + cat > x/X.java <<'EOF' +package x; + +public class X { + public static void print() { + System.out.println("X"); + } +} +EOF + cat > x/BUILD <<'EOF' +java_library( + name = "x", + srcs = ["X.java"], + visibility = ["//visibility:public"], +) +EOF + + bazel build //a >& $TEST_log && fail "Building //a should error out" + expect_log "** Please add the following dependencies:" + expect_log "//x to //a " + expect_log "'add deps //x' //a " + expect_not_log "to //a:a_bin" +} + + run_suite "Java integration tests"