diff --git a/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java b/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java index dd59d5c012f..77e7215e6ab 100644 --- a/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java +++ b/build-common/src/org/jetbrains/kotlin/compilerRunner/ArgumentUtils.java @@ -16,16 +16,16 @@ package org.jetbrains.kotlin.compilerRunner; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.Function; -import com.intellij.util.containers.ComparatorUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.cli.common.arguments.Argument; import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments; -import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument; +import org.jetbrains.kotlin.utils.StringsKt; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; public class ArgumentUtils { private ArgumentUtils() {} @@ -60,23 +60,17 @@ public class ArgumentUtils { continue; } - if (ComparatorUtil.equalsNullable(value, defaultValue)) continue; - - String name = getAlias(argument); - if (name == null) { - name = getName(argument, field); - } + if (Objects.equals(value, defaultValue)) continue; Class fieldType = field.getType(); if (fieldType.isArray()) { Object[] values = (Object[]) value; if (values.length == 0) continue; - //noinspection unchecked - value = StringUtil.join(values, Function.TO_STRING, argument.delimiter()); + value = StringsKt.join(Arrays.asList(values), ","); } - result.add(argument.prefix() + name); + result.add(argument.value()); if (fieldType == boolean.class || fieldType == Boolean.class) continue; @@ -88,14 +82,4 @@ public class ArgumentUtils { convertArgumentsToStringList(arguments, defaultArguments, superClazz, result); } } - - private static String getAlias(Argument argument) { - String alias = argument.alias(); - return alias.isEmpty() ? null : alias; - } - - private static String getName(Argument argument, Field field) { - String name = argument.value(); - return name.isEmpty() ? field.getName() : name; - } } diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java index 188ef22b440..d17dc7b00d7 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.cli.common.arguments; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument; import java.io.Serializable; import java.util.List; @@ -29,69 +28,78 @@ public abstract class CommonCompilerArguments implements Serializable { public static final String PLUGIN_OPTION_FORMAT = "plugin::="; @GradleOption(DefaultValues.LanguageVersions.class) - @Argument(value = "language-version", description = "Provide source compatibility with specified language version") - @ValueDescription("") + @Argument( + value = "-language-version", + valueDescription = "", + description = "Provide source compatibility with specified language version" + ) public String languageVersion; @GradleOption(DefaultValues.LanguageVersions.class) - @Argument(value = "api-version", description = "Allow to use declarations only from the specified version of bundled libraries") - @ValueDescription("") + @Argument( + value = "-api-version", + valueDescription = "", + description = "Allow to use declarations only from the specified version of bundled libraries" + ) public String apiVersion; @GradleOption(DefaultValues.BooleanFalseDefault.class) - @Argument(value = "nowarn", description = "Generate no warnings") + @Argument(value = "-nowarn", description = "Generate no warnings") public boolean suppressWarnings; @GradleOption(DefaultValues.BooleanFalseDefault.class) - @Argument(value = "verbose", description = "Enable verbose logging output") + @Argument(value = "-verbose", description = "Enable verbose logging output") public boolean verbose; - @Argument(value = "version", description = "Display compiler version") + @Argument(value = "-version", description = "Display compiler version") public boolean version; - @Argument(value = "help", alias = "h", description = "Print a synopsis of standard options") + @Argument(value = "-help", shortName = "-h", description = "Print a synopsis of standard options") public boolean help; - @Argument(value = "X", description = "Print a synopsis of advanced options") + @Argument(value = "-X", description = "Print a synopsis of advanced options") public boolean extraHelp; - @Argument(value = "Xno-inline", description = "Disable method inlining") + @Argument(value = "-P", valueDescription = PLUGIN_OPTION_FORMAT, description = "Pass an option to a plugin") + public String[] pluginOptions; + + // Advanced options + + @Argument(value = "-Xno-inline", description = "Disable method inlining") public boolean noInline; // TODO Remove in 1.0 - @Argument(value = "Xrepeat", description = "Repeat compilation (for performance analysis)") - @ValueDescription("") + @Argument( + value = "-Xrepeat", + valueDescription = "", + description = "Repeat compilation (for performance analysis)" + ) public String repeat; - @Argument(value = "Xskip-metadata-version-check", description = "Load classes with bad metadata version anyway (incl. pre-release classes)") + @Argument(value = "-Xskip-metadata-version-check", description = "Load classes with bad metadata version anyway (incl. pre-release classes)") public boolean skipMetadataVersionCheck; - @Argument(value = "Xallow-kotlin-package", description = "Allow compiling code in package 'kotlin'") + @Argument(value = "-Xallow-kotlin-package", description = "Allow compiling code in package 'kotlin'") public boolean allowKotlinPackage; - @Argument(value = "Xplugin", description = "Load plugins from the given classpath") - @ValueDescription("") + @Argument(value = "-Xplugin", valueDescription = "", description = "Load plugins from the given classpath") public String[] pluginClasspaths; - @Argument(value = "Xmulti-platform", description = "Enable experimental language support for multi-platform projects") + @Argument(value = "-Xmulti-platform", description = "Enable experimental language support for multi-platform projects") public boolean multiPlatform; - @Argument(value = "Xno-check-impl", description = "Do not check presence of 'impl' modifier in multi-platform projects") + @Argument(value = "-Xno-check-impl", description = "Do not check presence of 'impl' modifier in multi-platform projects") public boolean noCheckImpl; - @Argument(value = "Xcoroutines=warn") + @Argument(value = "-Xcoroutines=warn", description = "") public boolean coroutinesWarn; - @Argument(value = "Xcoroutines=error") + @Argument(value = "-Xcoroutines=error", description = "") public boolean coroutinesError; - @Argument(value = "Xcoroutines=enable") + @Argument(value = "-Xcoroutines=enable", description = "") public boolean coroutinesEnable; - @Argument(value = "P", description = "Pass an option to a plugin") - @ValueDescription(PLUGIN_OPTION_FORMAT) - public String[] pluginOptions; - public List freeArgs = new SmartList<>(); public List unknownExtraFlags = new SmartList<>(); diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.java index 00cbf9a3666..4713053bcb5 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.java +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.java @@ -17,8 +17,6 @@ package org.jetbrains.kotlin.cli.common.arguments; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument; import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.CALL; import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.NO_CALL; @@ -27,52 +25,61 @@ public class K2JSCompilerArguments extends CommonCompilerArguments { public static final long serialVersionUID = 0L; @GradleOption(DefaultValues.StringNullDefault.class) - @Argument(value = "output", description = "Output file path") - @ValueDescription("") + @Argument(value = "-output", valueDescription = "", description = "Output file path") public String outputFile; @GradleOption(DefaultValues.BooleanTrueDefault.class) - @Argument(value = "no-stdlib", description = "Don't use bundled Kotlin stdlib") + @Argument(value = "-no-stdlib", description = "Don't use bundled Kotlin stdlib") public boolean noStdlib; - @Argument(value = "libraries", description = "Paths to Kotlin libraries with .meta.js and .kjsm files, separated by system file separator") - @ValueDescription("") + @Argument( + value = "-libraries", + valueDescription = "", + description = "Paths to Kotlin libraries with .meta.js and .kjsm files, separated by system file separator") public String libraries; @GradleOption(DefaultValues.BooleanFalseDefault.class) - @Argument(value = "source-map", description = "Generate source map") + @Argument(value = "-source-map", description = "Generate source map") public boolean sourceMap; @GradleOption(DefaultValues.BooleanTrueDefault.class) - @Argument(value = "meta-info", description = "Generate .meta.js and .kjsm files with metadata. Use to create a library") + @Argument(value = "-meta-info", description = "Generate .meta.js and .kjsm files with metadata. Use to create a library") public boolean metaInfo; @GradleOption(DefaultValues.JsEcmaVersions.class) - @Argument(value = "target", description = "Generate JS files for specific ECMA version") - @ValueDescription("{ v5 }") + @Argument(value = "-target", valueDescription = "{ v5 }", description = "Generate JS files for specific ECMA version") public String target; @GradleOption(DefaultValues.JsModuleKinds.class) - @Argument(value = "module-kind", description = "Kind of a module generated by compiler") - @ValueDescription("{ plain, amd, commonjs, umd }") + @Argument( + value = "-module-kind", + valueDescription = "{ plain, amd, commonjs, umd }", + description = "Kind of a module generated by compiler" + ) public String moduleKind; @GradleOption(DefaultValues.JsMain.class) - @Nullable - @Argument(value = "main", description = "Whether a main function should be called") - @ValueDescription("{" + CALL + "," + NO_CALL + "}") + @Argument(value = "-main", valueDescription = "{" + CALL + "," + NO_CALL + "}", description = "Whether a main function should be called") public String main; - @Argument(value = "output-prefix", description = "Path to file which will be added to the beginning of output file") - @ValueDescription("") + @Argument( + value = "-output-prefix", + valueDescription = "", + description = "Path to file which will be added to the beginning of output file" + ) public String outputPrefix; - @Argument(value = "output-postfix", description = "Path to file which will be added to the end of output file") - @ValueDescription("") + @Argument( + value = "-output-postfix", + valueDescription = "", + description = "Path to file which will be added to the end of output file" + ) public String outputPostfix; + // Advanced options + @GradleOption(DefaultValues.BooleanFalseDefault.class) - @Argument(value = "Xtypedarrays", description = "Translate primitive arrays to JS typed arrays") + @Argument(value = "-Xtypedarrays", description = "Translate primitive arrays to JS typed arrays") public boolean typedArrays; @NotNull diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java index eaa71c125a9..36645f3d8b7 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java @@ -17,102 +17,117 @@ package org.jetbrains.kotlin.cli.common.arguments; import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument; import org.jetbrains.kotlin.config.JvmTarget; public class K2JVMCompilerArguments extends CommonCompilerArguments { public static final long serialVersionUID = 0L; - @Argument(value = "d", description = "Destination for generated class files") - @ValueDescription("") + @Argument(value = "-d", valueDescription = "", description = "Destination for generated class files") public String destination; - @Argument(value = "classpath", alias = "cp", description = "Paths where to find user class files") - @ValueDescription("") + @Argument(value = "-classpath", shortName = "-cp", valueDescription = "", description = "Paths where to find user class files") public String classpath; @GradleOption(DefaultValues.BooleanFalseDefault.class) - @Argument(value = "include-runtime", description = "Include Kotlin runtime in to resulting .jar") + @Argument(value = "-include-runtime", description = "Include Kotlin runtime in to resulting .jar") public boolean includeRuntime; @GradleOption(DefaultValues.StringNullDefault.class) - @Argument(value = "jdk-home", description = "Path to JDK home directory to include into classpath, if differs from default JAVA_HOME") - @ValueDescription("") + @Argument( + value = "-jdk-home", + valueDescription = "", + description = "Path to JDK home directory to include into classpath, if differs from default JAVA_HOME" + ) public String jdkHome; @GradleOption(DefaultValues.BooleanFalseDefault.class) - @Argument(value = "no-jdk", description = "Don't include Java runtime into classpath") + @Argument(value = "-no-jdk", description = "Don't include Java runtime into classpath") public boolean noJdk; @GradleOption(DefaultValues.BooleanTrueDefault.class) - @Argument(value = "no-stdlib", description = "Don't include Kotlin runtime into classpath") + @Argument(value = "-no-stdlib", description = "Don't include Kotlin runtime into classpath") public boolean noStdlib; @GradleOption(DefaultValues.BooleanTrueDefault.class) - @Argument(value = "no-reflect", description = "Don't include Kotlin reflection implementation into classpath") + @Argument(value = "-no-reflect", description = "Don't include Kotlin reflection implementation into classpath") public boolean noReflect; - @Argument(value = "module", description = "Path to the module file to compile") - @ValueDescription("") + @Argument(value = "-module", valueDescription = "", description = "Path to the module file to compile") public String module; - @Argument(value = "script", description = "Evaluate the script file") + @Argument(value = "-script", description = "Evaluate the script file") public boolean script; - @Argument(value = "script-templates", description = "Script definition template classes") - @ValueDescription("") + @Argument( + value = "-script-templates", + valueDescription = "", + description = "Script definition template classes" + ) public String[] scriptTemplates; - @Argument(value = "kotlin-home", description = "Path to Kotlin compiler home directory, used for runtime libraries discovery") - @ValueDescription("") + @Argument( + value = "-kotlin-home", + valueDescription = "", + description = "Path to Kotlin compiler home directory, used for runtime libraries discovery" + ) public String kotlinHome; - @Argument(value = "module-name", description = "Module name") + @Argument(value = "-module-name", description = "Module name") public String moduleName; @GradleOption(DefaultValues.JvmTargetVersions.class) - @Argument(value = "jvm-target", description = "Target version of the generated JVM bytecode (1.6 or 1.8), default is 1.6") - @ValueDescription("") + @Argument( + value = "-jvm-target", + valueDescription = "", + description = "Target version of the generated JVM bytecode (1.6 or 1.8), default is 1.6" + ) public String jvmTarget; @GradleOption(DefaultValues.BooleanFalseDefault.class) - @Argument(value = "java-parameters", description = "Generate metadata for Java 1.8 reflection on method parameters") + @Argument(value = "-java-parameters", description = "Generate metadata for Java 1.8 reflection on method parameters") public boolean javaParameters; // Advanced options - @Argument(value = "Xno-call-assertions", description = "Don't generate not-null assertion after each invocation of method returning not-null") + + @Argument(value = "-Xno-call-assertions", description = "Don't generate not-null assertion after each invocation of method returning not-null") public boolean noCallAssertions; - @Argument(value = "Xno-param-assertions", description = "Don't generate not-null assertions on parameters of methods accessible from Java") + @Argument(value = "-Xno-param-assertions", description = "Don't generate not-null assertions on parameters of methods accessible from Java") public boolean noParamAssertions; - @Argument(value = "Xno-optimize", description = "Disable optimizations") + @Argument(value = "-Xno-optimize", description = "Disable optimizations") public boolean noOptimize; - @Argument(value = "Xreport-perf", description = "Report detailed performance statistics") + @Argument(value = "-Xreport-perf", description = "Report detailed performance statistics") public boolean reportPerf; - @Argument(value = "Xmultifile-parts-inherit", description = "Compile multifile classes as a hierarchy of parts and facade") + @Argument(value = "-Xmultifile-parts-inherit", description = "Compile multifile classes as a hierarchy of parts and facade") public boolean inheritMultifileParts; - @Argument(value = "Xskip-runtime-version-check", description = "Allow Kotlin runtime libraries of incompatible versions in the classpath") + @Argument(value = "-Xskip-runtime-version-check", description = "Allow Kotlin runtime libraries of incompatible versions in the classpath") public boolean skipRuntimeVersionCheck; - @Argument(value = "Xdump-declarations-to", description = "Path to JSON file to dump Java to Kotlin declaration mappings") - @ValueDescription("") + @Argument( + value = "-Xdump-declarations-to", + valueDescription = "", + description = "Path to JSON file to dump Java to Kotlin declaration mappings" + ) public String declarationsOutputPath; - @Argument(value = "Xsingle-module", description = "Combine modules for source files and binary dependencies into a single module") + @Argument(value = "-Xsingle-module", description = "Combine modules for source files and binary dependencies into a single module") public boolean singleModule; - @Argument(value = "Xadd-compiler-builtins", description = "Add definitions of built-in declarations to the compilation classpath (useful with -no-stdlib)") + @Argument(value = "-Xadd-compiler-builtins", description = "Add definitions of built-in declarations to the compilation classpath (useful with -no-stdlib)") public boolean addCompilerBuiltIns; - @Argument(value = "Xload-builtins-from-dependencies", description = "Load definitions of built-in declarations from module dependencies, instead of from the compiler") + @Argument(value = "-Xload-builtins-from-dependencies", description = "Load definitions of built-in declarations from module dependencies, instead of from the compiler") public boolean loadBuiltInsFromDependencies; - @Argument(value = "Xscript-resolver-environment", description = "Script resolver environment in key-value pairs (the value could be quoted and escaped)") - @ValueDescription("") + @Argument( + value = "-Xscript-resolver-environment", + valueDescription = "", + description = "Script resolver environment in key-value pairs (the value could be quoted and escaped)" + ) public String[] scriptResolverEnvironment; // Paths to output directories for friend modules. diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.java index 18e5d383bb4..3583f38078b 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.java +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.java @@ -16,16 +16,17 @@ package org.jetbrains.kotlin.cli.common.arguments; -import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument; - public class K2MetadataCompilerArguments extends CommonCompilerArguments { public static final long serialVersionUID = 0L; - @Argument(value = "d", description = "Destination for generated .kotlin_metadata files") - @ValueDescription("") + @Argument(value = "-d", valueDescription = "", description = "Destination for generated .kotlin_metadata files") public String destination; - @Argument(value = "classpath", alias = "cp", description = "Paths where to find library .kotlin_metadata files") - @ValueDescription("") + @Argument( + value = "-classpath", + shortName = "-cp", + valueDescription = "", + description = "Paths where to find library .kotlin_metadata files" + ) public String classpath; } diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/ValueDescription.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/ValueDescription.java deleted file mode 100644 index a6504ec3572..00000000000 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/ValueDescription.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * 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 org.jetbrains.kotlin.cli.common.arguments; - -import org.jetbrains.annotations.NotNull; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -public @interface ValueDescription { - @NotNull - String value(); -} diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/argumentUtils.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/argumentUtils.kt index f7f4d240ccb..5fd114331cd 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/argumentUtils.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/argumentUtils.kt @@ -16,14 +16,13 @@ package org.jetbrains.kotlin.cli.common.arguments -import com.intellij.util.xmlb.XmlSerializerUtil -import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Args import java.lang.reflect.Field import java.lang.reflect.Modifier import java.util.* -@JvmOverloads fun parseArguments(args: Array, arguments: A, ignoreInvalidArguments: Boolean = false) { - val unparsedArgs = Args.parse(arguments, args, false) +@JvmOverloads +fun parseArguments(args: Array, arguments: A, ignoreInvalidArguments: Boolean = false) { + val unparsedArgs = parseCommandLineArguments(args, arguments) val (unknownExtraArgs, unknownArgs) = unparsedArgs.partition { it.startsWith("-X") } arguments.unknownExtraFlags = unknownExtraArgs arguments.freeArgs = if (ignoreInvalidArguments) unknownArgs.filterNot { it.startsWith("-") } else unknownArgs diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/parseCommandLineArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/parseCommandLineArguments.kt new file mode 100644 index 00000000000..92bb839b30b --- /dev/null +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/parseCommandLineArguments.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * 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 org.jetbrains.kotlin.cli.common.arguments + +import java.lang.reflect.Field + +annotation class Argument( + val value: String, + val shortName: String = "", + val valueDescription: String = "", + val description: String +) + +val Argument.isAdvanced: Boolean + get() = value.startsWith("-X") && value.length > 2 + +fun parseCommandLineArguments(args: Array, result: A): List { + data class ArgumentField(val field: Field, val argumentNames: List) + + val fields = result::class.java.fields.mapNotNull { field -> + val argument = field.getAnnotation(Argument::class.java) + if (argument != null) + ArgumentField(field, listOfNotNull(argument.value, argument.shortName.takeUnless(String::isEmpty))) + else null + } + + val freeArgs = mutableListOf() + var i = 0 + while (i < args.size) { + val arg = args[i++] + val field = fields.firstOrNull { (_, names) -> arg in names }?.field + if (field == null) { + freeArgs.add(arg) + continue + } + + val value: Any = + if (field.type == Boolean::class.java) true + else { + if (i == args.size) { + throw IllegalArgumentException("No value passed for argument $arg") + } + args[i++] + } + + updateField(field, result, value) + } + + return freeArgs +} + +private fun updateField(field: Field, result: A, value: Any) { + when (field.type) { + Boolean::class.java, String::class.java -> field.set(result, value) + Array::class.java -> { + val newElements = (value as String).split(",").toTypedArray() + @Suppress("UNCHECKED_CAST") + val oldValue = field.get(result) as Array? + field.set(result, if (oldValue != null) arrayOf(*oldValue, *newElements) else newElements) + } + else -> throw IllegalStateException("Unsupported argument type: ${field.type}") + } +} diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/Args.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/Args.java deleted file mode 100644 index 76514cff32a..00000000000 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/Args.java +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Copyright (c) 2005, Sam Pullara. All Rights Reserved. - * You may modify and redistribute as long as this attribution remains. - */ - -package org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli; - - -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.io.PrintStream; -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -public class Args { - - /** - * {@link ValueCreator} building object using a one arg constructor taking a {@link String} object as parameter - */ - public static final ValueCreator FROM_STRING_CONSTRUCTOR = new ValueCreator() { - public Object createValue(Class type, String value) { - Object v = null; - try { - Constructor init = type.getDeclaredConstructor(String.class); - v = init.newInstance(value); - } catch (NoSuchMethodException e) { - // ignore - } catch (Exception e) { - throw new IllegalArgumentException("Failed to convert " + value + " to type " + type.getName(), e); - } - return v; - } - }; - public static final ValueCreator ENUM_CREATOR = new ValueCreator() { - @SuppressWarnings({"unchecked", "rawtypes"}) - public Object createValue(Class type, String value) { - if (Enum.class.isAssignableFrom(type)) { - return Enum.valueOf(type, value); - } - return null; - } - }; - private static final List DEFAULT_VALUE_CREATORS = Arrays.asList(Args.FROM_STRING_CONSTRUCTOR, Args.ENUM_CREATOR); - private static List valueCreators = new ArrayList(DEFAULT_VALUE_CREATORS); - - /** - * A convenience method for parsing and automatically producing error messages. - * - * @param target Either an instance or a class - * @param args The arguments you want to parse and populate - * @return The list of arguments that were not consumed - */ - public static List parseOrExit(Object target, String[] args) { - try { - return parse(target, args); - } catch (IllegalArgumentException e) { - System.err.println(e.getMessage()); - Args.usage(target); - System.exit(1); - throw e; - } - } - - public static List parse(Object target, String[] args) { - return parse(target, args, true); - } - - /** - * Parse a set of arguments and populate the target with the appropriate values. - * - * @param target - * Either an instance or a class - * @param args - * The arguments you want to parse and populate - * @param failOnExtraFlags - * Throw an IllegalArgumentException if extra flags are present - * @return The list of arguments that were not consumed - */ - public static List parse(Object target, String[] args, boolean failOnExtraFlags) { - List arguments = new ArrayList(); - arguments.addAll(Arrays.asList(args)); - Class clazz; - if (target instanceof Class) { - clazz = (Class) target; - } else { - clazz = target.getClass(); - try { - BeanInfo info = Introspector.getBeanInfo(clazz); - for (PropertyDescriptor pd : info.getPropertyDescriptors()) { - processProperty(target, pd, arguments); - } - } catch (IntrospectionException e) { - // If its not a JavaBean we ignore it - } - } - - // Check fields of 'target' class and its superclasses - for (Class currentClazz = clazz; currentClazz != null; currentClazz = currentClazz.getSuperclass()) { - for (Field field : currentClazz.getDeclaredFields()) { - processField(target, field, arguments); - } - } - - if (failOnExtraFlags) { - for (String argument : arguments) { - if (argument.startsWith("-")) { - throw new IllegalArgumentException("Invalid argument: " + argument); - } - } - } - return arguments; - } - - private static void processField(Object target, Field field, List arguments) { - Argument argument = field.getAnnotation(Argument.class); - if (argument != null) { - boolean set = false; - for (Iterator i = arguments.iterator(); i.hasNext(); ) { - String arg = i.next(); - String prefix = argument.prefix(); - String delimiter = argument.delimiter(); - if (arg.startsWith(prefix)) { - Object value; - String name = getName(argument, field); - String alias = getAlias(argument); - arg = arg.substring(prefix.length()); - Class type = field.getType(); - if (arg.equals(name) || (alias != null && arg.equals(alias))) { - i.remove(); - value = consumeArgumentValue(type, argument, i); - if (!set) { - setField(type, field, target, value, delimiter); - } else { - addArgument(type, field, target, value, delimiter); - } - set = true; - } - if (set && !type.isArray()) break; - } - } - if (!set && argument.required()) { - String name = getName(argument, field); - throw new IllegalArgumentException("You must set argument " + name); - } - } - } - - private static void addArgument(Class type, Field field, Object target, Object value, String delimiter) { - try { - Object[] os = (Object[]) field.get(target); - Object[] vs = (Object[]) getValue(type, value, delimiter); - Object[] s = (Object[]) Array.newInstance(type.getComponentType(), os.length + vs.length); - System.arraycopy(os, 0, s, 0, os.length); - System.arraycopy(vs, 0, s, os.length, vs.length); - field.set(target, s); - } catch (IllegalAccessException iae) { - throw new IllegalArgumentException("Could not set field " + field, iae); - } catch (NoSuchMethodException e) { - throw new IllegalArgumentException("Could not find constructor in class " + type.getName() + " that takes a string", e); - } - } - - private static void addPropertyArgument(Class type, PropertyDescriptor property, Object target, Object value, String delimiter) { - try { - Object[] os = (Object[]) property.getReadMethod().invoke(target); - Object[] vs = (Object[]) getValue(type, value, delimiter); - Object[] s = (Object[]) Array.newInstance(type.getComponentType(), os.length + vs.length); - System.arraycopy(os, 0, s, 0, os.length); - System.arraycopy(vs, 0, s, os.length, vs.length); - property.getWriteMethod().invoke(target, (Object) s); - } catch (IllegalAccessException iae) { - throw new IllegalArgumentException("Could not set property " + property, iae); - } catch (NoSuchMethodException e) { - throw new IllegalArgumentException("Could not find constructor in class " + type.getName() + " that takes a string", e); - } catch (InvocationTargetException e) { - throw new IllegalArgumentException("Failed to validate argument " + value + " for " + property); - } - } - - private static void processProperty(Object target, PropertyDescriptor property, List arguments) { - Method writeMethod = property.getWriteMethod(); - if (writeMethod != null) { - Argument argument = writeMethod.getAnnotation(Argument.class); - if (argument != null) { - boolean set = false; - for (Iterator i = arguments.iterator(); i.hasNext(); ) { - String arg = i.next(); - String prefix = argument.prefix(); - String delimiter = argument.delimiter(); - if (arg.startsWith(prefix)) { - Object value; - String name = getName(argument, property); - String alias = getAlias(argument); - arg = arg.substring(prefix.length()); - Class type = property.getPropertyType(); - if (arg.equals(name) || (alias != null && arg.equals(alias))) { - i.remove(); - value = consumeArgumentValue(type, argument, i); - if (!set) { - setProperty(type, property, target, value, delimiter); - } else { - addPropertyArgument(type, property, target, value, delimiter); - } - set = true; - } - if (set && !type.isArray()) break; - } - } - if (!set && argument.required()) { - String name = getName(argument, property); - throw new IllegalArgumentException("You must set argument " + name); - } - } - } - } - - /** - * Generate usage information based on the target annotations. - * - * @param target An instance or class. - */ - public static void usage(Object target) { - usage(System.err, target); - } - - /** - * Generate usage information based on the target annotations. - * - * @param errStream A {@link java.io.PrintStream} to print the usage information to. - * @param target An instance or class. - */ - public static void usage(PrintStream errStream, Object target) { - Class clazz; - if (target instanceof Class) { - clazz = (Class) target; - } else { - clazz = target.getClass(); - } - errStream.println("Usage: " + clazz.getName()); - for (Class currentClazz = clazz; currentClazz != null; currentClazz = currentClazz.getSuperclass()) { - for (Field field : currentClazz.getDeclaredFields()) { - fieldUsage(errStream, target, field); - } - } - try { - BeanInfo info = Introspector.getBeanInfo(clazz); - for (PropertyDescriptor pd : info.getPropertyDescriptors()) { - propertyUsage(errStream, target, pd); - } - } catch (IntrospectionException e) { - // If its not a JavaBean we ignore it - } - } - - private static void fieldUsage(PrintStream errStream, Object target, Field field) { - Argument argument = field.getAnnotation(Argument.class); - if (argument != null) { - String name = getName(argument, field); - String alias = getAlias(argument); - String prefix = argument.prefix(); - String delimiter = argument.delimiter(); - String description = argument.description(); - makeAccessible(field); - try { - Object defaultValue = field.get(target); - Class type = field.getType(); - propertyUsage(errStream, prefix, name, alias, type, delimiter, description, defaultValue); - } catch (IllegalAccessException e) { - throw new IllegalArgumentException("Could not use thie field " + field + " as an argument field", e); - } - } - } - - private static void propertyUsage(PrintStream errStream, Object target, PropertyDescriptor field) { - Method writeMethod = field.getWriteMethod(); - if (writeMethod != null) { - Argument argument = writeMethod.getAnnotation(Argument.class); - if (argument != null) { - String name = getName(argument, field); - String alias = getAlias(argument); - String prefix = argument.prefix(); - String delimiter = argument.delimiter(); - String description = argument.description(); - try { - Method readMethod = field.getReadMethod(); - Object defaultValue; - if (readMethod == null) { - defaultValue = null; - } else { - defaultValue = readMethod.invoke(target, (Object[]) null); - } - Class type = field.getPropertyType(); - propertyUsage(errStream, prefix, name, alias, type, delimiter, description, defaultValue); - } catch (IllegalAccessException e) { - throw new IllegalArgumentException("Could not use thie field " + field + " as an argument field", e); - } catch (InvocationTargetException e) { - throw new IllegalArgumentException("Could not get default value for " + field, e); - } - } - } - - } - - private static void propertyUsage(PrintStream errStream, String prefix, String name, String alias, Class type, String delimiter, String description, Object defaultValue) { - StringBuilder sb = new StringBuilder(" "); - sb.append(prefix); - sb.append(name); - if (alias != null) { - sb.append(" ("); - sb.append(prefix); - sb.append(alias); - sb.append(")"); - } - if (type == Boolean.TYPE || type == Boolean.class) { - sb.append(" [flag] "); - sb.append(description); - } else { - sb.append(" ["); - if (type.isArray()) { - String typeName = getTypeName(type.getComponentType()); - sb.append(typeName); - sb.append("["); - sb.append(delimiter); - sb.append("]"); - } else { - String typeName = getTypeName(type); - sb.append(typeName); - } - sb.append("] "); - sb.append(description); - if (defaultValue != null) { - sb.append(" ("); - if (type.isArray()) { - List list = new ArrayList(); - int len = Array.getLength(defaultValue); - for (int i = 0; i < len; i++) { - list.add(Array.get(defaultValue, i)); - } - sb.append(list); - } else { - sb.append(defaultValue); - } - sb.append(")"); - } - - } - errStream.println(sb); - } - - private static String getTypeName(Class type) { - String typeName = type.getName(); - int beginIndex = typeName.lastIndexOf("."); - typeName = typeName.substring(beginIndex + 1); - return typeName; - } - - static String getName(Argument argument, PropertyDescriptor property) { - String name = argument.value(); - if (name.equals("")) { - name = property.getName(); - } - return name; - - } - - private static Object consumeArgumentValue(Class type, Argument argument, Iterator i) { - Object value; - if (type == Boolean.TYPE || type == Boolean.class) { - value = true; - } else { - if (i.hasNext()) { - value = i.next(); - i.remove(); - } else { - throw new IllegalArgumentException("Must have a value for non-boolean argument " + argument.value()); - } - } - return value; - } - - static void setProperty(Class type, PropertyDescriptor property, Object target, Object value, String delimiter) { - try { - value = getValue(type, value, delimiter); - property.getWriteMethod().invoke(target, value); - } catch (IllegalAccessException iae) { - throw new IllegalArgumentException("Could not set property " + property, iae); - } catch (NoSuchMethodException e) { - throw new IllegalArgumentException("Could not find constructor in class " + type.getName() + " that takes a string", e); - } catch (InvocationTargetException e) { - throw new IllegalArgumentException("Failed to validate argument " + value + " for " + property); - } - } - - static String getAlias(Argument argument) { - String alias = argument.alias(); - if (alias.equals("")) { - alias = null; - } - return alias; - } - - static String getName(Argument argument, Field field) { - String name = argument.value(); - if (name.equals("")) { - name = field.getName(); - } - return name; - } - - static void setField(Class type, Field field, Object target, Object value, String delimiter) { - makeAccessible(field); - try { - value = getValue(type, value, delimiter); - field.set(target, value); - } catch (IllegalAccessException iae) { - throw new IllegalArgumentException("Could not set field " + field, iae); - } catch (NoSuchMethodException e) { - throw new IllegalArgumentException("Could not find constructor in class " + type.getName() + " that takes a string", e); - } - } - - private static Object getValue(Class type, Object value, String delimiter) throws NoSuchMethodException { - if (type != String.class && type != Boolean.class && type != Boolean.TYPE) { - String string = (String) value; - if (type.isArray()) { - String[] strings = string.split(delimiter); - type = type.getComponentType(); - if (type == String.class) { - value = strings; - } else { - Object[] array = (Object[]) Array.newInstance(type, strings.length); - for (int i = 0; i < array.length; i++) { - array[i] = createValue(type, strings[i]); - } - value = array; - } - } else { - value = createValue(type, string); - } - } - return value; - } - - private static Object createValue(Class type, String valueAsString) throws NoSuchMethodException { - for (ValueCreator valueCreator : valueCreators) { - Object createdValue = valueCreator.createValue(type, valueAsString); - if (createdValue != null) { - return createdValue; - } - } - throw new IllegalArgumentException(String.format("cannot instanciate any %s object using %s value", type.toString(), valueAsString)); - } - - private static void makeAccessible(AccessibleObject ao) { - if (ao instanceof Member) { - Member member = (Member) ao; - if (!Modifier.isPublic(member.getModifiers())) { - ao.setAccessible(true); - } - } - } - - /** - * Creates a {@link ValueCreator} object able to create object assignable from given type, - * using a static one arg method which name is the the given one taking a String object as parameter - * - * @param compatibleType the base assignable for which this object will try to invoke the given method - * @param methodName the name of the one arg method taking a String as parameter that will be used to built a new value - * @return null if the object could not be created, the value otherwise - */ - public static ValueCreator byStaticMethodInvocation(Class compatibleType, String methodName) { - return new ValueCreator() { - public Object createValue(Class type, String value) { - Object v = null; - if (compatibleType.isAssignableFrom(type)) { - try { - Method m = type.getMethod(methodName, String.class); - return m.invoke(null, value); - } catch (NoSuchMethodException e) { - // ignore - } catch (Exception e) { - throw new IllegalArgumentException(String.format("could not invoke %s#%s to create an obejct from %s", type.toString(), methodName, value)); - } - } - return v; - } - }; - } - - /** - * Allows external extension of the valiue creators. - * - * @param vc another value creator to take into account for trying to create values - */ - public static void registerValueCreator(ValueCreator vc) { - valueCreators.add(vc); - } - - /** - * Cleanup of registered ValueCreators (mainly for tests) - */ - public static void resetValueCreators() { - valueCreators.clear(); - valueCreators.addAll(DEFAULT_VALUE_CREATORS); - } - - public static interface ValueCreator { - /** - * Creates a value object of the given type using the given string value representation; - * - * @param type the type to create an instance of - * @param value the string represented value of the object to create - * @return null if the object could not be created, the value otherwise - */ - public Object createValue(Class type, String value); - } -} diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/Argument.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/Argument.java deleted file mode 100644 index 2149455966a..00000000000 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/Argument.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2005, Sam Pullara. All Rights Reserved. - * You may modify and redistribute as long as this attribution remains. - */ - -package org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Documented -@Retention(RetentionPolicy.RUNTIME) -public @interface Argument { - /** - * This is the actual command line argument itself - */ - String value() default ""; - /** - * If this is true, then the argument must be set or the parse will fail - */ - boolean required() default false; - - /** - * This is the prefix expected for the argument - */ - String prefix() default "-"; - /** - * Each argument can have an alias - */ - String alias() default ""; - /** - * A description of the argument that will appear in the usage method - */ - String description() default ""; - - /** - * A delimiter for arguments that are multi-valued. - */ - String delimiter() default ","; -} diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/PropertiesArgs.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/PropertiesArgs.java deleted file mode 100644 index 7816feb3776..00000000000 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/parser/com/sampullara/cli/PropertiesArgs.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2010-2017 JetBrains s.r.o. - * - * 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 org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli; - -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Properties; - -/** - * Created by IntelliJ IDEA. - *

- * User: samp - * Date: Nov 11, 2007 - * Time: 3:42:27 PM - */ -public class PropertiesArgs { - /** - * Parse properties instead of String arguments. Any additional arguments need to be passed some other way. - * This is often used in a second pass when the property filename is passed on the command line. Because of - * required properties you must be careful to set them all in the property file. - * - * @param target Either an instance or a class - * @param arguments The properties that contain the arguments - */ - public static void parse(Object target, Properties arguments) { - Class clazz; - if (target instanceof Class) { - clazz = (Class) target; - } else { - clazz = target.getClass(); - } - for (Field field : clazz.getDeclaredFields()) { - processField(target, field, arguments); - } - try { - BeanInfo info = Introspector.getBeanInfo(clazz); - for (PropertyDescriptor pd : info.getPropertyDescriptors()) { - processProperty(target, pd, arguments); - } - } catch (IntrospectionException e) { - // If its not a JavaBean we ignore it - } - } - - private static void processField(Object target, Field field, Properties arguments) { - Argument argument = field.getAnnotation(Argument.class); - if (argument != null) { - String name = Args.getName(argument, field); - String alias = Args.getAlias(argument); - Class type = field.getType(); - Object value = arguments.get(name); - if (value == null && alias != null) { - value = arguments.get(alias); - } - if (value != null) { - if (type == Boolean.TYPE || type == Boolean.class) { - value = true; - } - Args.setField(type, field, target, value, argument.delimiter()); - } else { - if (argument.required()) { - throw new IllegalArgumentException("You must set argument " + name); - } - } - } - } - - private static void processProperty(Object target, PropertyDescriptor property, Properties arguments) { - Method writeMethod = property.getWriteMethod(); - if (writeMethod != null) { - Argument argument = writeMethod.getAnnotation(Argument.class); - if (argument != null) { - String name = Args.getName(argument, property); - String alias = Args.getAlias(argument); - Object value = arguments.get(name); - if (value == null && alias != null) { - value = arguments.get(alias); - } - if (value != null) { - Class type = property.getPropertyType(); - if (type == Boolean.TYPE || type == Boolean.class) { - value = true; - } - Args.setProperty(type, property, target, value, argument.delimiter()); - } else { - if (argument.required()) { - throw new IllegalArgumentException("You must set argument " + name); - } - } - } - } - } -} diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java b/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java index ceb1ca6212d..d5ef56a4fd0 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java @@ -18,9 +18,9 @@ package org.jetbrains.kotlin.cli.common; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.cli.common.arguments.Argument; import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments; -import org.jetbrains.kotlin.cli.common.arguments.ValueDescription; -import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument; +import org.jetbrains.kotlin.cli.common.arguments.ParseCommandLineArgumentsKt; import java.io.PrintStream; import java.lang.reflect.Field; @@ -59,29 +59,24 @@ class Usage { Argument argument = field.getAnnotation(Argument.class); if (argument == null) return null; - ValueDescription description = field.getAnnotation(ValueDescription.class); - String argumentValue = argument.value(); // TODO: this is a dirty hack, provide better mechanism for keys that can have several values boolean isXCoroutinesKey = argumentValue.contains("Xcoroutines"); - String value = isXCoroutinesKey ? "Xcoroutines={enable|warn|error}" : argument.value(); - boolean extraOption = value.startsWith("X") && value.length() > 1; - if (extraHelp != extraOption) return null; - - String prefix = argument.prefix(); + String value = isXCoroutinesKey ? "-Xcoroutines={enable|warn|error}" : argumentValue; + if (extraHelp != ParseCommandLineArgumentsKt.isAdvanced(argument)) return null; StringBuilder sb = new StringBuilder(" "); - sb.append(prefix); sb.append(value); - if (!argument.alias().isEmpty()) { + + if (!argument.shortName().isEmpty()) { sb.append(" ("); - sb.append(prefix); - sb.append(argument.alias()); + sb.append(argument.shortName()); sb.append(")"); } - if (description != null) { + + if (!argument.valueDescription().isEmpty()) { sb.append(" "); - sb.append(description.value()); + sb.append(argument.valueDescription()); } if (isXCoroutinesKey) { diff --git a/generators/src/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt b/generators/src/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt index 4aa2db321c1..df28004acbf 100644 --- a/generators/src/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt +++ b/generators/src/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt @@ -17,20 +17,19 @@ package org.jetbrains.kotlin.generators.arguments import org.jetbrains.kotlin.cli.common.arguments.* -import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.utils.Printer import java.io.File import java.io.PrintStream import kotlin.reflect.KAnnotatedElement import kotlin.reflect.KProperty1 -import kotlin.reflect.declaredMemberProperties +import kotlin.reflect.full.declaredMemberProperties // Additional properties that should be included in interface @Suppress("unused") interface AdditionalGradleProperties { @GradleOption(EmptyList::class) - @Argument(description = "A list of additional compiler arguments") + @Argument(value = "", description = "A list of additional compiler arguments") var freeCompilerArgs: List object EmptyList : DefaultValues("emptyList()") diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt index fd3d51d1e3b..8d9f30ce0ea 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt @@ -23,8 +23,8 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ProjectFileIndex import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.cli.common.arguments.Argument import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder @@ -40,7 +40,7 @@ val KtElement.builtIns: KotlinBuiltIns get() = getResolutionFacade().moduleDescriptor.builtIns private val multiPlatformProjectsArg: String by lazy { - "-" + CommonCompilerArguments::multiPlatform.annotations.filterIsInstance().single().value + CommonCompilerArguments::multiPlatform.annotations.filterIsInstance().single().value } fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion { diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt index 66171d1bbf9..c92a8c595e8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt @@ -26,7 +26,6 @@ import com.intellij.ui.HoverHyperlinkLabel import com.intellij.util.ui.FormBuilder import com.intellij.util.ui.ThreeStateCheckBox import org.jetbrains.kotlin.cli.common.arguments.* -import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.idea.compiler.configuration.* import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull @@ -199,7 +198,7 @@ class KotlinFacetEditorGeneralTab( if (additionalValue != field[emptyArguments]) { val argumentInfo = field.annotations.firstIsInstanceOrNull() ?: continue val addTo = if (additionalValue != field[primaryArguments]) overridingArguments else redundantArguments - addTo += "" + argumentInfo.value + "" + addTo += "" + argumentInfo.value.first() + "" } } if (overridingArguments.isNotEmpty() || redundantArguments.isNotEmpty()) { diff --git a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt index 3f6c5c627fc..12e8c991e85 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt @@ -30,8 +30,6 @@ import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VfsUtil import com.intellij.testFramework.PsiTestUtil -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument import org.jetbrains.kotlin.config.CompilerSettings import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider import org.jetbrains.kotlin.config.TargetPlatformKind @@ -105,13 +103,8 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() { protected fun Module.enableMultiPlatform() { createFacet() val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this) - val compilerSettings = CompilerSettings() - compilerSettings.additionalArguments += " -$multiPlatformArg" - facetSettings.compilerSettings = compilerSettings + facetSettings.compilerSettings = CompilerSettings().apply { + additionalArguments += " -Xmulti-platform" + } } - - companion object { - private val multiPlatformArg = CommonCompilerArguments::multiPlatform.annotations.filterIsInstance().single().value - } - -} \ No newline at end of file +}