aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java
diff options
context:
space:
mode:
authorGravatar Irina Iancu <elenairina@google.com>2017-01-16 09:11:33 +0000
committerGravatar Vladimir Moskva <vladmos@google.com>2017-01-16 13:47:07 +0000
commite9674fb187b5b95136eb93058eab9d48dcfdbeca (patch)
tree450ff9f6a59166a0767a1f39ed60aee3ab3aa52c /src/main/java
parent266bb166293c44cd6fb25d66fc2b2aff328ed69e (diff)
Adding Java compilation to java_lite_proto_library Skylark version.
-- PiperOrigin-RevId: 144608820 MOS_MIGRATED_REVID=144608820
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java136
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoSkylarkCommon.java47
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java18
4 files changed, 202 insertions, 3 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index d89953d1bf..362fd2709b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -52,6 +52,7 @@ import com.google.devtools.build.lib.bazel.rules.java.BazelJavaImportRule;
import com.google.devtools.build.lib.bazel.rules.java.BazelJavaLibraryRule;
import com.google.devtools.build.lib.bazel.rules.java.BazelJavaPluginRule;
import com.google.devtools.build.lib.bazel.rules.java.BazelJavaRuleClasses;
+import com.google.devtools.build.lib.bazel.rules.java.BazelJavaSemantics;
import com.google.devtools.build.lib.bazel.rules.java.BazelJavaTestRule;
import com.google.devtools.build.lib.bazel.rules.java.proto.BazelJavaLiteProtoAspect;
import com.google.devtools.build.lib.bazel.rules.java.proto.BazelJavaLiteProtoLibraryRule;
@@ -550,8 +551,9 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(new BazelAarImportRule());
builder.addSkylarkAccessibleTopLevels("android_common", new AndroidSkylarkCommon());
+ builder.addSkylarkAccessibleTopLevels(
+ "java_common", new JavaSkylarkCommon(BazelJavaSemantics.INSTANCE));
builder.addSkylarkAccessibleTopLevels("java_proto_common", JavaProtoSkylarkCommon.class);
- builder.addSkylarkAccessibleTopLevels("java_common", JavaSkylarkCommon.INSTANCE);
try {
builder.addWorkspaceFilePrefix(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
index 7797ef5658..632dba6da4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
@@ -13,14 +13,33 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.java;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.MiddlemanProvider;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode;
+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;
import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
+import com.google.devtools.build.lib.rules.SkylarkRuleContext;
+import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.syntax.SkylarkList;
+import java.util.LinkedList;
+import java.util.List;
/** A module that contains Skylark utilities for Java support. */
@SkylarkModule(name = "java_common", doc = "Utilities for Java compilation support in Skylark.")
public class JavaSkylarkCommon {
- public static final JavaSkylarkCommon INSTANCE = new JavaSkylarkCommon();
+ private final JavaSemantics javaSemantics;
+
+ public JavaSkylarkCommon(JavaSemantics javaSemantics) {
+ this.javaSemantics = javaSemantics;
+ }
@SkylarkCallable(
name = "provider",
@@ -30,4 +49,119 @@ public class JavaSkylarkCommon {
public SkylarkClassObjectConstructor getJavaProvider() {
return JavaProvider.JAVA_PROVIDER;
}
+
+ @SkylarkCallable(
+ name = "compile",
+ // There is one mandatory positional: the Skylark rule context.
+ mandatoryPositionals = 1,
+ parameters = {
+ @Param(
+ name = "source_jars",
+ positional = false,
+ named = true,
+ type = SkylarkList.class,
+ generic1 = Artifact.class
+ ),
+ @Param(name = "output", positional = false, named = true, type = Artifact.class),
+ @Param(
+ name = "javac_opts",
+ positional = false,
+ named = true,
+ type = SkylarkList.class,
+ generic1 = String.class
+ ),
+ @Param(
+ name = "deps",
+ positional = false,
+ named = true,
+ type = SkylarkList.class,
+ generic1 = JavaProvider.class
+ ),
+ @Param(
+ name = "strict_deps",
+ defaultValue = "OFF",
+ positional = false,
+ named = true,
+ type = String.class
+ ),
+ @Param(
+ name = "java_toolchain",
+ positional = false,
+ named = true,
+ type = ConfiguredTarget.class
+ ),
+ @Param(
+ name = "host_javabase",
+ positional = false,
+ named = true,
+ type = ConfiguredTarget.class
+ ),
+ }
+ )
+ public JavaProvider createJavaCompileAction(
+ SkylarkRuleContext skylarkRuleContext,
+ SkylarkList<Artifact> sourceJars,
+ Artifact outputJar,
+ SkylarkList<String> javacOpts,
+ SkylarkList<JavaProvider> deps,
+ String strictDepsMode,
+ ConfiguredTarget javaToolchain,
+ ConfiguredTarget hostJavabase) {
+ JavaLibraryHelper helper =
+ new JavaLibraryHelper(skylarkRuleContext.getRuleContext())
+ .setOutput(outputJar)
+ .addSourceJars(sourceJars)
+ .setJavacOpts(javacOpts);
+ helper.addAllDeps(getJavaCompilationArgsProviders(deps));
+ helper.setCompilationStrictDepsMode(getStrictDepsMode(strictDepsMode));
+ MiddlemanProvider hostJavabaseProvider = hostJavabase.getProvider(MiddlemanProvider.class);
+
+ NestedSet<Artifact> hostJavabaseArtifacts =
+ hostJavabase == null
+ ? NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER)
+ : hostJavabaseProvider.getMiddlemanArtifact();
+ JavaToolchainProvider javaToolchainProvider =
+ checkNotNull(javaToolchain.getProvider(JavaToolchainProvider.class));
+ JavaCompilationArgs artifacts =
+ helper.build(
+ javaSemantics,
+ javaToolchainProvider,
+ hostJavabaseArtifacts,
+ SkylarkList.createImmutable(ImmutableList.<Artifact>of()));
+ return new JavaProvider(helper.buildCompilationArgsProvider(artifacts, true));
+ }
+
+ @SkylarkCallable(
+ name = "merge",
+ // We have one positional argument: the list of providers to merge.
+ mandatoryPositionals = 1
+ )
+ public static JavaProvider mergeJavaProviders(SkylarkList<JavaProvider> providers) {
+ return new JavaProvider(
+ JavaCompilationArgsProvider.merge(getJavaCompilationArgsProviders(providers)));
+ }
+
+ private static List<JavaCompilationArgsProvider> getJavaCompilationArgsProviders(
+ SkylarkList<JavaProvider> providers) {
+ List<JavaCompilationArgsProvider> javaCompilationArgsProviders = new LinkedList<>();
+ for (JavaProvider provider : providers) {
+ javaCompilationArgsProviders.add(provider.getJavaCompilationArgsProvider());
+ }
+ return javaCompilationArgsProviders;
+ }
+
+ private static StrictDepsMode getStrictDepsMode(String strictDepsMode) {
+ switch (strictDepsMode) {
+ case "OFF":
+ return StrictDepsMode.OFF;
+ case "ERROR":
+ return StrictDepsMode.ERROR;
+ default:
+ throw new IllegalArgumentException(
+ "StrictDepsMode "
+ + strictDepsMode
+ + " not allowed."
+ + " Only OFF and ERROR values are accepted.");
+ }
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoSkylarkCommon.java
index 4135d4029a..5612095478 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoSkylarkCommon.java
@@ -19,7 +19,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.rules.SkylarkRuleContext;
+import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
+import com.google.devtools.build.lib.rules.java.JavaProvider;
+import com.google.devtools.build.lib.rules.java.JavaSemantics;
+import com.google.devtools.build.lib.rules.java.JavaToolchainProvider;
import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder;
import com.google.devtools.build.lib.rules.proto.ProtoLangToolchainProvider;
import com.google.devtools.build.lib.rules.proto.ProtoSupportDataProvider;
@@ -27,6 +32,7 @@ import com.google.devtools.build.lib.rules.proto.SupportData;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import java.util.List;
/**
* A class that exposes Java common methods for proto compilation.
@@ -77,6 +83,47 @@ public class JavaProtoSkylarkCommon {
true /* allowServices */);
}
+ @SkylarkCallable(
+ name = "toolchain_deps",
+ // This function is experimental for now.
+ documented = false,
+ // There's only one mandatory positional,the Skylark context
+ mandatoryPositionals = 1,
+ parameters = {
+ @Param(name = "proto_toolchain_attr", positional = false, named = true, type = String.class)
+ }
+ )
+ public static JavaProvider getRuntimeToolchainProvider(
+ SkylarkRuleContext skylarkRuleContext, String protoToolchainAttr) {
+ TransitiveInfoCollection runtime =
+ getProtoToolchainProvider(skylarkRuleContext, protoToolchainAttr).runtime();
+ return new JavaProvider(runtime.getProvider(JavaCompilationArgsProvider.class));
+ }
+
+ @SkylarkCallable(
+ name = "javac_opts",
+ // This function is experimental for now.
+ documented = false,
+ // There's only one mandatory positional,the Skylark context
+ mandatoryPositionals = 1,
+ parameters = {
+ @Param(name = "java_toolchain_attr", positional = false, named = true, type = String.class)
+ }
+ )
+ // TODO(elenairina): Consider a nicer way of returning this, taking in a JavaToolchainProvider.
+ public static List<String> getJavacOpts(
+ SkylarkRuleContext skylarkRuleContext, String javaToolchainAttr) {
+ ConfiguredTarget javaToolchainConfigTarget =
+ (ConfiguredTarget) checkNotNull(skylarkRuleContext.getAttr().getValue(javaToolchainAttr));
+ JavaToolchainProvider toolchain =
+ checkNotNull(javaToolchainConfigTarget.getProvider(JavaToolchainProvider.class));
+
+ return ImmutableList.<String>builder()
+ .addAll(toolchain.getJavacOptions())
+ .addAll(toolchain.getCompatibleJavacOptions(JavaSemantics.PROTO_JAVACOPTS_KEY))
+ .build();
+ }
+
private static ProtoLangToolchainProvider getProtoToolchainProvider(
SkylarkRuleContext skylarkRuleContext, String protoToolchainAttr) {
ConfiguredTarget javaliteToolchain = (ConfiguredTarget) checkNotNull(
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
index bb859c90c6..387b565e44 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
@@ -157,12 +157,28 @@ public final class EvalUtils {
|| c.equals(String.class) // basic values
|| c.equals(Integer.class)
|| c.equals(Boolean.class)
- || c.isAnnotationPresent(SkylarkModule.class) // registered Skylark class
+ // there is a registered Skylark ancestor class (useful e.g. when using AutoValue)
+ || hasSkylarkAcceptableAncestor(c)
|| ImmutableMap.class.isAssignableFrom(c) // will be converted to SkylarkDict
|| NestedSet.class.isAssignableFrom(c) // will be converted to SkylarkNestedSet
|| c.equals(PathFragment.class); // other known class
}
+ private static boolean hasSkylarkAcceptableAncestor(Class<?> c) {
+ if (c == null) {
+ return false;
+ }
+ if (c.isAnnotationPresent(SkylarkModule.class)) {
+ return true;
+ }
+ for (Class<?> inter : c.getInterfaces()) {
+ if (hasSkylarkAcceptableAncestor(inter)) {
+ return true;
+ }
+ }
+ return hasSkylarkAcceptableAncestor(c.getSuperclass());
+ }
+
// TODO(bazel-team): move the following few type-related functions to SkylarkType
/**
* Return the Skylark-type of {@code c}