diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinWithGradleConfigurator.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinWithGradleConfigurator.kt index 1dbbe52ccb9..2b0460a6c49 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinWithGradleConfigurator.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinWithGradleConfigurator.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.idea.configuration import com.intellij.codeInsight.CodeInsightUtilCore +import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix import com.intellij.ide.actions.OpenFileAction import com.intellij.openapi.extensions.Extensions import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil @@ -43,6 +44,7 @@ import org.jetbrains.kotlin.idea.framework.ui.ConfigureDialogWithModulesAndVersi import org.jetbrains.kotlin.idea.quickfix.ChangeCoroutineSupportFix import org.jetbrains.kotlin.idea.util.application.executeCommand import org.jetbrains.kotlin.idea.util.application.executeWriteCommand +import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor import org.jetbrains.kotlin.idea.versions.getStdlibArtifactId import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.plugins.gradle.util.GradleConstants @@ -227,6 +229,11 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator { } } + override fun addLibraryDependency(module: Module, element: PsiElement, library: ExternalLibraryDescriptor, libraryJarDescriptors: List) { + val scope = OrderEntryFix.suggestScopeByLocation(module, element) + KotlinWithGradleConfigurator.addKotlinLibraryToModule(module, scope, library) + } + companion object { fun getManipulator(file: PsiFile): GradleBuildScriptManipulator = when (file) { is KtFile -> KotlinBuildScriptManipulator(file) diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt index ea5bbe39ffe..5f18dc2f4b9 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.idea.maven.configuration import com.intellij.codeInsight.CodeInsightUtilCore +import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix import com.intellij.ide.actions.OpenFileAction import com.intellij.ide.highlighter.JavaFileType import com.intellij.openapi.command.WriteCommandAction @@ -24,6 +25,8 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleUtilCore import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ExternalLibraryDescriptor +import com.intellij.openapi.roots.JavaProjectModelModificationService import com.intellij.openapi.ui.Messages import com.intellij.openapi.vfs.WritingAccessProvider import com.intellij.psi.PsiElement @@ -47,6 +50,7 @@ import org.jetbrains.kotlin.idea.framework.ui.ConfigureDialogWithModulesAndVersi import org.jetbrains.kotlin.idea.maven.* import org.jetbrains.kotlin.idea.quickfix.ChangeCoroutineSupportFix import org.jetbrains.kotlin.idea.util.application.runReadAction +import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor abstract class KotlinMavenConfigurator protected constructor(private val testArtifactId: String?, @@ -230,6 +234,11 @@ abstract class KotlinMavenConfigurator } } + override fun addLibraryDependency(module: Module, element: PsiElement, library: ExternalLibraryDescriptor, libraryJarDescriptors: List) { + val scope = OrderEntryFix.suggestScopeByLocation(module, element) + JavaProjectModelModificationService.getInstance(module.project).addDependency(module, library, scope) + } + override fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) { val runtimeUpdateRequired = state != LanguageFeature.State.DISABLED && (getRuntimeLibraryVersion(module)?.startsWith("1.0") ?: false) diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt index 527cc6d1d34..b09f295f6cd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt @@ -19,8 +19,11 @@ package org.jetbrains.kotlin.idea.configuration import com.intellij.openapi.extensions.ExtensionPointName import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ExternalLibraryDescriptor +import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor import org.jetbrains.kotlin.resolve.TargetPlatform enum class ConfigureKotlinStatus { @@ -53,6 +56,8 @@ interface KotlinProjectConfigurator { fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) + fun addLibraryDependency(module: Module, element: PsiElement, library: ExternalLibraryDescriptor, libraryJarDescriptors: List) + companion object { val EP_NAME = ExtensionPointName.create("org.jetbrains.kotlin.projectConfigurator") } diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt index 7e3d12d6a86..fd803ac4185 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt @@ -27,6 +27,7 @@ import com.intellij.openapi.vfs.JarFileSystem import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VfsUtilCore +import com.intellij.psi.PsiElement import org.jetbrains.annotations.Contract import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider @@ -39,12 +40,12 @@ import org.jetbrains.kotlin.idea.framework.ui.FileUIUtils import org.jetbrains.kotlin.idea.quickfix.askUpdateRuntime import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor +import org.jetbrains.kotlin.idea.versions.findAllUsedLibraries import org.jetbrains.kotlin.idea.versions.findKotlinRuntimeLibrary import java.io.File import java.util.* abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProjectConfigurator { - protected abstract val libraryName: String protected abstract val messageForOverrideDialog: String @@ -369,6 +370,38 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj } } + override fun addLibraryDependency(module: Module, element: PsiElement, library: ExternalLibraryDescriptor, libraryJarDescriptors: List) { + val project = module.project + val collector = createConfigureKotlinNotificationCollector(project) + + for (library in findAllUsedLibraries(project).keySet()) { + val runtimeJar = LibraryJarDescriptor.RUNTIME_JAR.findExistingJar(library) ?: continue + + val model = library.modifiableModel + val libFilesDir = VfsUtilCore.virtualToIoFile(runtimeJar).parent + + for (libraryJarDescriptor in libraryJarDescriptors) { + if (libraryJarDescriptor.findExistingJar(library) != null) continue + + val libFile = libraryJarDescriptor.getPathInPlugin() + if (!libFile.exists()) continue + + val libIoFile = File(libFilesDir, libraryJarDescriptor.jarName) + if (libIoFile.exists()) { + model.addRoot(VfsUtil.getUrlForLibraryRoot(libIoFile), libraryJarDescriptor.orderRootType) + } + else { + val copied = copyFileToDir(libFile, libFilesDir, collector)!! + model.addRoot(VfsUtil.getUrlForLibraryRoot(copied), libraryJarDescriptor.orderRootType) + } + } + + model.commit() + } + + collector.showNotification() + } + companion object { val DEFAULT_LIBRARY_DIR = "lib" diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/AddKotlinLibQuickFix.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/AddKotlinLibQuickFix.kt index 4865fb64161..9435064f07f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/AddKotlinLibQuickFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/AddKotlinLibQuickFix.kt @@ -16,36 +16,29 @@ package org.jetbrains.kotlin.idea.inspections -import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix import com.intellij.codeInsight.intention.IntentionAction import com.intellij.openapi.editor.Editor import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ExternalLibraryDescriptor -import com.intellij.openapi.roots.JavaProjectModelModificationService import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory -import com.intellij.openapi.vfs.VfsUtil -import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinPluginUtil -import org.jetbrains.kotlin.idea.configuration.KotlinJavaModuleConfigurator import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator -import org.jetbrains.kotlin.idea.configuration.createConfigureKotlinNotificationCollector +import org.jetbrains.kotlin.idea.configuration.findApplicableConfigurator import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory import org.jetbrains.kotlin.idea.quickfix.quickfixUtil.createIntentionForFirstParentOfType import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion -import org.jetbrains.kotlin.idea.versions.findAllUsedLibraries import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtImportDirective -import java.io.File class AddReflectionQuickFix(element: KtElement) : AddKotlinLibQuickFix(element, listOf(LibraryJarDescriptor.REFLECT_JAR, @@ -124,53 +117,10 @@ abstract class AddKotlinLibQuickFix(element: KtElement, override fun invoke(project: Project, editor: Editor?, file: KtFile) { val element = element ?: return - val module = ProjectRootManager.getInstance(project).fileIndex.getModuleForFile(element.containingFile.virtualFile) - if (module != null) { - if (KotlinPluginUtil.isMavenModule(module)) { - val scope = OrderEntryFix.suggestScopeByLocation(module, element) - JavaProjectModelModificationService.getInstance(project).addDependency(module, getLibraryDescriptor(module), scope) + val module = ProjectRootManager.getInstance(project).fileIndex.getModuleForFile(element.containingFile.virtualFile) ?: return - return - } - - if (KotlinPluginUtil.isGradleModule(module) || KotlinPluginUtil.isAndroidGradleModule(module)) { - val scope = OrderEntryFix.suggestScopeByLocation(module, element) - KotlinWithGradleConfigurator.addKotlinLibraryToModule(module, scope, getLibraryDescriptor(module)) - - return - } - } - - val configurator = KotlinJavaModuleConfigurator.instance - - val collector = createConfigureKotlinNotificationCollector(project) - - for (library in findAllUsedLibraries(project).keySet()) { - val runtimeJar = LibraryJarDescriptor.RUNTIME_JAR.findExistingJar(library) ?: continue - - val model = library.modifiableModel - val libFilesDir = VfsUtilCore.virtualToIoFile(runtimeJar).parent - - for (libraryJarDescriptor in libraryJarDescriptors) { - if (libraryJarDescriptor.findExistingJar(library) != null) continue - - val libFile = libraryJarDescriptor.getPathInPlugin() - if (!libFile.exists()) continue - - val libIoFile = File(libFilesDir, libraryJarDescriptor.jarName) - if (libIoFile.exists()) { - model.addRoot(VfsUtil.getUrlForLibraryRoot(libIoFile), libraryJarDescriptor.orderRootType) - } - else { - val copied = configurator.copyFileToDir(libFile, libFilesDir, collector)!! - model.addRoot(VfsUtil.getUrlForLibraryRoot(copied), libraryJarDescriptor.orderRootType) - } - } - - model.commit() - } - - collector.showNotification() + val configurator = findApplicableConfigurator(module) + configurator.addLibraryDependency(module, element, getLibraryDescriptor(module), libraryJarDescriptors) } companion object {