diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules')
8 files changed, 218 insertions, 347 deletions
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 263fc49468..0cc409fd74 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 @@ -23,6 +23,7 @@ import com.google.devtools.build.lib.analysis.Runfiles; import com.google.devtools.build.lib.analysis.RunfilesProvider; import com.google.devtools.build.lib.analysis.RunfilesSupport; import com.google.devtools.build.lib.analysis.SkylarkProviderValidationUtil; +import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.events.Location; @@ -60,9 +61,14 @@ import java.util.Map; public final class SkylarkRuleConfiguredTargetBuilder { /** - * Create a Rule Configured Target from the ruleContext and the ruleImplementation. + * Create a Rule Configured Target from the ruleContext and the ruleImplementation. The + * registeredProviderTypes map indicates which keys in structs returned by skylark rules + * should be interpreted as native TransitiveInfoProvider instances of type (map value). */ - public static ConfiguredTarget buildRule(RuleContext ruleContext, BaseFunction ruleImplementation) + public static ConfiguredTarget buildRule( + RuleContext ruleContext, + BaseFunction ruleImplementation, + Map<String, Class<? extends TransitiveInfoProvider>> registeredProviderTypes) throws InterruptedException { String expectFailure = ruleContext.attributes().get("expect_failure", Type.STRING); try (Mutability mutability = Mutability.create("configured target")) { @@ -90,7 +96,8 @@ public final class SkylarkRuleConfiguredTargetBuilder { ruleContext.ruleError("Expected failure not found: " + expectFailure); return null; } - ConfiguredTarget configuredTarget = createTarget(ruleContext, target); + ConfiguredTarget configuredTarget = + createTarget(ruleContext, target, registeredProviderTypes); SkylarkProviderValidationUtil.checkOrphanArtifacts(ruleContext); return configuredTarget; } catch (EvalException e) { @@ -131,7 +138,10 @@ public final class SkylarkRuleConfiguredTargetBuilder { // TODO(bazel-team): this whole defaulting - overriding executable, runfiles and files_to_build // is getting out of hand. Clean this whole mess up. - private static ConfiguredTarget createTarget(RuleContext ruleContext, Object target) + private static ConfiguredTarget createTarget( + RuleContext ruleContext, + Object target, + Map<String, Class<? extends TransitiveInfoProvider>> registeredProviderTypes) throws EvalException { Artifact executable = getExecutable(ruleContext, target); RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(ruleContext); @@ -142,7 +152,7 @@ public final class SkylarkRuleConfiguredTargetBuilder { filesToBuild.add(executable); } builder.setFilesToBuild(filesToBuild.build()); - return addStructFields(ruleContext, builder, target, executable); + return addStructFields(ruleContext, builder, target, executable, registeredProviderTypes); } private static Artifact getExecutable(RuleContext ruleContext, Object target) @@ -206,8 +216,12 @@ public final class SkylarkRuleConfiguredTargetBuilder { } } - private static ConfiguredTarget addStructFields(RuleContext ruleContext, - RuleConfiguredTargetBuilder builder, Object target, Artifact executable) + private static ConfiguredTarget addStructFields( + RuleContext ruleContext, + RuleConfiguredTargetBuilder builder, + Object target, + Artifact executable, + Map<String, Class<? extends TransitiveInfoProvider>> registeredProviderTypes) throws EvalException { Location loc = null; Runfiles statelessRunfiles = null; @@ -268,6 +282,10 @@ public final class SkylarkRuleConfiguredTargetBuilder { InstrumentedFilesCollector.NO_METADATA_COLLECTOR, Collections.<Artifact>emptySet()); builder.addProvider(InstrumentedFilesProvider.class, instrumentedFilesProvider); + } else if (registeredProviderTypes.containsKey(key)) { + Class<? extends TransitiveInfoProvider> providerType = registeredProviderTypes.get(key); + TransitiveInfoProvider provider = cast(key, struct, providerType, loc); + builder.addProvider(providerType, provider); } else if (!key.equals("executable")) { // We handled executable already. builder.addSkylarkTransitiveInfo(key, struct.getValue(key), loc); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java index f77e8ba1b7..a8d9931cd6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java @@ -14,9 +14,18 @@ package com.google.devtools.build.lib.rules.objc; +import com.google.common.annotations.VisibleForTesting; import com.google.devtools.build.lib.rules.apple.AppleToolchain; +import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key; import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; +import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature; +import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature.Param; +import com.google.devtools.build.lib.syntax.BuiltinFunction; +import com.google.devtools.build.lib.syntax.SkylarkDict; +import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor; + +import java.util.Map.Entry; /** * A class that exposes apple rule implementation internals to skylark. @@ -26,6 +35,25 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; doc = "Functions for skylark to access internals of the apple rule implementations." ) public class AppleSkylarkCommon { + + @VisibleForTesting + public static final String BAD_KEY_ERROR = "Argument %s not a recognized key or 'providers'."; + + @VisibleForTesting + public static final String BAD_SET_TYPE_ERROR = + "Value for key %s must be a set of %s, instead found set of %s."; + + @VisibleForTesting + public static final String BAD_PROVIDERS_ITER_ERROR = + "Value for argument 'providers' must be a list of ObjcProvider instances, instead found %s."; + + @VisibleForTesting + public static final String BAD_PROVIDERS_ELEM_ERROR = + "Value for argument 'providers' must be a list of ObjcProvider instances, instead found " + + "iterable with %s."; + + @VisibleForTesting + public static final String NOT_SET_ERROR = "Value for key %s must be a set, instead found %s."; @SkylarkCallable( name = "apple_toolchain", @@ -34,14 +62,46 @@ public class AppleSkylarkCommon { public AppleToolchain getAppleToolchain() { return new AppleToolchain(); } - - @SkylarkCallable( - name = "keys", - doc = "Retrieves ObjcProvider keys", - structField = true + + @SkylarkSignature( + name = "new_objc_provider", + objectType = AppleSkylarkCommon.class, + returnType = ObjcProvider.class, + doc = "Creates a new ObjcProvider instance.", + mandatoryPositionals = { + @Param(name = "self", type = AppleSkylarkCommon.class, doc = "The apple_common instance.") + }, + extraKeywords = { + @Param( + name = "kwargs", + type = SkylarkDict.class, + defaultValue = "{}", + doc = "Dictionary of arguments" + ) + } ) - public SkylarkKeyStore getKeys() { - return new SkylarkKeyStore(); - } + public static final BuiltinFunction NEW_OBJC_PROVIDER = + new BuiltinFunction("new_objc_provider") { + @SuppressWarnings("unused") + // This method is registered statically for skylark, and never called directly. + public ObjcProvider invoke(AppleSkylarkCommon self, SkylarkDict<String, Object> kwargs) { + ObjcProvider.Builder resultBuilder = new ObjcProvider.Builder(); + for (Entry<String, Object> entry : kwargs.entrySet()) { + Key<?> key = ObjcProvider.getSkylarkKeyForString(entry.getKey()); + if (key != null) { + resultBuilder.addElementsFromSkylark(key, entry.getValue()); + } else if (entry.getKey().equals("providers")) { + resultBuilder.addProvidersFromSkylark(entry.getValue()); + } else { + throw new IllegalArgumentException(String.format(BAD_KEY_ERROR, entry.getKey())); + } + } + return resultBuilder.build(); + } + }; + + static { + SkylarkSignatureProcessor.configureSkylarkFunctions(AppleSkylarkCommon.class); + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java index 442a847494..d06a374f07 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java @@ -27,7 +27,6 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.RunfilesSupport; -import com.google.devtools.build.lib.analysis.SkylarkProviders; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.rules.apple.AppleConfiguration; @@ -38,7 +37,6 @@ import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes; import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary; import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; -import com.google.devtools.build.lib.syntax.ClassObject.SkylarkClassObject; /** * Implementation for rules that link binaries. @@ -173,10 +171,7 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory .addProvider(ObjcProvider.class, objcProvider) .addProvider( InstrumentedFilesProvider.class, - compilationSupport.getInstrumentedFilesProvider(common)) - .addSkylarkTransitiveInfo( - ObjcProvider.OBJC_SKYLARK_PROVIDER_NAME, - common.getObjcProvider().toSkylarkProvider()); + compilationSupport.getInstrumentedFilesProvider(common)); if (xcTestAppProvider.isPresent()) { // TODO(bazel-team): Stop exporting an XcTestAppProvider once objc_binary no longer creates an // application bundle. @@ -222,8 +217,6 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory .setHasModuleMap() .setLinkedBinary(intermediateArtifacts.strippedSingleArchitectureBinary()); - builder.addDepObjcProviders(createSkylarkObjcProviders(ruleContext)); - if (ObjcRuleClasses.objcConfiguration(ruleContext).generateDebugSymbols() || ObjcRuleClasses.objcConfiguration(ruleContext).generateDsym()) { builder.addDebugArtifacts(DsymOutputType.APP); @@ -237,25 +230,6 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory } /** - * Constructs an ObjcProvider instance for each skylark objc provider in this target's - * dependencies. - */ - private Iterable<ObjcProvider> createSkylarkObjcProviders(RuleContext ruleContext) { - ImmutableList.Builder<ObjcProvider> skylarkProviderListBuilder = ImmutableList.builder(); - for (SkylarkProviders skylarkProviders : - ruleContext.getPrerequisites("deps", Mode.TARGET, SkylarkProviders.class)) { - Object objcSkylarkProvider = - skylarkProviders.getValue(ObjcProvider.OBJC_SKYLARK_PROVIDER_TO_EXPORT_NAME); - if (objcSkylarkProvider != null) { - ObjcProvider objcProviderFromSkylark = - ObjcProvider.fromSkylarkProvider((SkylarkClassObject) objcSkylarkProvider); - skylarkProviderListBuilder.add(objcProviderFromSkylark); - } - } - return skylarkProviderListBuilder.build(); - } - - /** * Performs additional configuration of the target. The default implementation does nothing, but * subclasses may override it to add logic. */ diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java index c2dce23cbb..fd37871cc8 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java @@ -82,8 +82,6 @@ public class J2ObjcLibrary implements RuleConfiguredTargetFactory { J2ObjcMappingFileProvider.class, ObjcRuleClasses.j2ObjcMappingFileProvider(ruleContext)) .addProvider(ObjcProvider.class, objcProvider) .addProvider(XcodeProvider.class, xcodeProviderBuilder.build()) - .addSkylarkTransitiveInfo( - ObjcProvider.OBJC_SKYLARK_PROVIDER_NAME, objcProvider.toSkylarkProvider()) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java index 991a6d83be..aad16f1e1b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java @@ -143,8 +143,6 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory { .addProvider( CcLinkParamsProvider.class, new CcLinkParamsProvider(new ObjcLibraryCcLinkParamsStore(common))) - .addSkylarkTransitiveInfo( - ObjcProvider.OBJC_SKYLARK_PROVIDER_NAME, common.getObjcProvider().toSkylarkProvider()) .build(); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java index e46d8204ec..c7b115f79a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java @@ -64,8 +64,6 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory { return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build()) .addProvider(XcodeProvider.class, xcodeProviderBuilder.build()) .addProvider(ObjcProvider.class, common.getObjcProvider()) - .addSkylarkTransitiveInfo( - ObjcProvider.OBJC_SKYLARK_PROVIDER_NAME, common.getObjcProvider().toSkylarkProvider()) .build(); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java index 91f5c1fca2..92ddc73b3f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java @@ -28,10 +28,10 @@ import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.rules.cpp.CppModuleMap; import com.google.devtools.build.lib.rules.cpp.LinkerInputs; -import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.syntax.ClassObject.SkylarkClassObject; import com.google.devtools.build.lib.syntax.SkylarkNestedSet; +import com.google.devtools.build.lib.syntax.SkylarkType; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.TargetControl; @@ -44,29 +44,19 @@ import java.util.Map; * deps that are needed for building Objective-C rules. */ @Immutable -public final class ObjcProvider implements TransitiveInfoProvider { +@SkylarkModule(name = "ObjcProvider", doc = "A provider for compilation and linking of objc.") +public final class ObjcProvider extends SkylarkClassObject implements TransitiveInfoProvider { /** - * The name skylark dependents can use to access a Skylark provider containing information - * from a target's ObjcProvider. + * The skylark struct key name for a rule implementation to use when exporting an ObjcProvider. */ public static final String OBJC_SKYLARK_PROVIDER_NAME = "objc"; /** - * The name skylark dependents can use to export a native objc provider to depending native - * rules. - * - * <p>This constant must be different from OBJC_SKYLARK_PROVIDER_NAME to prevent skylark rules - * from automatically exporting the ObjcProvider provided to them by dependents. This can - * lead to duplicate symbol linker errors. - */ - public static final String OBJC_SKYLARK_PROVIDER_TO_EXPORT_NAME = "objc_export"; - - /** * Represents one of the things this provider can provide transitively. Things are provided as * {@link NestedSet}s of type E. */ - @SkylarkModule(name = "Key", doc = "An ObjcProvider key.") + @Immutable public static class Key<E> { private final Order order; private final String skylarkKeyName; @@ -81,7 +71,6 @@ public final class ObjcProvider implements TransitiveInfoProvider { /** * Returns the name of the collection represented by this key in the Skylark provider. */ - @SkylarkCallable(name = "name", structField = true) public String getSkylarkKeyName() { return skylarkKeyName; } @@ -95,6 +84,7 @@ public final class ObjcProvider implements TransitiveInfoProvider { } public static final Key<Artifact> LIBRARY = new Key<>(LINK_ORDER, "library", Artifact.class); + public static final Key<Artifact> IMPORTED_LIBRARY = new Key<>(LINK_ORDER, "imported_library", Artifact.class); @@ -339,6 +329,51 @@ public final class ObjcProvider implements TransitiveInfoProvider { // Items which should not be propagated to dependents. private final ImmutableMap<Key<?>, NestedSet<?>> nonPropagatedItems; + /** + * All keys in ObjcProvider that will be passed in the corresponding Skylark provider. + */ + // Only keys for Artifact or primitive types can be in the Skylark provider, as other types + // are not supported as Skylark types. + // Note: This list is only required to support objcprovider <-> skylarkprovider conversion, which + // will be removed in favor of native skylark ObjcProvider access once that is implemented. + static final ImmutableList<Key<?>> KEYS_FOR_SKYLARK = + ImmutableList.<Key<?>>of( + LIBRARY, + IMPORTED_LIBRARY, + LINKED_BINARY, + FORCE_LOAD_LIBRARY, + HEADER, + SOURCE, + DEFINE, + ASSET_CATALOG, + SDK_DYLIB, + XCDATAMODEL, + MODULE_MAP, + MERGE_ZIP, + FRAMEWORK_FILE, + DEBUG_SYMBOLS, + DEBUG_SYMBOLS_PLIST, + BREAKPAD_FILE, + STORYBOARD, + XIB, + STRINGS, + LINKOPT, + J2OBJC_LIBRARY, + ROOT_MERGE_ZIP); + + /** + * Returns the skylark key for the given string, or null if no such key exists or is available + * to Skylark. + */ + static Key<?> getSkylarkKeyForString(String keyName) { + Key<?> result = null; + for (Key<?> candidateKey : KEYS_FOR_SKYLARK) { + if (candidateKey.getSkylarkKeyName().equals(keyName)) { + return candidateKey; + } + } + return null; + } // Items which should be passed to strictly direct dependers, but not transitive dependers. private final ImmutableMap<Key<?>, NestedSet<?>> strictDependencyItems; @@ -346,7 +381,9 @@ public final class ObjcProvider implements TransitiveInfoProvider { private ObjcProvider( ImmutableMap<Key<?>, NestedSet<?>> items, ImmutableMap<Key<?>, NestedSet<?>> nonPropagatedItems, - ImmutableMap<Key<?>, NestedSet<?>> strictDependencyItems) { + ImmutableMap<Key<?>, NestedSet<?>> strictDependencyItems, + ImmutableMap<String, Object> skylarkFields) { + super(skylarkFields, "ObjcProvider field %s could not be instantiated"); this.items = Preconditions.checkNotNull(items); this.nonPropagatedItems = Preconditions.checkNotNull(nonPropagatedItems); this.strictDependencyItems = Preconditions.checkNotNull(strictDependencyItems); @@ -387,35 +424,6 @@ public final class ObjcProvider implements TransitiveInfoProvider { } /** - * Returns a {@code SkylarkClassObject} containing values from this provider that is suitable - * for a skylark provider. - */ - public SkylarkClassObject toSkylarkProvider() { - ImmutableMap.Builder<String, Object> providerBuilder = ImmutableMap.<String, Object>builder(); - for (Key<?> key : SkylarkKeyStore.KEYS_FOR_SKYLARK) { - providerBuilder.put(key.getSkylarkKeyName(), new SkylarkNestedSet(key.getType(), get(key))); - } - return new SkylarkClassObject(providerBuilder.build(), "No such attribute '%s'"); - } - - /** - * Returns an {@code ObjcProvider} from a given skylark provider. For each candidate key - * in the ObjcProvider, will check the given skylark provider to see if that key is represented - * in the returned struct. - */ - public static ObjcProvider fromSkylarkProvider(SkylarkClassObject skylarkProvider) { - Builder builder = new Builder(); - for (Key<?> key : SkylarkKeyStore.KEYS_FOR_SKYLARK) { - SkylarkNestedSet skylarkSet = - (SkylarkNestedSet) skylarkProvider.getValue(key.getSkylarkKeyName()); - if (skylarkSet != null) { - builder.uncheckedAddAll(key, skylarkSet.getSet(key.getType()), builder.items); - } - } - return builder.build(); - } - - /** * A builder for this context with an API that is optimized for collecting information from * several transitive dependencies. */ @@ -576,20 +584,83 @@ public final class ObjcProvider implements TransitiveInfoProvider { return this; } + /** + * Add elements in toAdd with the given key from skylark. An error is thrown if toAdd is not + * an appropriate SkylarkNestedSet. + */ + void addElementsFromSkylark(Key<?> key, Object toAdd) { + if (!(toAdd instanceof SkylarkNestedSet)) { + throw new IllegalArgumentException( + String.format( + AppleSkylarkCommon.NOT_SET_ERROR, key.getSkylarkKeyName(), toAdd.getClass())); + } else if (!((SkylarkNestedSet) toAdd).getContentType().canBeCastTo(key.getType())) { + throw new IllegalArgumentException( + String.format( + AppleSkylarkCommon.BAD_SET_TYPE_ERROR, + key.getSkylarkKeyName(), + key.getType(), + ((SkylarkNestedSet) toAdd).getContentType().getType())); + } else { + uncheckedAddAll(key, (SkylarkNestedSet) toAdd, this.items); + } + } + + /** + * Adds the given providers from skylark. An error is thrown if toAdd is not an iterable of + * ObjcProvider instances. + */ + @SuppressWarnings("unchecked") + void addProvidersFromSkylark(Object toAdd) { + if (!(toAdd instanceof Iterable)) { + throw new IllegalArgumentException( + String.format(AppleSkylarkCommon.BAD_PROVIDERS_ITER_ERROR, toAdd.getClass())); + } else { + Iterable<Object> toAddIterable = (Iterable<Object>) toAdd; + for (Object toAddObject : toAddIterable) { + if (!(toAddObject instanceof ObjcProvider)) { + throw new IllegalArgumentException( + String.format(AppleSkylarkCommon.BAD_PROVIDERS_ELEM_ERROR, toAddObject.getClass())); + } else { + this.addTransitiveAndPropagate((ObjcProvider) toAddObject); + } + } + } + } + public ObjcProvider build() { - ImmutableMap.Builder<Key<?>, NestedSet<?>> propagated = new ImmutableMap.Builder<>(); + ImmutableMap.Builder<Key<?>, NestedSet<?>> propagatedBuilder = new ImmutableMap.Builder<>(); for (Map.Entry<Key<?>, NestedSetBuilder<?>> typeEntry : items.entrySet()) { - propagated.put(typeEntry.getKey(), typeEntry.getValue().build()); + propagatedBuilder.put(typeEntry.getKey(), typeEntry.getValue().build()); } - ImmutableMap.Builder<Key<?>, NestedSet<?>> nonPropagated = new ImmutableMap.Builder<>(); + ImmutableMap.Builder<Key<?>, NestedSet<?>> nonPropagatedBuilder = + new ImmutableMap.Builder<>(); for (Map.Entry<Key<?>, NestedSetBuilder<?>> typeEntry : nonPropagatedItems.entrySet()) { - nonPropagated.put(typeEntry.getKey(), typeEntry.getValue().build()); + nonPropagatedBuilder.put(typeEntry.getKey(), typeEntry.getValue().build()); } - ImmutableMap.Builder<Key<?>, NestedSet<?>> strictDependency = new ImmutableMap.Builder<>(); + ImmutableMap.Builder<Key<?>, NestedSet<?>> strictDependencyBuilder = + new ImmutableMap.Builder<>(); for (Map.Entry<Key<?>, NestedSetBuilder<?>> typeEntry : strictDependencyItems.entrySet()) { - strictDependency.put(typeEntry.getKey(), typeEntry.getValue().build()); + strictDependencyBuilder.put(typeEntry.getKey(), typeEntry.getValue().build()); + } + + ImmutableMap<Key<?>, NestedSet<?>> propagated = propagatedBuilder.build(); + ImmutableMap<Key<?>, NestedSet<?>> nonPropagated = nonPropagatedBuilder.build(); + ImmutableMap<Key<?>, NestedSet<?>> strictDependency = strictDependencyBuilder.build(); + + ImmutableMap.Builder<String, Object> skylarkFields = new ImmutableMap.Builder<>(); + for (Key<?> key : KEYS_FOR_SKYLARK) { + SkylarkType type = SkylarkType.of(key.getType()); + if (items.containsKey(key)) { + skylarkFields.put( + key.getSkylarkKeyName(), SkylarkNestedSet.of(type, propagated.get(key))); + } + if (strictDependency.containsKey(key)) { + skylarkFields.put( + key.getSkylarkKeyName(), SkylarkNestedSet.of(type, strictDependency.get(key))); + } } - return new ObjcProvider(propagated.build(), nonPropagated.build(), strictDependency.build()); + + return new ObjcProvider(propagated, nonPropagated, strictDependency, skylarkFields.build()); } } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/SkylarkKeyStore.java b/src/main/java/com/google/devtools/build/lib/rules/objc/SkylarkKeyStore.java deleted file mode 100644 index 0b99bdcdc1..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/SkylarkKeyStore.java +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright 2016 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. - -package com.google.devtools.build.lib.rules.objc; - -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key; -import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; - -/** - * A container for valid ObjcProvider keys, to be provided to skylark. - */ -@SkylarkModule( - name = "objc_provider_keys_store", - doc = "A container for valid ObjcProvider keys." -) -public class SkylarkKeyStore { - - @SkylarkCallable( - name = "library", - doc = "Returns a key that gives libraries in this target" - ) - public static Key<Artifact> getLibrary() { - return ObjcProvider.LIBRARY; - } - - @SkylarkCallable( - name = "imported_library", - doc = "Returns a key that gives imported libraries in this target" - ) - public static Key<Artifact> getImportedLibrary() { - return ObjcProvider.IMPORTED_LIBRARY; - } - - @SkylarkCallable( - name = "linked_binary", - doc = "Returns a key that gives single-architecture linked binaries to " - + "be combined into a multi-architecture binary" - ) - public static Key<Artifact> getLinkedBinary() { - return ObjcProvider.LINKED_BINARY; - } - - @SkylarkCallable( - name = "force_load_library", - doc = "Returns a key that gives libraries to laod with the " - + "'-force_load' flag." - ) - public static Key<Artifact> getForceLoadLibrary() { - return ObjcProvider.FORCE_LOAD_LIBRARY; - } - - @SkylarkCallable( - name = "header", - doc = "Returns a key that gives all header files." - ) - public static Key<Artifact> getHeader() { - return ObjcProvider.HEADER; - } - - @SkylarkCallable( - name = "source", - doc = "Returns a key that gives all source files." - ) - public static Key<Artifact> getSource() { - return ObjcProvider.SOURCE; - } - - @SkylarkCallable( - name = "define", - doc = "Returns a key that gives all values in 'defines' attributes." - ) - public static Key<String> getDefine() { - return ObjcProvider.DEFINE; - } - - @SkylarkCallable( - name = "asset_catalog", - doc = "Returns the 'ASSET_CATALOG' key." - ) - public static Key<Artifact> getAssetCatalog() { - return ObjcProvider.ASSET_CATALOG; - } - - @SkylarkCallable( - name = "sdk_dylib", - doc = "Returns the 'SDK_DYLIB' key." - ) - public static Key<String> getSdkDylib() { - return ObjcProvider.SDK_DYLIB; - } - - @SkylarkCallable( - name = "xcdatamodel", - doc = "Returns the 'XCDATAMODEL' key." - ) - public static Key<Artifact> getXcDataModel() { - return ObjcProvider.XCDATAMODEL; - } - - @SkylarkCallable( - name = "module_map", - doc = "Returns a key that gives clang module maps." - ) - public static Key<Artifact> getModuleMap() { - return ObjcProvider.MODULE_MAP; - } - - @SkylarkCallable( - name = "merge_zip", - doc = "Returns a key that gives zips to include in the bundle." - ) - public static Key<Artifact> getMergeZip() { - return ObjcProvider.MERGE_ZIP; - } - - @SkylarkCallable( - name = "root_merge_zip", - doc = "Returns a key that gives zips to include outside the bundle." - ) - public static Key<Artifact> getRootMergeZip() { - return ObjcProvider.ROOT_MERGE_ZIP; - } - - @SkylarkCallable( - name = "framework_file", - doc = "Returns a key that gives .framework files to be included in " - + "compilation and linking." - ) - public static Key<Artifact> getFrameworkFile() { - return ObjcProvider.FRAMEWORK_FILE; - } - - @SkylarkCallable( - name = "debug_symbols", - doc = "Returns a key that gives an artifact containing debug symbol " - + "information." - ) - public static Key<Artifact> getDebugSymbols() { - return ObjcProvider.DEBUG_SYMBOLS; - } - - @SkylarkCallable( - name = "debug_symbols_plist", - doc = "Returns a key that gives an artifact containing the plist " - + "on debug symbols." - ) - public static Key<Artifact> getDebugSymbolsPlist() { - return ObjcProvider.DEBUG_SYMBOLS_PLIST; - } - - @SkylarkCallable( - name = "breakpad_file", - doc = "Returns a key that gives the generated breakpad file for crash " - + "reporting." - ) - public static Key<Artifact> getBreakpadFile() { - return ObjcProvider.BREAKPAD_FILE; - } - - @SkylarkCallable( - name = "storyboard", - doc = "Returns a key that gives artifacts for storyboard sources." - ) - public static Key<Artifact> getStoryboard() { - return ObjcProvider.STORYBOARD; - } - - @SkylarkCallable( - name = "xib", - doc = "Returns a key that gives artifacts for .xib file sources." - ) - public static Key<Artifact> getXib() { - return ObjcProvider.XIB; - } - - @SkylarkCallable( - name = "strings", - doc = "Returns a key that gives artifacts for strings source files." - ) - public static Key<Artifact> getStrings() { - return ObjcProvider.STRINGS; - } - - @SkylarkCallable( - name = "linkopt", - doc = "Returns a key that gives linking options from dependencies." - ) - public static Key<String> getLinkopt() { - return ObjcProvider.LINKOPT; - } - - @SkylarkCallable( - name = "j2objc_library", - doc = "Returns a key that gives static libraries that are built from " - + "J2ObjC-translated Java code." - ) - public static Key<Artifact> getJ2ObjcLibrary() { - return ObjcProvider.J2OBJC_LIBRARY; - } - - /** - * All keys in ObjcProvider that will be passed in the corresponding Skylark provider. - */ - // Only keys for Artifact or primitive types can be in the Skylark provider, as other types - // are not supported as Skylark types. - // Note: This list is only required to support objcprovider <-> skylarkprovider conversion, which - // will be removed in favor of native skylark ObjcProvider access once that is implemented. - static final ImmutableList<ObjcProvider.Key<?>> KEYS_FOR_SKYLARK = - ImmutableList.<ObjcProvider.Key<?>>of( - ObjcProvider.LIBRARY, - ObjcProvider.IMPORTED_LIBRARY, - ObjcProvider.LINKED_BINARY, - ObjcProvider.FORCE_LOAD_LIBRARY, - ObjcProvider.HEADER, - ObjcProvider.SOURCE, - ObjcProvider.DEFINE, - ObjcProvider.ASSET_CATALOG, - ObjcProvider.SDK_DYLIB, - ObjcProvider.XCDATAMODEL, - ObjcProvider.MODULE_MAP, - ObjcProvider.MERGE_ZIP, - ObjcProvider.FRAMEWORK_FILE, - ObjcProvider.DEBUG_SYMBOLS, - ObjcProvider.DEBUG_SYMBOLS_PLIST, - ObjcProvider.BREAKPAD_FILE, - ObjcProvider.STORYBOARD, - ObjcProvider.XIB, - ObjcProvider.STRINGS, - ObjcProvider.LINKOPT, - ObjcProvider.J2OBJC_LIBRARY, - ObjcProvider.ROOT_MERGE_ZIP); -} |