Skip to content

Commit

Permalink
Add full kotlin configurations to kotlin rule (v2) (facebook#2526)
Browse files Browse the repository at this point in the history
* Add full kotlin configurations to kotlin rule

* Adding test for KotlinConfiguredComilerFactory

* Fixing pmd issue on setup method

* Renaming remaining references to extra_kotlinc_arguments to free_compiler_args

* Adding license info to new test file

Co-authored-by: Zac Sweers <pandanomic@gmail.com>
  • Loading branch information
tyvsmith and ZacSweers authored Aug 25, 2020
1 parent a68ef0d commit 1c601fd
Show file tree
Hide file tree
Showing 11 changed files with 376 additions and 35 deletions.
2 changes: 1 addition & 1 deletion docs/rule/android_library.soy
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ compiled class files and resources.
{/call}

{call buck.arg}
{param name: 'extra_kotlinc_arguments' /}
{param name: 'free_compiler_args' /}
{param default : '[]' /}
{param desc}
List of additional arguments to pass into the Kotlin compiler.
Expand Down
107 changes: 103 additions & 4 deletions docs/rule/kotlin_library.soy
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ the <code>resources</code> argument.
Kotlin compiler plugins</a> to use when compiling this library.
This takes a list of source paths, each of which will be prefixed
with <code>-Xplugin=</code> and passed as extra arguments to the compiler.
Unlike <code>extra_kotlinc_arguments</code>, these can be <em>source paths</em>,
not just strings (though <code>extra_kotlinc_arguments</code> should be used
Unlike <code>free_compiler_args</code>, these can be <em>source paths</em>,
not just strings (though <code>free_compiler_args</code> should be used
to specify plugin compiler options with <code>-P</code>).
<p>
For example, if you want to use{sp}
Expand Down Expand Up @@ -115,10 +115,109 @@ remote_file(
{/call}

{call buck.arg}
{param name: 'extra_kotlinc_arguments' /}
{param name: 'free_compiler_args' /}
{param default: '[]' /}
{param desc}
List of additional arguments to pass into the Kotlin compiler.
A list of additional compiler arguments.
{/param}
{/call}

{call buck.arg}
{param name: 'all_warnings_as_errors' /}
{param default: 'false' /}
{param desc}
Report an error if there are any warnings.
{/param}
{/call}

{call buck.arg}
{param name: 'suppress_warnings' /}
{param default: 'false' /}
{param desc}
Generate no warnings.
{/param}
{/call}

{call buck.arg}
{param name: 'verbose' /}
{param default: 'false' /}
{param desc}
Enable verbose logging output.
{/param}
{/call}

{call buck.arg}
{param name: 'include_runtime' /}
{param default: 'false' /}
{param desc}
Include Kotlin runtime in to resulting .jar
{/param}
{/call}

{call buck.arg}
{param name: 'jvm_target' /}
{param default: '1.6' /}
{param desc}
Target version of the generated JVM bytecode (1.6 or 1.8), default is 1.6
Possible values: "1.6", "1.8"
{/param}
{/call}

{call buck.arg}
{param name: 'jdk_home' /}
{param default: 'None' /}
{param desc}
Path to JDK home directory to include into classpath, if differs from default JAVA_HOME
{/param}
{/call}

{call buck.arg}
{param name: 'no_jdk' /}
{param default: 'false' /}
{param desc}
Don't include Java runtime into classpath.
{/param}
{/call}

{call buck.arg}
{param name: 'no_stdlib' /}
{param default: 'true' /}
{param desc}
Don't include kotlin-stdlib.jar or kotlin-reflect.jar into classpath.
{/param}
{/call}

{call buck.arg}
{param name: 'no_reflect' /}
{param default: 'true' /}
{param desc}
Don't include kotlin-reflect.jar into classpath.
{/param}
{/call}

{call buck.arg}
{param name: 'java_parameters' /}
{param default: 'false' /}
{param desc}
Generate metadata for Java 1.8 reflection on method parameters.
{/param}
{/call}

{call buck.arg}
{param name: 'api_version' /}
{param default: 'None' /}
{param desc}
Allow to use declarations only from the specified version of bundled libraries.
Possible values: "1.0", "1.1", "1.2", "1.3", "1.4 (EXPERIMENTAL)".
{/param}
{/call}

{call buck.arg}
{param name: 'language_version' /}
{param default: 'None' /}
{param desc}
Provide source compatibility with specified language version.
Possible values: "1.0", "1.1", "1.2", "1.3", "1.4 (EXPERIMENTAL)".
{/param}
{/call}

Expand Down
2 changes: 1 addition & 1 deletion docs/rule/robolectric_test.soy
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ with Robolectric test runner. It extends from <code>java_test()</code> rule.
{call test_common.contacts_arg /}

{call buck.arg}
{param name: 'extra_kotlinc_arguments' /}
{param name: 'free_compiler_args' /}
{param default : '[]' /}
{param desc}
List of additional arguments to pass into the Kotlin compiler.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

package com.facebook.buck.jvm.kotlin;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.util.Comparator.comparing;

import com.facebook.buck.core.model.BuildTarget;
import com.facebook.buck.core.model.TargetConfiguration;
import com.facebook.buck.core.rules.BuildRule;
Expand All @@ -34,11 +37,19 @@
import com.facebook.buck.jvm.kotlin.KotlinLibraryDescription.AnnotationProcessingTool;
import com.facebook.buck.jvm.kotlin.KotlinLibraryDescription.CoreArg;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Maps;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import javax.annotation.Nullable;

public class KotlinConfiguredCompilerFactory extends ConfiguredCompilerFactory {
Expand Down Expand Up @@ -81,7 +92,7 @@ public CompileToJarStepFactory configure(
kotlinBuckConfig.getKotlinc(),
kotlinBuckConfig.getKotlinHomeLibraries(),
pathToAbiGenerationPluginJar,
kotlinArgs.getExtraKotlincArguments(),
condenseCompilerArguments(kotlinArgs),
kotlinArgs.getKotlincPlugins(),
getFriendSourcePaths(buildRuleResolver, kotlinArgs.getFriendPaths(), kotlinBuckConfig),
kotlinArgs.getAnnotationProcessingTool().orElse(AnnotationProcessingTool.KAPT),
Expand Down Expand Up @@ -161,4 +172,64 @@ private static ImmutableList<SourcePath> getFriendSourcePaths(

return sourcePaths.build();
}

ImmutableList<String> condenseCompilerArguments(CoreArg kotlinArgs) {
ImmutableMap.Builder<String, Optional<String>> optionBuilder = ImmutableMap.builder();
LinkedHashMap<String, Optional<String>> freeArgs = Maps.newLinkedHashMap();
kotlinArgs.getFreeCompilerArgs()
.forEach(arg -> freeArgs.put(arg, Optional.empty()));
optionBuilder.putAll(freeArgs);

// Args from CommonToolArguments.kt and KotlinCommonToolOptions.kt
if (kotlinArgs.getAllWarningsAsErrors()) {
optionBuilder.put("-Werror", Optional.empty());
}
if (kotlinArgs.getSuppressWarnings()) {
optionBuilder.put("-nowarn", Optional.empty());
}
if (kotlinArgs.getVerbose()) {
optionBuilder.put("-verbose", Optional.empty());
}

// Args from K2JVMCompilerArguments.kt and KotlinJvmOptions.kt
optionBuilder.put("-jvm-target", Optional.of(kotlinArgs.getJvmTarget()));
if (kotlinArgs.getIncludeRuntime()) {
optionBuilder.put("-include-runtime", Optional.empty());
}
kotlinArgs.getJdkHome().ifPresent(jdkHome -> optionBuilder.put("-jdk-home", Optional.of(jdkHome)));
if (kotlinArgs.getNoJdk()) {
optionBuilder.put("-no-jdk", Optional.empty());
}
if (kotlinArgs.getNoStdlib()) {
optionBuilder.put("-no-stdlib", Optional.empty());
}
if (kotlinArgs.getNoReflect()) {
optionBuilder.put("-no-reflect", Optional.empty());
}
if (kotlinArgs.getJavaParameters()) {
optionBuilder.put("-java-parameters", Optional.empty());
}
kotlinArgs.getApiVersion().ifPresent(apiVersion -> optionBuilder.put("-api-version", Optional.of(apiVersion)));
kotlinArgs.getLanguageVersion().ifPresent(languageVersion -> optionBuilder.put("-language-version", Optional.of(languageVersion)));

// Return de-duping keys and sorting by them.
return optionBuilder.build()
.entrySet()
.stream()
.filter(distinctByKey(Map.Entry::getKey))
.sorted(comparing(Map.Entry::getKey, String.CASE_INSENSITIVE_ORDER))
.flatMap(entry -> {
if (entry.getValue().isPresent()) {
return ImmutableList.of(entry.getKey(), entry.getValue().get()).stream();
} else {
return ImmutableList.of(entry.getKey()).stream();
}
})
.collect(toImmutableList());
}

static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
}
96 changes: 95 additions & 1 deletion src/com/facebook/buck/jvm/kotlin/KotlinLibraryDescription.java
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,101 @@ public enum AnnotationProcessingTool {
}

public interface CoreArg extends JavaLibraryDescription.CoreArg {
ImmutableList<String> getExtraKotlincArguments();

/**
* A list of additional compiler arguments.
*/
ImmutableList<String> getFreeCompilerArgs();

/**
* Report an error if there are any warnings.
*/
@Value.Default
default boolean getAllWarningsAsErrors() {
return false;
}

/**
* Generate no warnings.
*/
@Value.Default
default boolean getSuppressWarnings() {
return false;
}

/**
* Enable verbose logging output.
*/
@Value.Default
default boolean getVerbose() {
return false;
}

/**
* Include Kotlin runtime in to resulting .jar
*/
@Value.Default
default boolean getIncludeRuntime() {
return false;
}

/**
* Target version of the generated JVM bytecode (1.6 or 1.8), default is 1.6
* Possible values: "1.6", "1.8"
*/
@Value.Default
default String getJvmTarget() {
return "1.6";
}

/**
* Path to JDK home directory to include into classpath, if differs from default JAVA_HOME
*/
Optional<String> getJdkHome();

/**
* Don't include Java runtime into classpath.
*/
@Value.Default
default boolean getNoJdk() {
return false;
}

/**
* Don't include kotlin-stdlib.jar or kotlin-reflect.jar into classpath.
*/
@Value.Default
default boolean getNoStdlib() {
return true;
}

/**
* Don't include kotlin-reflect.jar into classpath.
*/
@Value.Default
default boolean getNoReflect() {
return true;
}

/**
* Generate metadata for Java 1.8 reflection on method parameters.
*/
@Value.Default
default boolean getJavaParameters() {
return false;
}

/**
* Allow to use declarations only from the specified version of bundled libraries.
* Possible values: "1.0", "1.1", "1.2", "1.3", "1.4".
*/
Optional<String> getApiVersion();

/**
* Provide source compatibility with specified language version.
* Possible values: "1.0", "1.1", "1.2", "1.3", "1.4".
*/
Optional<String> getLanguageVersion();

Optional<AnnotationProcessingTool> getAnnotationProcessingTool();

Expand Down
Loading

0 comments on commit 1c601fd

Please sign in to comment.