Show plugin usage on invalid arguments
This commit is contained in:
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.cli.common.modules.ModuleScriptData;
|
|||||||
import org.jetbrains.kotlin.cli.jvm.compiler.*;
|
import org.jetbrains.kotlin.cli.jvm.compiler.*;
|
||||||
import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal;
|
import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal;
|
||||||
import org.jetbrains.kotlin.codegen.CompilationException;
|
import org.jetbrains.kotlin.codegen.CompilationException;
|
||||||
import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException;
|
import org.jetbrains.kotlin.compiler.plugin.*;
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||||
import org.jetbrains.kotlin.config.Services;
|
import org.jetbrains.kotlin.config.Services;
|
||||||
@@ -94,6 +94,11 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
|
|||||||
try {
|
try {
|
||||||
PluginCliParser.loadPlugins(arguments, configuration);
|
PluginCliParser.loadPlugins(arguments, configuration);
|
||||||
}
|
}
|
||||||
|
catch (PluginCliOptionProcessingException e) {
|
||||||
|
String message = e.getMessage() + "\n\n" + PluginPackage.cliPluginUsageString(e.getPluginId(), e.getOptions());
|
||||||
|
messageCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION);
|
||||||
|
return INTERNAL_ERROR;
|
||||||
|
}
|
||||||
catch (CliOptionProcessingException e) {
|
catch (CliOptionProcessingException e) {
|
||||||
messageCollector.report(CompilerMessageSeverity.ERROR, e.getMessage(), CompilerMessageLocation.NO_LOCATION);
|
messageCollector.report(CompilerMessageSeverity.ERROR, e.getMessage(), CompilerMessageLocation.NO_LOCATION);
|
||||||
return INTERNAL_ERROR;
|
return INTERNAL_ERROR;
|
||||||
|
|||||||
@@ -16,26 +16,21 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cli.jvm
|
package org.jetbrains.kotlin.cli.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
|
|
||||||
import kotlin.platform.*
|
import kotlin.platform.*
|
||||||
import java.util.jar.JarFile
|
import java.util.jar.JarFile
|
||||||
import java.util.jar.Attributes
|
import java.util.jar.Attributes
|
||||||
import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
|
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
import com.intellij.util.containers.MultiMap
|
import com.intellij.util.containers.MultiMap
|
||||||
import org.jetbrains.kotlin.compiler.plugin.CliOption
|
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
|
||||||
import java.util.ServiceLoader
|
import java.util.ServiceLoader
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.Enumeration
|
import java.util.Enumeration
|
||||||
import org.jetbrains.kotlin.compiler.plugin.parsePluginOption
|
|
||||||
import org.jetbrains.kotlin.compiler.plugin.CliOptionValue
|
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||||
import org.jetbrains.kotlin.utils.valuesToMap
|
import org.jetbrains.kotlin.utils.valuesToMap
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
|
import org.jetbrains.kotlin.compiler.plugin.*
|
||||||
|
|
||||||
|
|
||||||
public object PluginCliParser {
|
public object PluginCliParser {
|
||||||
@@ -85,10 +80,16 @@ public object PluginCliParser {
|
|||||||
for (option in processor.pluginOptions) {
|
for (option in processor.pluginOptions) {
|
||||||
val values = optionsToValues[option]
|
val values = optionsToValues[option]
|
||||||
if (option.required && values.isEmpty()) {
|
if (option.required && values.isEmpty()) {
|
||||||
throw CliOptionProcessingException("Required plugin option not present: ${processor.pluginId}:${option.name}")
|
throw PluginCliOptionProcessingException(
|
||||||
|
processor.pluginId,
|
||||||
|
processor.pluginOptions,
|
||||||
|
"Required plugin option not present: ${processor.pluginId}:${option.name}")
|
||||||
}
|
}
|
||||||
if (!option.allowMultipleOccurrences && values.size() > 1) {
|
if (!option.allowMultipleOccurrences && values.size() > 1) {
|
||||||
throw CliOptionProcessingException("Multiple values not allowed for plugin option ${processor.pluginId}:${option.name}")
|
throw PluginCliOptionProcessingException(
|
||||||
|
processor.pluginId,
|
||||||
|
processor.pluginOptions,
|
||||||
|
"Multiple values are not allowed for plugin option ${processor.pluginId}:${option.name}")
|
||||||
}
|
}
|
||||||
|
|
||||||
for (value in values) {
|
for (value in values) {
|
||||||
|
|||||||
@@ -26,7 +26,32 @@ public class CliOption(
|
|||||||
public val allowMultipleOccurrences: Boolean = false
|
public val allowMultipleOccurrences: Boolean = false
|
||||||
)
|
)
|
||||||
|
|
||||||
public class CliOptionProcessingException(message: String, cause: Throwable? = null): RuntimeException(message, cause)
|
public open class CliOptionProcessingException(message: String, cause: Throwable? = null): RuntimeException(message, cause)
|
||||||
|
|
||||||
|
public class PluginCliOptionProcessingException(
|
||||||
|
val pluginId: String,
|
||||||
|
val options: Collection<CliOption>,
|
||||||
|
message: String,
|
||||||
|
cause: Throwable? = null
|
||||||
|
): CliOptionProcessingException(message, cause)
|
||||||
|
|
||||||
|
public fun cliPluginUsageString(pluginId: String, options: Collection<CliOption>): String {
|
||||||
|
val LEFT_INDENT = 2
|
||||||
|
val MAX_OPTION_WIDTH = 26
|
||||||
|
|
||||||
|
val renderedOptions = options.map {
|
||||||
|
val name = "${it.name} ${it.valueDescription}"
|
||||||
|
val margin = if (name.length() > MAX_OPTION_WIDTH) {
|
||||||
|
"\n" + " ".repeat(MAX_OPTION_WIDTH + LEFT_INDENT + 1)
|
||||||
|
} else " ".repeat(1 + MAX_OPTION_WIDTH - name.length())
|
||||||
|
|
||||||
|
val modifiers = (if (it.required) "required" else "") + (if (it.allowMultipleOccurrences) "multiple" else "")
|
||||||
|
val modifiersEnclosed = if (modifiers.isNotEmpty()) " ($modifiers)" else ""
|
||||||
|
|
||||||
|
" ".repeat(LEFT_INDENT) + name + margin + it.description + modifiersEnclosed
|
||||||
|
}
|
||||||
|
return "Plugin \"$pluginId\" usage:\n" + renderedOptions.joinToString("\n", postfix = "\n")
|
||||||
|
}
|
||||||
|
|
||||||
public data class CliOptionValue(
|
public data class CliOptionValue(
|
||||||
val pluginId: String,
|
val pluginId: String,
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
-d
|
||||||
|
$TEMP_DIR$
|
||||||
|
-Xplugin
|
||||||
|
dist/kotlinc/lib/android-compiler-plugin.jar
|
||||||
|
-P
|
||||||
|
plugin:org.jetbrains.kotlin.android:androidManifest=$TESTDATA_DIR$/androidPlugin/AndroidManifest.xml
|
||||||
|
$TESTDATA_DIR$/pluginSimple.kt
|
||||||
|
$TESTDATA_DIR$/androidPlugin/androidApp.kt
|
||||||
|
$TESTDATA_DIR$/androidPlugin/androidView.kt
|
||||||
|
$TESTDATA_DIR$/androidPlugin/androidWidget.kt
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import android.view.*
|
||||||
|
import android.app.*
|
||||||
|
import android.widget.*
|
||||||
|
import kotlinx.android.synthetic.layout.*
|
||||||
|
|
||||||
|
class MyActivity : Activity() {
|
||||||
|
{ textView.setText("Some text") }
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
ERROR: Required plugin option not present: org.jetbrains.kotlin.android:androidRes
|
||||||
|
|
||||||
|
Plugin "org.jetbrains.kotlin.android" usage:
|
||||||
|
androidRes <path> Android resources path (required)
|
||||||
|
androidManifest <path> Android manifest file (required)
|
||||||
|
|
||||||
|
COMPILATION_ERROR
|
||||||
@@ -77,4 +77,9 @@ public class CliCommonTest extends CliBaseTest {
|
|||||||
public void pluginSimple() throws Exception {
|
public void pluginSimple() throws Exception {
|
||||||
executeCompilerCompareOutputJVM();
|
executeCompilerCompareOutputJVM();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pluginSimpleUsage() throws Exception {
|
||||||
|
executeCompilerCompareOutputJVM();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user