mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
extend CommandLineInspectionProjectConfigurator API to pass more options into extensions
GitOrigin-RevId: 04db41ad3e5bdce2c2504b6bb5fdc129ead1297a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a4b7bcacc1
commit
86618d10a8
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. 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.google.common.base.Predicates;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.codeInspection.ex.*;
|
||||
@@ -62,6 +63,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
public final class InspectionApplication implements CommandLineInspectionProgressReporter {
|
||||
@@ -138,6 +140,41 @@ public final class InspectionApplication implements CommandLineInspectionProgres
|
||||
myHelpProvider.printHelpAndExit();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CommandLineInspectionProjectConfigurator.ConfiguratorContext configuratorContext(@NotNull Path projectPath, @Nullable AnalysisScope scope) {
|
||||
return new CommandLineInspectionProjectConfigurator.ConfiguratorContext() {
|
||||
@Override
|
||||
public @NotNull ProgressIndicator getProgressIndicator() {
|
||||
return new ProgressIndicatorBase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AnalysisScope getAnalyzerScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CommandLineInspectionProgressReporter getLogger() {
|
||||
return InspectionApplication.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Path getProjectPath() {
|
||||
return projectPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Predicate<Path> getFilesFilter() {
|
||||
return Predicates.alwaysTrue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Predicate<VirtualFile> getVirtualFilesFilter() {
|
||||
return Predicates.alwaysTrue();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void run(@NotNull Path projectPath, @NotNull Disposable parentDisposable) throws IOException, JDOMException {
|
||||
VirtualFile vfsProject = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(projectPath.toString()));
|
||||
if (vfsProject == null) {
|
||||
@@ -152,8 +189,9 @@ public final class InspectionApplication implements CommandLineInspectionProgres
|
||||
}
|
||||
|
||||
for (CommandLineInspectionProjectConfigurator configurator : CommandLineInspectionProjectConfigurator.EP_NAME.getExtensionList()) {
|
||||
if (configurator.isApplicable(projectPath, this)) {
|
||||
configurator.configureEnvironment(projectPath, this);
|
||||
CommandLineInspectionProjectConfigurator.ConfiguratorContext context = configuratorContext(projectPath, null);
|
||||
if (configurator.isApplicable(context)) {
|
||||
configurator.configureEnvironment(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,8 +313,9 @@ public final class InspectionApplication implements CommandLineInspectionProgres
|
||||
|
||||
private void configureProject(@NotNull Path projectPath, @NotNull Project project, @NotNull AnalysisScope scope) {
|
||||
for (CommandLineInspectionProjectConfigurator configurator : CommandLineInspectionProjectConfigurator.EP_NAME.getIterable()) {
|
||||
if (configurator.isApplicable(projectPath, this)) {
|
||||
configurator.configureProject(project, scope, this);
|
||||
CommandLineInspectionProjectConfigurator.ConfiguratorContext context = configuratorContext(projectPath, scope);
|
||||
if (configurator.isApplicable(context)) {
|
||||
configurator.configureProject(project, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.projectRoots.impl
|
||||
|
||||
import com.intellij.ide.CommandLineInspectionProgressReporter
|
||||
import com.intellij.ide.CommandLineInspectionProjectConfigurator
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.invokeAndWaitIfNeeded
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.util.ProgressIndicatorBase
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ui.configuration.UnknownSdk
|
||||
import com.intellij.openapi.roots.ui.configuration.UnknownSdkResolver
|
||||
@@ -17,33 +14,23 @@ import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.util.Consumer
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import java.nio.file.Path
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
class UnknownSdkInspectionCommandLineConfigurator : CommandLineInspectionProjectConfigurator {
|
||||
private val LOG: Logger = logger<UnknownSdkInspectionCommandLineConfigurator>()
|
||||
|
||||
override fun isApplicable(projectPath: Path, logger: CommandLineInspectionProgressReporter): Boolean {
|
||||
override fun isApplicable(context: CommandLineInspectionProjectConfigurator.ConfiguratorContext): Boolean {
|
||||
return !ApplicationManager.getApplication().isUnitTestMode
|
||||
}
|
||||
|
||||
override fun configureEnvironment(projectPath: Path, logger: CommandLineInspectionProgressReporter) {
|
||||
Registry.get("unknown.sdk").setValue(false) //forbid UnknownSdkTracker post startup activity
|
||||
override fun configureEnvironment(context: CommandLineInspectionProjectConfigurator.ConfiguratorContext) {
|
||||
Registry.get("unknown.sdk").setValue(false) // forbid UnknownSdkTracker post startup activity as we run it here
|
||||
}
|
||||
|
||||
override fun configureProject(project: Project,
|
||||
logger: CommandLineInspectionProgressReporter
|
||||
) = runBlocking {
|
||||
override fun configureProject(project: Project, context: CommandLineInspectionProjectConfigurator.ConfiguratorContext) = runBlocking {
|
||||
require(!ApplicationManager.getApplication().isWriteThread) { "The code below uses the same GUI thread to complete operations." +
|
||||
"Running from EDT would deadlock" }
|
||||
|
||||
val indicator = ProgressManager.getInstance().progressIndicator ?: ProgressIndicatorBase()
|
||||
indicator.pushState()
|
||||
try {
|
||||
resolveUnknownSdks(project, ProgressIndicatorBase())
|
||||
} finally {
|
||||
indicator.popState()
|
||||
}
|
||||
resolveUnknownSdks(project, context.progressIndicator)
|
||||
}
|
||||
|
||||
private suspend fun resolveUnknownSdks(project: Project, indicator: ProgressIndicator) {
|
||||
|
||||
@@ -2,48 +2,87 @@
|
||||
package com.intellij.ide;
|
||||
|
||||
import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.ide.impl.PatchProjectUtil;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Extension point that helps prepare project for opening in headless or automated environments.
|
||||
* Implementation must be stateless.
|
||||
* @author yole
|
||||
*/
|
||||
public interface CommandLineInspectionProjectConfigurator {
|
||||
ExtensionPointName<CommandLineInspectionProjectConfigurator> EP_NAME = ExtensionPointName.create("com.intellij.commandLineInspectionProjectConfigurator");
|
||||
|
||||
/**
|
||||
* Returns true if any additional configuration is required to inspect the project at the given path.
|
||||
*/
|
||||
boolean isApplicable(@NotNull Path projectPath, @NotNull CommandLineInspectionProgressReporter logger);
|
||||
interface ConfiguratorContext {
|
||||
@NotNull CommandLineInspectionProgressReporter getLogger();
|
||||
|
||||
/**
|
||||
* Invoked before a project is imported.
|
||||
*/
|
||||
default void configureEnvironment(@NotNull Path projectPath, @NotNull CommandLineInspectionProgressReporter logger) {
|
||||
/**
|
||||
* progress indicator can be used in the actions to report updates or check for cancellation
|
||||
*/
|
||||
@NotNull ProgressIndicator getProgressIndicator();
|
||||
|
||||
/**
|
||||
* Project that is about to be open
|
||||
*/
|
||||
@NotNull Path getProjectPath();
|
||||
|
||||
/**
|
||||
* Use this filter in the implementation to avoid configuring parts of the project
|
||||
* that are not intended to be (e.g. testData). It is up to user to provide filters.
|
||||
*
|
||||
* @see PatchProjectUtil#patchProject(com.intellij.openapi.project.Project)
|
||||
*/
|
||||
@NotNull Predicate<Path> getFilesFilter();
|
||||
|
||||
/**
|
||||
* The same predicate as {@link #getFilesFilter()} but for {@link VirtualFile}
|
||||
*/
|
||||
default @NotNull Predicate<VirtualFile> getVirtualFilesFilter() {
|
||||
Predicate<Path> filesPredicate = getFilesFilter();
|
||||
return file -> {
|
||||
Path path = file.getFileSystem().getNioPath(file);
|
||||
return path != null && filesPredicate.test(path);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to grab additional information from the context about the current inspections running,
|
||||
* if available
|
||||
*/
|
||||
@Nullable
|
||||
default AnalysisScope getAnalyzerScope() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is for {@link #isApplicable(Path, CommandLineInspectionProgressReporter)} inspections
|
||||
* after project is opened. In addition to the method, you may implement the
|
||||
* {@link #configureProject(Project, AnalysisScope, CommandLineInspectionProgressReporter)}
|
||||
* that is executed to prepare inspections run.
|
||||
*
|
||||
* @see #configureProject(Project, AnalysisScope, CommandLineInspectionProgressReporter)
|
||||
* @returns true if any additional configuration is required to inspect the project at the given path.
|
||||
*/
|
||||
default void configureProject(@NotNull Project project, @NotNull CommandLineInspectionProgressReporter logger) {
|
||||
|
||||
default boolean isApplicable(@NotNull ConfiguratorContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked after the project has been imported and before the analysis on the specified scope
|
||||
* is started.
|
||||
*
|
||||
* @see #configureProject(Project, CommandLineInspectionProgressReporter)
|
||||
* Invoked before a project is imported on the project directory. Only for {@link #isApplicable(ConfiguratorContext)}
|
||||
* extensions
|
||||
*/
|
||||
default void configureProject(@NotNull Project project, @NotNull AnalysisScope scope, @NotNull CommandLineInspectionProgressReporter logger) {
|
||||
configureProject(project, logger);
|
||||
default void configureEnvironment(@NotNull ConfiguratorContext context) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is for {@link #isApplicable(ConfiguratorContext)} inspections
|
||||
* after project is opened.
|
||||
*/
|
||||
default void configureProject(@NotNull Project project,
|
||||
@NotNull ConfiguratorContext context) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.plugins.gradle
|
||||
|
||||
import com.intellij.analysis.AnalysisScope
|
||||
import com.intellij.ide.CommandLineInspectionProgressReporter
|
||||
import com.intellij.ide.CommandLineInspectionProjectConfigurator
|
||||
import com.intellij.ide.CommandLineInspectionProjectConfigurator.ConfiguratorContext
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode.MODAL_SYNC
|
||||
@@ -17,25 +16,16 @@ import org.jetbrains.plugins.gradle.settings.GradleImportHintService
|
||||
import org.jetbrains.plugins.gradle.settings.GradleSettings
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
|
||||
class GradleCommandLineProjectConfigurator : CommandLineInspectionProjectConfigurator {
|
||||
private val LOG = Logger.getInstance(GradleManager::class.java)
|
||||
|
||||
private var wasAlreadyImported = false
|
||||
|
||||
override fun isApplicable(projectPath: Path, logger: CommandLineInspectionProgressReporter): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun configureEnvironment(projectPath: Path, logger: CommandLineInspectionProgressReporter) {
|
||||
wasAlreadyImported = projectPath.resolve(".idea").exists()
|
||||
override fun configureEnvironment(context: ConfiguratorContext) = context.run {
|
||||
Registry.get("external.system.auto.import.disabled").setValue(true)
|
||||
}
|
||||
|
||||
override fun configureProject(project: Project, logger: CommandLineInspectionProgressReporter) {
|
||||
override fun configureProject(project: Project, context: ConfiguratorContext) {
|
||||
val basePath = project.basePath ?: return
|
||||
|
||||
val state = GradleImportHintService.getInstance(project).state
|
||||
|
||||
if (state.skip) return
|
||||
@@ -50,6 +40,8 @@ class GradleCommandLineProjectConfigurator : CommandLineInspectionProjectConfigu
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val wasAlreadyImported = context.projectPath.resolve(".idea").exists()
|
||||
if (wasAlreadyImported && !GradleSettings.getInstance(project).linkedProjectsSettings.isEmpty()) {
|
||||
refreshProjects(ImportSpecBuilder(project, GradleConstants.SYSTEM_ID).use(MODAL_SYNC))
|
||||
return
|
||||
|
||||
@@ -27,16 +27,16 @@ import java.util.List;
|
||||
|
||||
public class PythonPluginCommandLineInspectionProjectConfigurator implements CommandLineInspectionProjectConfigurator {
|
||||
@Override
|
||||
public boolean isApplicable(@NotNull Path projectPath, @NotNull CommandLineInspectionProgressReporter logger) {
|
||||
public boolean isApplicable(@NotNull ConfiguratorContext context) {
|
||||
List<Sdk> sdks = PythonSdkUtil.getAllSdks();
|
||||
if (!sdks.isEmpty()) return false;
|
||||
|
||||
try {
|
||||
boolean hasAnyPythonFiles = Files.walk(projectPath).anyMatch(f -> {
|
||||
boolean hasAnyPythonFiles = Files.walk(context.getProjectPath()).anyMatch(f -> {
|
||||
return f.toString().endsWith(".py");
|
||||
});
|
||||
if (!hasAnyPythonFiles) {
|
||||
logger.reportMessage(3, "Skipping Python interpreter autodetection because the project doesn't contain any Python files");
|
||||
context.getLogger().reportMessage(3, "Skipping Python interpreter autodetection because the project doesn't contain any Python files");
|
||||
}
|
||||
|
||||
return hasAnyPythonFiles;
|
||||
@@ -47,7 +47,8 @@ public class PythonPluginCommandLineInspectionProjectConfigurator implements Com
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureEnvironment(@NotNull Path projectPath, @NotNull CommandLineInspectionProgressReporter logger) {
|
||||
public void configureEnvironment(@NotNull ConfiguratorContext context) {
|
||||
CommandLineInspectionProgressReporter logger = context.getLogger();
|
||||
logger.reportMessage(3, "Python environment configuration...");
|
||||
List<Sdk> sdks = PythonSdkUtil.getAllSdks();
|
||||
logger.reportMessage(3, "Python interpreters detected:");
|
||||
@@ -55,7 +56,7 @@ public class PythonPluginCommandLineInspectionProjectConfigurator implements Com
|
||||
logger.reportMessage(3, sdk.getHomePath());
|
||||
}
|
||||
if (sdks.isEmpty()) {
|
||||
final List<Sdk> detectedSdks = PySdkExtKt.findAllPythonSdks(projectPath);
|
||||
final List<Sdk> detectedSdks = PySdkExtKt.findAllPythonSdks(context.getProjectPath());
|
||||
|
||||
if (detectedSdks.size() > 0) {
|
||||
for (Sdk sdk : detectedSdks) {
|
||||
@@ -76,21 +77,22 @@ public class PythonPluginCommandLineInspectionProjectConfigurator implements Com
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureProject(@NotNull Project project,
|
||||
@NotNull AnalysisScope scope,
|
||||
@NotNull CommandLineInspectionProgressReporter logger) {
|
||||
public void configureProject(@NotNull Project project, @NotNull ConfiguratorContext context) {
|
||||
List<Sdk> sdks = PythonSdkUtil.getAllSdks();
|
||||
if (!sdks.isEmpty()) {
|
||||
PythonFacetType facetType = PythonFacetType.getInstance();
|
||||
for (VirtualFile f : scope.getFiles()) {
|
||||
if (FileTypeRegistry.getInstance().isFileOfType(f, PythonFileType.INSTANCE)) {
|
||||
if (sdks.isEmpty()) return;
|
||||
|
||||
Module m = ModuleUtilCore.findModuleForFile(f, project);
|
||||
if (m != null && FacetManager.getInstance(m).getFacetByType(facetType.getId()) == null) {
|
||||
WriteAction.runAndWait(() -> {
|
||||
FacetManager.getInstance(m).addFacet(facetType, facetType.getPresentableName(), null);
|
||||
});
|
||||
}
|
||||
AnalysisScope scope = context.getAnalyzerScope();
|
||||
if (scope == null) return;
|
||||
|
||||
PythonFacetType facetType = PythonFacetType.getInstance();
|
||||
for (VirtualFile f : scope.getFiles()) {
|
||||
if (FileTypeRegistry.getInstance().isFileOfType(f, PythonFileType.INSTANCE)) {
|
||||
|
||||
Module m = ModuleUtilCore.findModuleForFile(f, project);
|
||||
if (m != null && FacetManager.getInstance(m).getFacetByType(facetType.getId()) == null) {
|
||||
WriteAction.runAndWait(() -> {
|
||||
FacetManager.getInstance(m).addFacet(facetType, facetType.getPresentableName(), null);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user