Skip to content

Commit

Permalink
facebook#956 [WIP] Add kotlin annotation processor (kapt) support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Woodward committed Oct 13, 2017
1 parent 1f717b5 commit d18c4f2
Show file tree
Hide file tree
Showing 15 changed files with 463 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/com/facebook/buck/jvm/kotlin/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ java_immutables_library(
"//src/com/facebook/buck/rules/macros:macros",
"//src/com/facebook/buck/shell:steps",
"//src/com/facebook/buck/step:step",
"//src/com/facebook/buck/step/fs:fs",
"//src/com/facebook/buck/util:exceptions",
"//src/com/facebook/buck/util:io",
"//src/com/facebook/buck/util:process_executor",
Expand Down
11 changes: 11 additions & 0 deletions src/com/facebook/buck/jvm/kotlin/ExternalKotlinc.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public int buildWithClasspath(
ImmutableList<String> command =
ImmutableList.<String>builder()
.add(pathToKotlinc.toString())
.addAll(options)
.addAll(
transform(
kotlinSourceFilePaths,
Expand Down Expand Up @@ -168,6 +169,16 @@ public String getShortName() {
return pathToKotlinc.toString();
}

@Override
public Path getAPPaths() {
throw new IllegalStateException("Not supported yet");
}

@Override
public Path getStdlibPath() {
throw new IllegalStateException("Not supported yet");
}

@Override
public ImmutableMap<String, String> getEnvironment(SourcePathResolver resolver) {
return ImmutableMap.of();
Expand Down
19 changes: 18 additions & 1 deletion src/com/facebook/buck/jvm/kotlin/JarBackedReflectedKotlinc.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,16 @@ public class JarBackedReflectedKotlinc implements Kotlinc {
private static final Map<Set<String>, Object> kotlinShims = new ConcurrentHashMap<>();

private final ImmutableSet<SourcePath> compilerClassPath;
private final Path annotationProcessingClassPath;
private final Path pathToStdlibJar;

JarBackedReflectedKotlinc(ImmutableSet<SourcePath> compilerClassPath) {
JarBackedReflectedKotlinc(
ImmutableSet<SourcePath> compilerClassPath,
Path annotationProcessingClassPath,
Path pathToStdlibJar) {
this.compilerClassPath = compilerClassPath;
this.annotationProcessingClassPath = annotationProcessingClassPath;
this.pathToStdlibJar = pathToStdlibJar;
}

@Override
Expand All @@ -95,6 +102,16 @@ public String getShortName() {
return "kotlinc";
}

@Override
public Path getAPPaths() {
return annotationProcessingClassPath;
}

@Override
public Path getStdlibPath() {
return pathToStdlibJar;
}

@Override
public ImmutableList<String> getCommandPrefix(SourcePathResolver resolver) {
throw new UnsupportedOperationException("In memory kotlinc may not be used externally");
Expand Down
89 changes: 87 additions & 2 deletions src/com/facebook/buck/jvm/kotlin/KotlinBuckConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;

public class KotlinBuckConfig {
private static final String SECTION = "kotlin";
private static final String JAVA_SECTION = "java";

private static final Path DEFAULT_KOTLIN_COMPILER = Paths.get("kotlinc");

Expand All @@ -47,9 +49,10 @@ public Kotlinc getKotlinc() {
ImmutableSet<SourcePath> classpathEntries =
ImmutableSet.of(
delegate.getSourcePath(getPathToStdlibJar()),
delegate.getSourcePath(getPathToCompilerJar()));
delegate.getSourcePath(getPathToCompilerJar()),
delegate.getSourcePath(getPathToTools()));

return new JarBackedReflectedKotlinc(classpathEntries);
return new JarBackedReflectedKotlinc(classpathEntries, getPathToAP(), getPathToStdlibJar());
}
}

Expand Down Expand Up @@ -131,6 +134,49 @@ Path getPathToCompilerJar() {
"Could not resolve kotlin compiler JAR location (kotlin home:" + getKotlinHome() + ").");
}

/**
* Get the path to the Kotlin annotation processing jar.
*
* @return the Kotlin annotation processing jar path
*/
Path getPathToAP() {
Path compiler = getKotlinHome().resolve("kotlin-annotation-processing.jar");
if (Files.isRegularFile(compiler)) {
return compiler.normalize();
}

compiler = getKotlinHome().resolve(Paths.get("lib", "kotlin-annotation-processing.jar"));
if (Files.isRegularFile(compiler)) {
return compiler.normalize();
}

compiler =
getKotlinHome().resolve(Paths.get("libexec", "lib", "kotlin-annotation-processing.jar"));
if (Files.isRegularFile(compiler)) {
return compiler.normalize();
}

throw new HumanReadableException(
"Could not resolve kotlin annotation processing JAR location (kotlin home:"
+ getKotlinHome()
+ ").");
}

/**
* Get the path to the java tools jar.
*
* @return the java tools jar path
*/
Path getPathToTools() {
Path compiler = getJavaHome().resolve("lib/tools.jar");
if (Files.isRegularFile(compiler)) {
return compiler.normalize();
}

throw new HumanReadableException(
"Could not resolve tools JAR location (java home:" + getJavaHome() + ").");
}

/**
* Determine whether external Kotlin compilation is being forced. The default is internal
* (in-process) execution, but this can be overridden in .buckconfig by setting the "external"
Expand Down Expand Up @@ -200,4 +246,43 @@ private Path getKotlinHome() {
"Could not resolve kotlin home directory, Consider setting KOTLIN_HOME.", io);
}
}

/**
* Find the Java home (installation) directory by searching in this order: <br>
*
* <ul>
* <li>If the "java_home" directory is specified in .buckconfig then use it.
* <li>Check the environment for a JAVA_HOME variable, if defined then use it.
* </ul>
*
* @return the Java home path
*/
// String javaHome = "/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/";
private Path getJavaHome() {
Map<String, String> environment = System.getenv();
try {
// Check the buck configuration for a specified kotlin home
Optional<String> value = delegate.getValue(JAVA_SECTION, "java_home");
if (value.isPresent()) {
boolean isAbsolute = Paths.get(value.get()).isAbsolute();
Optional<Path> homePath = delegate.getPath(JAVA_SECTION, "java_home", !isAbsolute);
if (homePath.isPresent() && Files.isDirectory(homePath.get())) {
return homePath.get().toRealPath().normalize();
} else {
throw new HumanReadableException(
"Java home directory (" + homePath + ") specified in .buckconfig was not found.");
}
} else if (environment.containsKey("JAVA_HOME")) {
return Paths.get(environment.get("JAVA_HOME")).normalize();
} else if (System.getProperty("java.home") != null) {
return Paths.get(System.getProperty("java.home")).normalize();
} else {
throw new HumanReadableException(
"Could not resolve java home directory, Consider setting JAVA_HOME.");
}
} catch (IOException io) {
throw new HumanReadableException(
"Could not resolve java home directory, Consider setting JAVA_HOME.", io);
}
}
}
4 changes: 4 additions & 0 deletions src/com/facebook/buck/jvm/kotlin/Kotlinc.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,8 @@ String getDescription(
Path pathToSrcsList);

String getShortName();

Path getAPPaths();

Path getStdlibPath();
}
12 changes: 9 additions & 3 deletions src/com/facebook/buck/jvm/kotlin/KotlincStep.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@
import java.util.Optional;

public class KotlincStep implements Step {
private static final String CLASSPATH_FLAG = "-cp";
private static final String CLASSPATH_FLAG = "-classpath";
private static final String DESTINATION_FLAG = "-d";
private static final String INCLUDE_RUNTIME_FLAG = "-include-runtime";
private static final String EXCLUDE_REFLECT = "-no-reflect";
private static final String VERBOSE = "-verbose";

private final Kotlinc kotlinc;
private final ImmutableSortedSet<Path> combinedClassPathEntries;
Expand Down Expand Up @@ -136,7 +138,9 @@ private ImmutableList<String> getOptions(

final ImmutableList.Builder<String> builder = ImmutableList.builder();

builder.add(INCLUDE_RUNTIME_FLAG);
if (outputDirectory != null) {
builder.add(DESTINATION_FLAG, filesystem.resolve(outputDirectory).toString());
}

if (!buildClasspathEntries.isEmpty()) {
builder.add(
Expand All @@ -148,7 +152,9 @@ private ImmutableList<String> getOptions(
path -> filesystem.resolve(path).toAbsolutePath().toString())));
}

builder.add(DESTINATION_FLAG, filesystem.resolve(outputDirectory).toString());
builder.add(INCLUDE_RUNTIME_FLAG);
builder.add(EXCLUDE_REFLECT);
builder.add(VERBOSE);

if (!extraArguments.isEmpty()) {
builder.addAll(extraArguments);
Expand Down
Loading

0 comments on commit d18c4f2

Please sign in to comment.