/*
* Copyright 2017-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.jvm.java;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.CellPathResolver;
import com.facebook.buck.rules.CommonDescriptionArg;
import com.facebook.buck.rules.Description;
import com.facebook.buck.rules.HasDeclaredDeps;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SourcePathRuleFinder;
import com.facebook.buck.rules.TargetGraph;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.buck.util.immutables.BuckStyleImmutable;
import com.facebook.buck.versions.VersionPropagator;
import org.immutables.value.Value;
/**
* Description of a rule that builds a Java compiler plugin (either a {@link
* javax.annotation.processing.Processor} or TODO(jkeljo): a {@link com.sun.source.util.Plugin}).
*/
public class JavaAnnotationProcessorDescription
implements Description<JavaAnnotationProcessorDescriptionArg>,
VersionPropagator<JavaAnnotationProcessorDescriptionArg> {
@Override
public Class<JavaAnnotationProcessorDescriptionArg> getConstructorArgType() {
return JavaAnnotationProcessorDescriptionArg.class;
}
@Override
public BuildRule createBuildRule(
TargetGraph targetGraph,
BuildRuleParams params,
BuildRuleResolver resolver,
CellPathResolver cellRoots,
JavaAnnotationProcessorDescriptionArg args)
throws NoSuchBuildTargetException {
JavacPluginProperties.Builder propsBuilder = JavacPluginProperties.builder();
propsBuilder.addProcessorNames(args.getProcessorClass());
for (BuildRule dep : params.getBuildDeps()) {
if (!(dep instanceof JavaLibrary)) {
throw new HumanReadableException(
String.format(
"%s: dependencies must produce JVM libraries; %s is a %s",
params.getBuildTarget(), dep.getBuildTarget(), dep.getType()));
}
propsBuilder.addDep(dep);
}
boolean reuseClassLoader = !args.isIsolateClassLoader();
propsBuilder.setCanReuseClassLoader(reuseClassLoader);
propsBuilder.setDoesNotAffectAbi(args.isDoesNotAffectAbi());
propsBuilder.setSupportsAbiGenerationFromSource(args.isSupportsAbiGenerationFromSource());
JavacPluginProperties properties = propsBuilder.build();
SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(resolver));
return new JavaAnnotationProcessor(
params.copyAppendingExtraDeps(properties.getClasspathDeps()), pathResolver, properties);
}
@BuckStyleImmutable
@Value.Immutable
interface AbstractJavaAnnotationProcessorDescriptionArg
extends CommonDescriptionArg, HasDeclaredDeps {
String getProcessorClass();
@Value.Default
default boolean isIsolateClassLoader() {
return false;
}
/**
* A value of false indicates that the annotation processor generates classes that are intended
* for use outside of the code being processed. Annotation processors that affect the ABI of the
* rule in which they run must be run during ABI generation from source.
*
* <p>Defaults to false because that's the "safe" value. When migrating to ABI generation from
* source, having as few ABI-affecting processors as possible will yield the fastest ABI
* generation.
*/
@Value.Default
default boolean isDoesNotAffectAbi() {
return false;
}
/**
* If true, allows ABI-affecting annotation processors to run during ABI generation from source.
* To run during ABI generation from source, an annotation processor must meet all of the
* following criteria:
* <li>
*
* <ul>
* Uses only the public APIs from JSR-269 (annotation processing). Access to the Compiler
* Tree API may also be possible via a Buck support library.
* </ul>
*
* <ul>
* Does not require details about types beyond those being compiled as a general rule. There
* are ways to ensure type information is available on a case by case basis, at some
* performance cost.
* </ul>
*
* Defaults to false because that's the "safe" value. When migrating to ABI generation from
* source, having as many ABI-affecting processors as possible running during ABI generation
* will result in the flattest build graph.
*/
@Value.Default
default boolean isSupportsAbiGenerationFromSource() {
return false;
}
}
}