diff --git a/java/execution/impl/resources/messages/VMOptionsBundle.properties b/java/execution/impl/resources/messages/VMOptionsBundle.properties index 285cbcbd86ce..1a1c6aaadadb 100644 --- a/java/execution/impl/resources/messages/VMOptionsBundle.properties +++ b/java/execution/impl/resources/messages/VMOptionsBundle.properties @@ -92,3 +92,26 @@ vm.option.verbose.description=Outputs messages about what the compiler is doing, vm.option.version.description=Prints version information. vm.option.werror.description=Terminates compilation when warnings occur. +# javac -X +vm.option.default.module.for.created.files.description=Specifies the fallback target module for files created by annotation processors, if none is specified or inferred. +vm.option.disable.line.doc.comments.description=Disables support for documentation comments with lines beginning ///. +vm.option.help.lint.description=Prints the supported keys for the -Xlint option. +vm.option.patch.module.javac.description=Overrides or augments a module with classes and resources in JAR files or directories. +vm.option.bootclasspath.javac.description=Overrides the location of the bootstrap class files. +vm.option.bootclasspath.a.javac.description=Adds a suffix to the bootstrap class path. +vm.option.bootclasspath.p.javac.description=Adds a prefix to the bootstrap class path. +vm.option.diags.description=Selects a diagnostic mode. +vm.option.doclint.description=Enables recommended checks for problems in documentation comments. +vm.option.doclint.groups.description=Enables or disables specific groups of checks in documentation comments. +vm.option.doclint.package.description=Enables or disables checks in specific packages. +vm.option.xlint.description=Enables all recommended warnings. +vm.option.xlint.keys.description=Enables and/or disables specific warning categories. +vm.option.maxerrs.description=Sets the maximum number of errors to print. +vm.option.maxwarns.description=Sets the maximum number of warnings to print. +vm.option.pkginfo.description=Specifies when and how javac generates package-info.class files. +vm.option.plugin.description=Specifies the name and optional arguments for a plug-in to be run. +vm.option.prefer.description=Specifies which file to read when both a source file and class file are found for an implicitly compiled class. +vm.option.print.description=Prints out a textual representation of specified types for debugging purposes. +vm.option.print.processor.info.description=Prints information about which annotations a processor is asked to process. +vm.option.print.rounds.description=Prints information about annotation processing rounds. +vm.option.stdout.description=Redirects standard output to a file. diff --git a/java/execution/impl/src/com/intellij/execution/vmOptions/CommandOptionsExtractor.kt b/java/execution/impl/src/com/intellij/execution/vmOptions/CommandOptionsExtractor.kt index 01947ab3044b..e632cc2ca2eb 100644 --- a/java/execution/impl/src/com/intellij/execution/vmOptions/CommandOptionsExtractor.kt +++ b/java/execution/impl/src/com/intellij/execution/vmOptions/CommandOptionsExtractor.kt @@ -92,8 +92,8 @@ internal abstract class CommandOptionsExtractor { private fun getOptionsForJava(javaHome: String): List { val output = getProcessOutput(javaHome) ?: return STANDARD_OPTION_LIST - val xxOptions = VMOptionsParser.parseXXOptions(output.stdout) - val xOptions = VMOptionsParser.parseXOptions(output.stderr) + val xxOptions = VMOptionsParser.parseJavaXXOptions(output.stdout) + val xOptions = VMOptionsParser.parseJavaXOptions(output.stderr) if (xOptions != null) { return xOptions + xxOptions + STANDARD_OPTION_LIST } @@ -135,8 +135,11 @@ internal abstract class CommandOptionsExtractor { private fun getOptionsForJavac(javaHome: String): List { val processOutput = getProcessOutput(javaHome) ?: return emptyList() - val parsedStandardOptions = VMOptionsParser.parseJavacDoubleDashedOptions(processOutput.stdout) - return if (parsedStandardOptions != null) parsedStandardOptions + STANDARD_OPTIONS_LIST else STANDARD_OPTIONS_LIST + val result = mutableListOf() + result.addAll(STANDARD_OPTIONS_LIST) + VMOptionsParser.parseJavacDoubleDashedOptions(processOutput.stdout)?.let { result.addAll(it) } + VMOptionsParser.parseJavacXOptions(processOutput.stdout)?.let { result.addAll(it) } + return result } } diff --git a/java/execution/impl/src/com/intellij/execution/vmOptions/VMOptionsParser.kt b/java/execution/impl/src/com/intellij/execution/vmOptions/VMOptionsParser.kt index 19489a37b55a..e6d0fe585d60 100644 --- a/java/execution/impl/src/com/intellij/execution/vmOptions/VMOptionsParser.kt +++ b/java/execution/impl/src/com/intellij/execution/vmOptions/VMOptionsParser.kt @@ -7,7 +7,7 @@ import org.jetbrains.annotations.PropertyKey internal object VMOptionsParser { private val LOG = Logger.getInstance(VMOptionsParser::class.java) - internal fun parseXXOptions(text: String) : List { + internal fun parseJavaXXOptions(text: String) : List { val lines = text.lineSequence().drop(1) val options = lines.mapNotNull { val lbraceIndex = it.indexOf("{") @@ -42,7 +42,7 @@ internal object VMOptionsParser { return options } - internal fun parseXOptions(stderr: String): List? { + internal fun parseJavaXOptions(stderr: String): List? { var tailIndex = stderr.indexOf("These extra options are subject to change without notice.") if (tailIndex == -1) { tailIndex = stderr.indexOf("The -X options are non-standard and subject to change without notice.") @@ -53,6 +53,17 @@ internal object VMOptionsParser { return parseLines(ParsingType.JavaExtraOptions, stderr.substring(0, tailIndex).trimStart().lines(), mapOf("-X" to VMOptionVariant.X, "--" to VMOptionVariant.DASH_DASH), separators) } + internal fun parseJavacXOptions(input: String): List? { + val lines = input.lines() + val beforeStartLine = lines.indexOf("") + if (beforeStartLine == -1) return null + val afterEndLine = lines.indexOf("These extra options are subject to change without notice.") + if (afterEndLine == -1) return null + if (beforeStartLine + 1 >= afterEndLine - 1) return null + return parseLines(ParsingType.JavacExtraOptions, lines.subList(beforeStartLine + 1, afterEndLine - 1), mapOf("-X" to VMOptionVariant.X, "--" to VMOptionVariant.DASH_DASH), charArrayOf(' ')) + } + + internal fun parseJavacDoubleDashedOptions(input: String): List? { val lines = input.lines() val lastLine = lines.indexOf("") @@ -185,7 +196,24 @@ internal object VMOptionsParser { } } - object JavacStandardOptions : ParsingType { + interface JavacOptionsBase : ParsingType { + override fun parseName(input: String): String { + // parsing names "-opt:{arguments}" + input.extractPrefix(Regex(":[\"\\[{(]"), ":")?.let { return it } + + // parsing names "-opt[=value]" + input.extractPrefix(Regex("\\["), "")?.let { return it } + + return input.extractPrefix(Regex("<"), shouldHaveTwoParts = false) ?: throw IllegalArgumentException("Cannot parse option name: $input") + } + + private fun String.extractPrefix(delimiter: Regex, suffix: String = "", shouldHaveTwoParts: Boolean = true): String? { + val parts = split(delimiter) + return if (parts.size == 2 || !shouldHaveTwoParts) parts.first().trimEnd(',') + suffix else null + } + } + + object JavacStandardOptions : JavacOptionsBase { override val optionDescriptionPropertyKey: Map = mapOf( Pair("--add-modules", "vm.option.add.modules.description"), Pair("--boot-class-path", "vm.option.boot.classpath.description"), @@ -211,21 +239,37 @@ internal object VMOptionsParser { ) override val kind: VMOptionKind = VMOptionKind.Standard - - override fun parseName(input: String): String { - // parsing names "-opt:{arguments}" - input.extractPrefix(":{", ":")?.let { return it } - - // parsing names "-opt[=value]" - input.extractPrefix("[", "")?.let { return it } - - return input.extractPrefix("<", shouldHaveTwoParts = false) ?: throw IllegalArgumentException("Cannot parse option name: $input") - } - - private fun String.extractPrefix(delimiter: String, suffix: String = "", shouldHaveTwoParts: Boolean = true): String? { - val parts = split(delimiter) - return if (parts.size == 2 || !shouldHaveTwoParts) parts.first().trimEnd(',') else null - } + } + + object JavacExtraOptions : JavacOptionsBase { + override val optionDescriptionPropertyKey: Map = mapOf( + Pair("--add-exports", "vm.option.add.exports.description"), + Pair("--add-reads", "vm.option.add.reads.description"), + Pair("--default-module-for-created-files", "vm.option.default.module.for.created.files.description"), + Pair("--disable-line-doc-comments", "vm.option.disable.line.doc.comments.description"), + Pair("--help-lint", "vm.option.help.lint.description"), + Pair("--patch-module", "vm.option.patch.module.javac.description"), + Pair("-Xbootclasspath:", "vm.option.bootclasspath.javac.description"), + Pair("-Xbootclasspath/a:", "vm.option.bootclasspath.a.javac.description"), + Pair("-Xbootclasspath/p:", "vm.option.bootclasspath.p.javac.description"), + Pair("-Xdiags:", "vm.option.diags.description"), + Pair("-Xdoclint", "vm.option.doclint.description"), + Pair("-Xdoclint:", "vm.option.doclint.groups.description"), + Pair("-Xdoclint/package:", "vm.option.doclint.package.description"), + Pair("-Xlint", "vm.option.xlint.description"), + Pair("-Xlint:", "vm.option.xlint.keys.description"), + Pair("-Xmaxerrs", "vm.option.maxerrs.description"), + Pair("-Xmaxwarns", "vm.option.maxwarns.description"), + Pair("-Xpkginfo:", "vm.option.pkginfo.description"), + Pair("-Xplugin:", "vm.option.plugin.description"), + Pair("-Xprefer:", "vm.option.prefer.description"), + Pair("-Xprint", "vm.option.print.description"), + Pair("-XprintProcessorInfo", "vm.option.print.processor.info.description"), + Pair("-XprintRounds", "vm.option.print.rounds.description"), + Pair("-Xstdout", "vm.option.stdout.description"), + ) + override val kind: VMOptionKind + get() = VMOptionKind.Product } } } \ No newline at end of file diff --git a/java/java-terminal/src/com/intellij/java/terminal/JavacShellCommandSpecsProvider.kt b/java/java-terminal/src/com/intellij/java/terminal/JavacShellCommandSpecsProvider.kt index 886189f0092e..196e2299f002 100644 --- a/java/java-terminal/src/com/intellij/java/terminal/JavacShellCommandSpecsProvider.kt +++ b/java/java-terminal/src/com/intellij/java/terminal/JavacShellCommandSpecsProvider.kt @@ -105,4 +105,20 @@ private val UI_OPTION_INFO_MAP = mapOf( "--system" to UIOptionInfo(argumentName = "jdk"), "--target" to UIOptionInfo(argumentName = "release"), "--upgrade-module-path" to UIOptionInfo(argumentName = "path", suggestionsGenerator = ShellDataGenerators.fileSuggestionsGenerator()), + "--add-exports" to UIOptionInfo(repeatTimes = 0, argumentName = "module/package=other-module(,other-module)*"), + "--add-reads" to UIOptionInfo(repeatTimes = 0, argumentName = "module=other-module(,other-module)*"), + "--default-module-for-created-files" to UIOptionInfo(argumentName = "module-name"), + "--patch-module" to UIOptionInfo(repeatTimes = 0, argumentName = "module=path"), + "-Xbootclasspath:" to UIOptionInfo(separator = "", argumentName = "path"), + "-Xbootclasspath/a:" to UIOptionInfo(separator = "", argumentName = "path"), + "-Xbootclasspath/p:" to UIOptionInfo(separator = "", argumentName = "path"), + "-Xdiags:" to UIOptionInfo(separator = "", isArgumentOptional = true, argumentName = "compact|verbose"), + "-Xdoclint:" to UIOptionInfo(separator = "", argumentName = "(none|all)"), + "-Xdoclint/package:" to UIOptionInfo(separator = "", argumentName = "(none|all)"), + "-Xlint:" to UIOptionInfo(separator = "", argumentName = "[-]key(,[-]key)*"), + "-Xmaxerrs" to UIOptionInfo(argumentName = "number"), + "-Xmaxwarns" to UIOptionInfo(argumentName = "number"), + "-Xpkginfo:" to UIOptionInfo(separator = "", argumentName = "always|legacy|nonempty", isArgumentOptional = true), + "-Xplugin:" to UIOptionInfo(separator = "", argumentName = "name"), + "-Xprefer:" to UIOptionInfo(separator = "", argumentName = "source|newer", isArgumentOptional = true), ) \ No newline at end of file diff --git a/java/java-terminal/test/com/intellij/java/terminal/completion/JavacShellCommandSpecsProviderTest.kt b/java/java-terminal/test/com/intellij/java/terminal/completion/JavacShellCommandSpecsProviderTest.kt index 3e78d252b109..7073234e9224 100644 --- a/java/java-terminal/test/com/intellij/java/terminal/completion/JavacShellCommandSpecsProviderTest.kt +++ b/java/java-terminal/test/com/intellij/java/terminal/completion/JavacShellCommandSpecsProviderTest.kt @@ -44,6 +44,12 @@ internal class JavacShellCommandSpecsProviderTest(engine: TerminalEngine) : JdkC UsefulTestCase.assertContainsElements(fixture.getCompletionNames("javac "), listOf("--enable-preview", "--release", "--source", "--target")) } + @Test + fun `extra options are present`() = runBlocking { + val fixture = createFixture() + UsefulTestCase.assertContainsElements(fixture.getCompletionNames("javac "), listOf("-Xlint", "-Xbootclasspath:")) + } + @Test fun `classpath suggestion generator`() = runBlocking { val separator = JavaShellCommandUtils.getClassPathSeparator() diff --git a/java/java-terminal/test/com/intellij/java/terminal/completion/JdkCommandsShellSpecsProviderTestBase.kt b/java/java-terminal/test/com/intellij/java/terminal/completion/JdkCommandsShellSpecsProviderTestBase.kt index dee425536f8e..3dd8bcbf0acf 100644 --- a/java/java-terminal/test/com/intellij/java/terminal/completion/JdkCommandsShellSpecsProviderTestBase.kt +++ b/java/java-terminal/test/com/intellij/java/terminal/completion/JdkCommandsShellSpecsProviderTestBase.kt @@ -88,6 +88,8 @@ internal abstract class JdkCommandsShellSpecsProviderTestBase(private val engine VMOption("source", null, null, VMOptionKind.Standard, null, VMOptionVariant.DASH_DASH), VMOption("target", null, null, VMOptionKind.Standard, null, VMOptionVariant.DASH_DASH), VMOption("experimental", null, null, VMOptionKind.Experimental, null, VMOptionVariant.DASH_DASH), + VMOption("lint", null, null, VMOptionKind.Product, null, VMOptionVariant.X), + VMOption("bootclasspath:", null, null, VMOptionKind.Product, null, VMOptionVariant.X), ) ) )