mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +07:00
QD-8426: Launch Qodana using ModernApplicationStarter
[QD-8426] Properly suspend in project opening & configuration Like in db06df3bd4ce31fbd56d74dccda89b15322b4136 we need to use different dispatching behaviour in prod/test to avoid an EDT deadlock, this time in the golang configurator [QD-8426] Rename interface [QD-8426] Merge InspectionApplication into InspectionApplicationBase Add deprecation annotation because of API check [QD-8426] Delegate all message reporting [QD-8429] Remove ProgressManager from QodanaInspectionApplication [QD-8426] Fully decouple QodanaInspectionApplication from InspectionApplicationBase [QD-8426] Update InspectionMain to ModernApplicationStarter [QD-8426] Convert InspectionApplicationFactory and InspectionMain to kotlin Rename .java to .kt QD-8426 Merge-request: IJ-MR-126583 Merged-by: Johannes Koenen <Johannes.Koenen@jetbrains.com> GitOrigin-RevId: bc152d816e2acad9bd20a6c7db512108377995b0
This commit is contained in:
committed by
intellij-monorepo-bot
parent
7ab8560477
commit
e2944e826f
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<InspectionApplicationFactory> EP_NAME = ExtensionPointName.create("com.intellij.inspectionApplicationFactory");
|
||||
|
||||
@NotNull
|
||||
String id();
|
||||
|
||||
InspectionApplicationBase getApplication(@NotNull List<String> args) throws InspectionApplicationException;
|
||||
|
||||
@NotNull
|
||||
static InspectionApplicationBase getApplication(@NotNull String id, @NotNull List<String> 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.");
|
||||
}
|
||||
}
|
||||
@@ -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<String>): InspectionApplicationStart
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getApplication(id: String, args: List<String>): 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<InspectionApplicationFactory> = create("com.intellij.inspectionApplicationFactory")
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface InspectionApplicationStart {
|
||||
interface Synchronous : InspectionApplicationStart {
|
||||
fun startup()
|
||||
}
|
||||
|
||||
interface Asynchronous : InspectionApplicationStart {
|
||||
suspend fun startup()
|
||||
}
|
||||
}
|
||||
@@ -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<String> 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<String> args) {
|
||||
myApplication.startup();
|
||||
}
|
||||
|
||||
private static void printHelpAndExit() {
|
||||
System.out.println(InspectionsBundle.message("inspection.command.line.explanation"));
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -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<String>) {
|
||||
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<String>) =
|
||||
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<String>): 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<String>) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user