/*
* Copyright 2013-present Facebook, Inc.
*
* 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.facebook.buck.android;
import com.facebook.buck.jvm.java.AnnotationProcessingParams;
import com.facebook.buck.jvm.java.CompileToJarStepFactory;
import com.facebook.buck.jvm.java.HasJavaAbi;
import com.facebook.buck.jvm.java.Javac;
import com.facebook.buck.jvm.java.JavacOptions;
import com.facebook.buck.jvm.java.JavacOptionsAmender;
import com.facebook.buck.jvm.java.JavacToJarStepFactory;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.Flavor;
import com.facebook.buck.model.InternalFlavor;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.SourcePathRuleFinder;
import com.facebook.buck.util.DependencyMode;
import com.google.common.base.Preconditions;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import java.util.Optional;
public class AndroidLibraryGraphEnhancer {
public static final Flavor DUMMY_R_DOT_JAVA_FLAVOR = InternalFlavor.of("dummy_r_dot_java");
private final BuildTarget dummyRDotJavaBuildTarget;
private final BuildRuleParams originalBuildRuleParams;
private final Javac javac;
private final JavacOptions javacOptions;
private final DependencyMode resourceDependencyMode;
private final boolean forceFinalResourceIds;
private final Optional<String> resourceUnionPackage;
private final Optional<String> finalRName;
private final boolean useOldStyleableFormat;
public AndroidLibraryGraphEnhancer(
BuildTarget buildTarget,
BuildRuleParams buildRuleParams,
Javac javac,
JavacOptions javacOptions,
DependencyMode resourceDependencyMode,
boolean forceFinalResourceIds,
Optional<String> resourceUnionPackage,
Optional<String> finalRName,
boolean useOldStyleableFormat) {
this.dummyRDotJavaBuildTarget = getDummyRDotJavaTarget(buildTarget);
this.originalBuildRuleParams = buildRuleParams;
this.javac = javac;
// Override javacoptions because DummyRDotJava doesn't require annotation processing.
this.javacOptions =
JavacOptions.builder(javacOptions)
.setAnnotationProcessingParams(AnnotationProcessingParams.EMPTY)
.build();
this.resourceDependencyMode = resourceDependencyMode;
this.forceFinalResourceIds = forceFinalResourceIds;
this.resourceUnionPackage = resourceUnionPackage;
this.finalRName = finalRName;
this.useOldStyleableFormat = useOldStyleableFormat;
}
public static BuildTarget getDummyRDotJavaTarget(BuildTarget buildTarget) {
return BuildTarget.builder(buildTarget).addFlavors(DUMMY_R_DOT_JAVA_FLAVOR).build();
}
public Optional<DummyRDotJava> getBuildableForAndroidResources(
BuildRuleResolver ruleResolver, boolean createBuildableIfEmptyDeps) {
Preconditions.checkState(!HasJavaAbi.isAbiTarget(dummyRDotJavaBuildTarget));
Optional<BuildRule> previouslyCreated = ruleResolver.getRuleOptional(dummyRDotJavaBuildTarget);
if (previouslyCreated.isPresent()) {
return previouslyCreated.map(input -> (DummyRDotJava) input);
}
ImmutableSortedSet<BuildRule> originalDeps = originalBuildRuleParams.getBuildDeps();
ImmutableSet<HasAndroidResourceDeps> androidResourceDeps;
switch (resourceDependencyMode) {
case FIRST_ORDER:
androidResourceDeps =
FluentIterable.from(originalDeps)
.filter(HasAndroidResourceDeps.class)
.filter(input -> input.getRes() != null)
.toSet();
break;
case TRANSITIVE:
androidResourceDeps =
UnsortedAndroidResourceDeps.createFrom(originalDeps, Optional.empty())
.getResourceDeps();
break;
default:
throw new IllegalStateException(
"Invalid resource dependency mode: " + resourceDependencyMode);
}
if (androidResourceDeps.isEmpty() && !createBuildableIfEmptyDeps) {
return Optional.empty();
}
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(ruleResolver);
CompileToJarStepFactory compileToJarStepFactory =
new JavacToJarStepFactory(javac, javacOptions, JavacOptionsAmender.IDENTITY);
BuildRuleParams dummyRDotJavaParams =
compileToJarStepFactory
.addInputs(
// DummyRDotJava inherits no dependencies from its android_library beyond the compiler
// that is used to build it
originalBuildRuleParams.copyReplacingDeclaredAndExtraDeps(
ImmutableSortedSet::of, ImmutableSortedSet::of),
ruleFinder)
.withBuildTarget(dummyRDotJavaBuildTarget);
DummyRDotJava dummyRDotJava =
new DummyRDotJava(
dummyRDotJavaParams,
ruleFinder,
androidResourceDeps,
compileToJarStepFactory,
forceFinalResourceIds,
resourceUnionPackage,
finalRName,
useOldStyleableFormat);
ruleResolver.addToIndex(dummyRDotJava);
return Optional.of(dummyRDotJava);
}
}