KT-11701 Add Maven Dependency quick fix could be supported in Kotlin sources
~ initial draft
This commit is contained in:
@@ -24,6 +24,8 @@
|
||||
<className>org.jetbrains.kotlin.idea.configuration.MavenPluginSourcesMoveToExecutionIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
<codeInsight.unresolvedReferenceQuickFixProvider
|
||||
implementation="org.jetbrains.kotlin.idea.configuration.KotlinMavenUnresolvedReferenceQuickFixProvider" />
|
||||
</extensions>
|
||||
|
||||
<module-components>
|
||||
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.configuration
|
||||
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey
|
||||
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInsight.intention.LowPriorityAction
|
||||
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.util.Condition
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.SmartPsiElementPointer
|
||||
import com.intellij.psi.xml.XmlFile
|
||||
import org.jetbrains.idea.maven.dom.MavenDomUtil
|
||||
import org.jetbrains.idea.maven.indices.MavenArtifactSearchDialog
|
||||
import org.jetbrains.idea.maven.project.MavenProjectsManager
|
||||
import org.jetbrains.idea.maven.utils.MavenArtifactScope
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
|
||||
import org.jetbrains.kotlin.idea.quickfix.IntentionActionPriority
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionFactoryWithDelegate
|
||||
import org.jetbrains.kotlin.idea.quickfix.QuickFixWithDelegateFactory
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import java.util.*
|
||||
|
||||
class KotlinMavenUnresolvedReferenceQuickFixProvider : UnresolvedReferenceQuickFixProvider<KtSimpleNameReference>() {
|
||||
override fun getReferenceClass(): Class<KtSimpleNameReference> = KtSimpleNameReference::class.java
|
||||
|
||||
override fun registerFixes(ref: KtSimpleNameReference, registrar: QuickFixActionRegistrar) {
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(ref.expression) ?: return
|
||||
if (!MavenProjectsManager.getInstance(module.project).isMavenizedModule(module)) {
|
||||
return
|
||||
}
|
||||
|
||||
val expression = ref.expression
|
||||
val importDirective = expression.getParentOfType<KtImportDirective>(true)
|
||||
|
||||
val name = if (importDirective != null) {
|
||||
if (importDirective.isAllUnder) {
|
||||
null
|
||||
} else {
|
||||
importDirective.importedFqName?.asString()
|
||||
}
|
||||
}
|
||||
else {
|
||||
val typeReference = expression.getParentOfType<KtTypeReference>(true)
|
||||
val referenced = typeReference?.text ?: expression.getReferencedName()
|
||||
|
||||
expression.getContainingKtFile()
|
||||
.importDirectives
|
||||
.firstOrNull { !it.isAllUnder && it.aliasName == referenced || it.importedFqName?.shortName()?.asString() == referenced }
|
||||
?.let { it.importedFqName?.asString() }
|
||||
?: referenced
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
registrar.register(AddMavenDependencyQuickFix(name, expression.createSmartPointer()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AddMavenDependencyQuickFix(val className: String, val smartPsiElementPointer: SmartPsiElementPointer<KtSimpleNameExpression>) : IntentionAction, LowPriorityAction {
|
||||
override fun getText() = "Add dependency..."
|
||||
override fun getFamilyName() = "Kotlin"
|
||||
override fun startInWriteAction() = false
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?) =
|
||||
smartPsiElementPointer.element.let { it != null && it.isValid } && file != null && MavenDomUtil.findContainingProject(file) != null
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
|
||||
if (editor == null || file == null) {
|
||||
return
|
||||
}
|
||||
|
||||
val virtualFile = file.originalFile.virtualFile ?: return
|
||||
val mavenProject = MavenDomUtil.findContainingProject(file) ?: return
|
||||
val xmlFile = PsiManager.getInstance(project).findFile(mavenProject.file) as? XmlFile ?: return
|
||||
|
||||
val ids = MavenArtifactSearchDialog.searchForClass(project, className)
|
||||
if (ids.isEmpty()) return
|
||||
|
||||
runWriteAction {
|
||||
val isTestSource = ProjectRootManager.getInstance(project).fileIndex.isInTestSourceContent(virtualFile)
|
||||
val scope = if (isTestSource) MavenArtifactScope.TEST else null
|
||||
|
||||
val pom = PomFile(xmlFile)
|
||||
|
||||
ids.forEach {
|
||||
pom.addDependency(it, scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object PlatformUnresolvedProvider : KotlinIntentionActionFactoryWithDelegate<KtNameReferenceExpression, String>() {
|
||||
override fun getElementOfInterest(diagnostic: Diagnostic) = QuickFixUtil.getParentElementOfType(diagnostic, KtNameReferenceExpression::class.java)
|
||||
override fun extractFixData(element: KtNameReferenceExpression, diagnostic: Diagnostic) = element.getReferencedName()
|
||||
|
||||
override fun createFixes(originalElementPointer: SmartPsiElementPointer<KtNameReferenceExpression>, diagnostic: Diagnostic, quickFixDataFactory: () -> String?): List<QuickFixWithDelegateFactory> {
|
||||
val result = ArrayList<QuickFixWithDelegateFactory>()
|
||||
|
||||
originalElementPointer.element?.references?.filterIsInstance<KtSimpleNameReference>()?.firstOrNull()?.let { reference ->
|
||||
UnresolvedReferenceQuickFixProvider.registerReferenceFixes(reference, object: QuickFixActionRegistrar {
|
||||
override fun register(action: IntentionAction) {
|
||||
result.add(QuickFixWithDelegateFactory(IntentionActionPriority.LOW) { action } )
|
||||
}
|
||||
|
||||
override fun register(fixRange: TextRange, action: IntentionAction, key: HighlightDisplayKey?) {
|
||||
register(action)
|
||||
}
|
||||
|
||||
override fun unregister(condition: Condition<IntentionAction>) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.quickfix
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||
import org.jetbrains.kotlin.idea.configuration.PlatformUnresolvedProvider
|
||||
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementAsConstructorParameter
|
||||
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler
|
||||
import org.jetbrains.kotlin.idea.inspections.AddModifierFixFactory
|
||||
@@ -318,7 +319,8 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
|
||||
UNRESOLVED_REFERENCE.registerFactory(CreateClassFromTypeReferenceActionFactory,
|
||||
CreateClassFromReferenceExpressionActionFactory,
|
||||
CreateClassFromCallWithConstructorCalleeActionFactory)
|
||||
CreateClassFromCallWithConstructorCalleeActionFactory,
|
||||
PlatformUnresolvedProvider)
|
||||
|
||||
PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.registerFactory(InsertDelegationCallQuickfix.InsertThisDelegationCallFactory)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user