diff --git a/platform/inspect/src/com/intellij/codeInspection/AbstractInspectionCmdlineOptions.java b/platform/inspect/src/com/intellij/codeInspection/AbstractInspectionCmdlineOptions.java index 0cf67c5cc6a9..4009bbfda0db 100644 --- a/platform/inspect/src/com/intellij/codeInspection/AbstractInspectionCmdlineOptions.java +++ b/platform/inspect/src/com/intellij/codeInspection/AbstractInspectionCmdlineOptions.java @@ -45,7 +45,7 @@ public abstract class AbstractInspectionCmdlineOptions implements InspectionTool protected abstract String @NotNull [] optionsBanner(); @Override - public void initApplication(InspectionApplication app) { + public void initApplication(InspectionApplicationBase app) { app.myHelpProvider = this; app.myProjectPath = determineProjectPath(); app.myProfileName = getProfileNameOrPathProperty(); diff --git a/platform/inspect/src/com/intellij/codeInspection/AbstractInspectionToolStarter.java b/platform/inspect/src/com/intellij/codeInspection/AbstractInspectionToolStarter.java index 8e3e004d0f28..e150e0d2f7b0 100644 --- a/platform/inspect/src/com/intellij/codeInspection/AbstractInspectionToolStarter.java +++ b/platform/inspect/src/com/intellij/codeInspection/AbstractInspectionToolStarter.java @@ -13,7 +13,7 @@ import java.util.concurrent.ForkJoinPool; @SuppressWarnings("UseOfSystemOutOrSystemErr") public abstract class AbstractInspectionToolStarter implements ApplicationStarter { - private InspectionApplication myApplication; + private InspectionApplicationBase myApplication; protected InspectionToolCmdlineOptions myOptions; protected abstract AbstractInspectionCmdlineOptions createCmdlineOptions(); @@ -56,13 +56,13 @@ public abstract class AbstractInspectionToolStarter implements ApplicationStarte System.exit(1); } - myApplication = new InspectionApplication(); + myApplication = new InspectionApplicationBase(); initApplication(myApplication, myOptions); // TODO: keep application settings in Memory } - protected InspectionApplication getApplication() { + protected InspectionApplicationBase getApplication() { return myApplication; } @@ -71,7 +71,7 @@ public abstract class AbstractInspectionToolStarter implements ApplicationStarte myOptions.beforeStartup(); IdeaForkJoinWorkerThreadFactory.setupForkJoinCommonPool(true); - InspectionApplication.LOG.info( + InspectionApplicationBase.LOG.info( "CPU cores: " + Runtime.getRuntime().availableProcessors() + "; " + "ForkJoinPool.commonPool: " + ForkJoinPool.commonPool() + "; " + "factory: " + ForkJoinPool.commonPool().getFactory()); @@ -79,7 +79,7 @@ public abstract class AbstractInspectionToolStarter implements ApplicationStarte myApplication.startup(); } - private static void initApplication(@NotNull InspectionApplication application, + private static void initApplication(@NotNull InspectionApplicationBase application, @NotNull InspectionToolCmdlineOptions opts) { opts.initApplication(application); } diff --git a/platform/inspect/src/com/intellij/codeInspection/InspectionApplication.java b/platform/inspect/src/com/intellij/codeInspection/InspectionApplication.java index 5a6a69e56b3e..64d1b18d3ba6 100644 --- a/platform/inspect/src/com/intellij/codeInspection/InspectionApplication.java +++ b/platform/inspect/src/com/intellij/codeInspection/InspectionApplication.java @@ -1,8 +1,10 @@ // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInspection; -import com.intellij.openapi.diagnostic.Logger; +/** + * @deprecated Inherit directly from InspectionApplicationBase + */ +@Deprecated(forRemoval = true) public final class InspectionApplication extends InspectionApplicationBase { - static final Logger LOG = Logger.getInstance(InspectionApplication.class); } diff --git a/platform/inspect/src/com/intellij/codeInspection/InspectionApplicationBase.java b/platform/inspect/src/com/intellij/codeInspection/InspectionApplicationBase.java index b4da7d91ea3d..95388f820462 100644 --- a/platform/inspect/src/com/intellij/codeInspection/InspectionApplicationBase.java +++ b/platform/inspect/src/com/intellij/codeInspection/InspectionApplicationBase.java @@ -62,7 +62,6 @@ import one.util.streamex.StreamEx; import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.VisibleForTesting; import org.jetbrains.concurrency.AsyncPromise; import javax.xml.stream.XMLStreamException; @@ -79,8 +78,8 @@ import java.util.function.Predicate; import static com.intellij.configurationStore.StoreUtilKt.forPoorJavaClientOnlySaveProjectIndEdtDoNotUseThisMethod; -public class InspectionApplicationBase implements CommandLineInspectionProgressReporter { - private static final Logger LOG = Logger.getInstance(InspectionApplicationBase.class); +public class InspectionApplicationBase implements CommandLineInspectionProgressReporter, InspectionApplicationStart.Synchronous { + public static final Logger LOG = Logger.getInstance(InspectionApplicationBase.class); public static final String PROJECT_STRUCTURE_DIR = "projectStructure"; @@ -272,8 +271,7 @@ public class InspectionApplicationBase implements CommandLineInspectionProgressR return project; } - @VisibleForTesting - public @Nullable AnalysisScope getAnalysisScope(@NotNull Project project) throws ExecutionException, InterruptedException { + private @Nullable AnalysisScope getAnalysisScope(@NotNull Project project) throws ExecutionException, InterruptedException { SearchScope scope = getSearchScope(project); if (scope == null) return null; return new AnalysisScope(scope, project); diff --git a/platform/inspect/src/com/intellij/codeInspection/InspectionApplicationFactory.java b/platform/inspect/src/com/intellij/codeInspection/InspectionApplicationFactory.java deleted file mode 100644 index 2c28ac4ac15b..000000000000 --- a/platform/inspect/src/com/intellij/codeInspection/InspectionApplicationFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.codeInspection; - -import com.intellij.openapi.extensions.ExtensionPointName; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -@ApiStatus.Internal -public interface InspectionApplicationFactory { - ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.inspectionApplicationFactory"); - - @NotNull - String id(); - - InspectionApplicationBase getApplication(@NotNull List args) throws InspectionApplicationException; - - @NotNull - static InspectionApplicationBase getApplication(@NotNull String id, @NotNull List args) throws InspectionApplicationException { - for (InspectionApplicationFactory extension : EP_NAME.getExtensionList()) { - if (extension.id().equals(id)) { - return extension.getApplication(args); - } - } - throw new InspectionApplicationException("There is no loaded inspect engine with id= '" + id + "'. Please check loaded plugin list."); - } -} \ No newline at end of file diff --git a/platform/inspect/src/com/intellij/codeInspection/InspectionApplicationFactory.kt b/platform/inspect/src/com/intellij/codeInspection/InspectionApplicationFactory.kt new file mode 100644 index 000000000000..1c0b0a17f4b5 --- /dev/null +++ b/platform/inspect/src/com/intellij/codeInspection/InspectionApplicationFactory.kt @@ -0,0 +1,34 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.codeInspection + +import com.intellij.openapi.extensions.ExtensionPointName +import com.intellij.openapi.extensions.ExtensionPointName.Companion.create +import org.jetbrains.annotations.ApiStatus + +@ApiStatus.Internal +interface InspectionApplicationFactory { + fun id(): String + + fun getApplication(args: List): InspectionApplicationStart + + companion object { + @JvmStatic + fun getApplication(id: String, args: List): InspectionApplicationStart = + EP_NAME.extensionList + .firstOrNull { it.id() == id } + ?.getApplication(args) + ?: throw InspectionApplicationException("There is no loaded inspect engine with id= '$id'. Please check loaded plugin list.") + + val EP_NAME: ExtensionPointName = create("com.intellij.inspectionApplicationFactory") + } +} + +sealed interface InspectionApplicationStart { + interface Synchronous : InspectionApplicationStart { + fun startup() + } + + interface Asynchronous : InspectionApplicationStart { + suspend fun startup() + } +} diff --git a/platform/inspect/src/com/intellij/codeInspection/InspectionMain.java b/platform/inspect/src/com/intellij/codeInspection/InspectionMain.java deleted file mode 100644 index c531e5a9579d..000000000000 --- a/platform/inspect/src/com/intellij/codeInspection/InspectionMain.java +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.codeInspection; - -import com.intellij.openapi.application.ApplicationStarter; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -@SuppressWarnings({"CallToPrintStackTrace", "UseOfSystemOutOrSystemErr"}) -public class InspectionMain implements ApplicationStarter { - private InspectionApplicationBase myApplication; - - @Override - public String getCommandName() { - return "inspect"; - } - - @Override - public int getRequiredModality() { - return NOT_IN_EDT; - } - - @Override - public void premain(@NotNull List args) { - InspectionApplication.LOG.info("Command line arguments: " + args); - if (args.size() > 1 && "qodana".equals(args.get(1))) { - try { - myApplication = InspectionApplicationFactory.getApplication("qodana", args.subList(2, args.size())); - } - catch (InspectionApplicationException e) { - System.err.println(e.getMessage()); - System.exit(1); - } - catch (Exception e) { - e.printStackTrace(); // workaround for IDEA-289086 - System.exit(1); - } - return; - } - myApplication = new InspectionApplication(); - if (args.size() < 4) { - System.err.println("invalid args:" + args); - printHelpAndExit(); - } - - myApplication.myHelpProvider = InspectionMain::printHelpAndExit; - myApplication.myProjectPath = args.get(1); - myApplication.myStubProfile = args.get(2); - myApplication.myOutPath = args.get(3); - - if (myApplication.myProjectPath == null - || myApplication.myOutPath == null - || myApplication.myStubProfile == null) { - System.err.println(myApplication.myProjectPath + myApplication.myOutPath + myApplication.myStubProfile); - printHelpAndExit(); - } - - try { - for (int i = 4; i < args.size(); i++) { - String arg = args.get(i); - if ("-profileName".equals(arg)) { - myApplication.myProfileName = args.get(++i); - } - else if ("-profilePath".equals(arg)) { - myApplication.myProfilePath = args.get(++i); - } - else if ("-d".equals(arg)) { - myApplication.mySourceDirectory = args.get(++i); - } - else if ("-scope".equals(arg)) { - myApplication.myScopePattern = args.get(++i); - } - else if ("-targets".equals(arg)) { - myApplication.myTargets = args.get(++i); - } - else if ("-format".equals(arg)) { - myApplication.myOutputFormat = args.get(++i); - } - else if ("-v0".equals(arg)) { - myApplication.setVerboseLevel(0); - } - else if ("-v1".equals(arg)) { - myApplication.setVerboseLevel(1); - } - else if ("-v2".equals(arg)) { - myApplication.setVerboseLevel(2); - } - else if ("-v3".equals(arg)) { - myApplication.setVerboseLevel(3); - } - else if ("-e".equals(arg)) { - myApplication.myRunWithEditorSettings = true; - } - else if ("-t".equals(arg)) { - myApplication.myErrorCodeRequired = false; - } - else if ("-changes".equals(arg)) { - myApplication.myAnalyzeChanges = true; - } - else //noinspection StatementWithEmptyBody - if ("-qodana".equals(arg)) { - } - else { - System.err.println("unexpected argument: " + arg); - printHelpAndExit(); - } - } - } - catch (IndexOutOfBoundsException e) { - e.printStackTrace(); - printHelpAndExit(); - } - - myApplication.myRunGlobalToolsOnly = System.getProperty("idea.no.local.inspections") != null; - } - - @Override - public void main(@NotNull List args) { - myApplication.startup(); - } - - private static void printHelpAndExit() { - System.out.println(InspectionsBundle.message("inspection.command.line.explanation")); - System.exit(1); - } -} diff --git a/platform/inspect/src/com/intellij/codeInspection/InspectionMain.kt b/platform/inspect/src/com/intellij/codeInspection/InspectionMain.kt new file mode 100644 index 000000000000..7dbb29092495 --- /dev/null +++ b/platform/inspect/src/com/intellij/codeInspection/InspectionMain.kt @@ -0,0 +1,130 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.codeInspection + +import com.intellij.codeInspection.InspectionApplicationFactory.Companion.getApplication +import com.intellij.openapi.application.ModernApplicationStarter +import java.util.concurrent.CompletableFuture +import kotlin.system.exitProcess + +class InspectionMain : ModernApplicationStarter() { + private lateinit var application: InspectionApplicationStart + + override fun premain(args: List) { + InspectionApplicationBase.LOG.info("Command line arguments: $args") + application = if (args.size > 1 && "qodana" == args[1]) { + buildQodanaApplication(args) + } + else { + buildInspectionApplication(args) + } + } + + private fun buildQodanaApplication(args: List) = + try { + getApplication("qodana", args.subList(2, args.size)) + } + catch (e: InspectionApplicationException) { + System.err.println(e.message) + exitProcess(1) + } + catch (e: Exception) { + e.printStackTrace() // workaround for IDEA-289086 + exitProcess(1) + } + + private fun buildInspectionApplication(args: List): InspectionApplicationStart { + val app = InspectionApplicationBase() + if (args.size < 4) { + System.err.println("invalid args:$args") + printHelpAndExit() + } + + app.myHelpProvider = InspectionToolCmdlineOptionHelpProvider { printHelpAndExit() } + app.myProjectPath = args[1] + app.myStubProfile = args[2] + app.myOutPath = args[3] + + if (app.myProjectPath == null || app.myOutPath == null || app.myStubProfile == null) { + System.err.println(app.myProjectPath + app.myOutPath + app.myStubProfile) + printHelpAndExit() + } + + try { + var i = 4 + while (i < args.size) { + when (val arg = args[i]) { + "-profileName" -> { + app.myProfileName = args[++i] + } + "-profilePath" -> { + app.myProfilePath = args[++i] + } + "-d" -> { + app.mySourceDirectory = args[++i] + } + "-scope" -> { + app.myScopePattern = args[++i] + } + "-targets" -> { + app.myTargets = args[++i] + } + "-format" -> { + app.myOutputFormat = args[++i] + } + "-v0" -> { + app.setVerboseLevel(0) + } + "-v1" -> { + app.setVerboseLevel(1) + } + "-v2" -> { + app.setVerboseLevel(2) + } + "-v3" -> { + app.setVerboseLevel(3) + } + "-e" -> { + app.myRunWithEditorSettings = true + } + "-t" -> { + app.myErrorCodeRequired = false + } + "-changes" -> { + app.myAnalyzeChanges = true + } + "-qodana" -> { /* do nothing */ + } + else -> { + System.err.println("unexpected argument: $arg") + printHelpAndExit() + } + } + i++ + } + } + catch (e: IndexOutOfBoundsException) { + e.printStackTrace() + printHelpAndExit() + } + + app.myRunGlobalToolsOnly = System.getProperty("idea.no.local.inspections") != null + return app + } + + override suspend fun start(args: List) { + when (val r = application) { + is InspectionApplicationStart.Asynchronous -> r.startup() + /* + todo https://youtrack.jetbrains.com/issue/IDEA-298594 + See also com.intellij.platform.ide.bootstrap.ApplicationLoader.executeApplicationStarter + */ + is InspectionApplicationStart.Synchronous -> CompletableFuture.runAsync(r::startup) + } + } + + + private fun printHelpAndExit() { + println(InspectionsBundle.message("inspection.command.line.explanation")) + exitProcess(1) + } +} diff --git a/platform/inspect/src/com/intellij/codeInspection/InspectionToolCmdlineOptions.java b/platform/inspect/src/com/intellij/codeInspection/InspectionToolCmdlineOptions.java index d85baca3d2db..fc9314f08593 100644 --- a/platform/inspect/src/com/intellij/codeInspection/InspectionToolCmdlineOptions.java +++ b/platform/inspect/src/com/intellij/codeInspection/InspectionToolCmdlineOptions.java @@ -7,7 +7,7 @@ public interface InspectionToolCmdlineOptions extends InspectionToolCmdlineOptio /** * @param app Inspection Application */ - void initApplication(InspectionApplication app); + void initApplication(InspectionApplicationBase app); /** * @return 0 if turned off