Add kotlin-test.jar to classpath quickfix

This commit is contained in:
Nikolay Krasko
2015-12-21 22:22:31 +03:00
parent 99966c17da
commit 1b92fa94bc
4 changed files with 68 additions and 18 deletions
@@ -263,6 +263,7 @@ suppress.warning.for=Suppress ''{0}'' for {1} {2}
reflection.not.found=Reflection not found in the classpath reflection.not.found=Reflection not found in the classpath
add.reflection.to.classpath=Add kotlin-reflect.jar to the classpath add.reflection.to.classpath=Add kotlin-reflect.jar to the classpath
add.test.to.classpath=Add kotlin-test.jar to the classpath
# Kotlin Compiler Settings Tab # Kotlin Compiler Settings Tab
@@ -72,4 +72,9 @@ public class JavaRuntimePresentationProvider extends LibraryPresentationProvider
public static VirtualFile getRuntimeSrcJar(@NotNull Library library) { public static VirtualFile getRuntimeSrcJar(@NotNull Library library) {
return getRuntimeSrcJar(Arrays.asList(library.getFiles(OrderRootType.SOURCES))); return getRuntimeSrcJar(Arrays.asList(library.getFiles(OrderRootType.SOURCES)));
} }
@Nullable
public static VirtualFile getTestJar(@NotNull Library library) {
return LibraryUtils.getJarFile(Arrays.asList(library.getFiles(OrderRootType.CLASSES)), PathUtil.KOTLIN_TEST_JAR);
}
} }
@@ -16,13 +16,16 @@
package org.jetbrains.kotlin.idea.inspections package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.extensions.Extensions import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VfsUtilCore
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.configuration.ConfigureKotlinInProjectUtils import org.jetbrains.kotlin.idea.configuration.ConfigureKotlinInProjectUtils
import org.jetbrains.kotlin.idea.configuration.KotlinJavaModuleConfigurator import org.jetbrains.kotlin.idea.configuration.KotlinJavaModuleConfigurator
@@ -38,42 +41,80 @@ import org.jetbrains.kotlin.utils.PathUtil
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.io.File import java.io.File
public class AddReflectionQuickFix(element: KtElement) : KotlinQuickFixAction<KtElement>(element) { public class AddReflectionQuickFix(element: KtElement) : AddKotlinLibQuickFix(element) {
override fun getText() = KotlinBundle.message("add.reflection.to.classpath") override fun getText() = KotlinBundle.message("add.reflection.to.classpath")
override fun getFamilyName() = getText() override fun getFamilyName() = text
override fun libraryPath(): String = PathUtil.KOTLIN_JAVA_REFLECT_JAR
override fun getLibFile(): File = PathUtil.getKotlinPathsForIdeaPlugin().getReflectPath()
override fun hasLibJarInLibrary(library: Library): Boolean = JavaRuntimePresentationProvider.getReflectJar(library) != null
companion object : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic) = diagnostic.createIntentionForFirstParentOfType(::AddReflectionQuickFix)
}
}
public class AddTestLibQuickFix(element: KtElement) : AddKotlinLibQuickFix(element) {
override fun getText() = KotlinBundle.message("add.test.to.classpath")
override fun getFamilyName() = text
override fun libraryPath(): String = PathUtil.KOTLIN_TEST_JAR
override fun getLibFile(): File = PathUtil.getKotlinPathsForIdeaPlugin().kotlinTestPath
override fun hasLibJarInLibrary(library: Library): Boolean = JavaRuntimePresentationProvider.getTestJar(library) != null
companion object : KotlinSingleIntentionActionFactory() {
val KOTLIN_TEST_UNRESOLVED = setOf(
"Asserter", "assertFailsWith", "currentStackTrace", "failsWith", "todo", "assertEquals",
"assertFails", "assertNot", "assertNotEquals", "assertNotNull", "assertNull", "assertTrue", "expect", "fail", "fails")
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val unresolvedReference = Errors.UNRESOLVED_REFERENCE.cast(diagnostic)
if (unresolvedReference.a.text in KOTLIN_TEST_UNRESOLVED) {
val ktFile = (diagnostic.psiElement.containingFile as? KtFile) ?: return null
if (ktFile.importDirectives.none { it.text.contains("kotlin.test.") }) return null
return diagnostic.createIntentionForFirstParentOfType(::AddTestLibQuickFix)
}
return null
}
}
}
public abstract class AddKotlinLibQuickFix(element: KtElement) : KotlinQuickFixAction<KtElement>(element) {
protected abstract fun libraryPath(): String
protected abstract fun getLibFile(): File
protected abstract fun hasLibJarInLibrary(library: Library): Boolean
override fun invoke(project: Project, editor: Editor?, file: KtFile) { override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val pluginReflectJar = PathUtil.getKotlinPathsForIdeaPlugin().getReflectPath() val libFile = getLibFile()
if (!pluginReflectJar.exists()) return if (!libFile.exists()) return
val configurator = Extensions.getExtensions(KotlinProjectConfigurator.EP_NAME) val configurator = Extensions.getExtensions(KotlinProjectConfigurator.EP_NAME)
.firstIsInstanceOrNull<KotlinJavaModuleConfigurator>() ?: return .firstIsInstanceOrNull<KotlinJavaModuleConfigurator>() ?: return
for (library in KotlinRuntimeLibraryUtil.findKotlinLibraries(project)) { for (library in KotlinRuntimeLibraryUtil.findKotlinLibraries(project)) {
val runtimeJar = JavaRuntimePresentationProvider.getRuntimeJar(library) ?: continue val runtimeJar = JavaRuntimePresentationProvider.getRuntimeJar(library) ?: continue
if (JavaRuntimePresentationProvider.getReflectJar(library) != null) continue if (hasLibJarInLibrary(library)) continue
val model = library.getModifiableModel() val model = library.modifiableModel
val libFilesDir = VfsUtilCore.virtualToIoFile(runtimeJar).getParent() val libFilesDir = VfsUtilCore.virtualToIoFile(runtimeJar).parent
val reflectIoFile = File(libFilesDir, PathUtil.KOTLIN_JAVA_REFLECT_JAR)
if (reflectIoFile.exists()) { val libIoFile = File(libFilesDir, libraryPath())
model.addRoot(VfsUtil.getUrlForLibraryRoot(reflectIoFile), OrderRootType.CLASSES) if (libIoFile.exists()) {
model.addRoot(VfsUtil.getUrlForLibraryRoot(libIoFile), OrderRootType.CLASSES)
} }
else { else {
val copied = configurator.copyFileToDir(project, pluginReflectJar, libFilesDir)!! val copied = configurator.copyFileToDir(project, libFile, libFilesDir)!!
model.addRoot(VfsUtil.getUrlForLibraryRoot(copied), OrderRootType.CLASSES) model.addRoot(VfsUtil.getUrlForLibraryRoot(copied), OrderRootType.CLASSES)
} }
model.commit() model.commit()
ConfigureKotlinInProjectUtils.showInfoNotification(project, ConfigureKotlinInProjectUtils.showInfoNotification(
"${PathUtil.KOTLIN_JAVA_REFLECT_JAR} was added to the library ${library.getName()}" project, "${libraryPath()} was added to the library ${library.name}")
)
} }
} }
companion object : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic) = diagnostic.createIntentionForFirstParentOfType(::AddReflectionQuickFix)
}
} }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler
import org.jetbrains.kotlin.idea.inspections.AddModifierFixFactory import org.jetbrains.kotlin.idea.inspections.AddModifierFixFactory
import org.jetbrains.kotlin.idea.inspections.AddReflectionQuickFix import org.jetbrains.kotlin.idea.inspections.AddReflectionQuickFix
import org.jetbrains.kotlin.idea.inspections.AddTestLibQuickFix
import org.jetbrains.kotlin.idea.inspections.InfixCallFix import org.jetbrains.kotlin.idea.inspections.InfixCallFix
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.* import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.*
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromCallWithConstructorCalleeActionFactory import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromCallWithConstructorCalleeActionFactory
@@ -125,6 +126,8 @@ public class QuickFixRegistrar : QuickFixContributor {
REPEATED_MODIFIER.registerFactory(removeModifierFactory) REPEATED_MODIFIER.registerFactory(removeModifierFactory)
UNRESOLVED_REFERENCE.registerFactory(AutoImportFix) UNRESOLVED_REFERENCE.registerFactory(AutoImportFix)
UNRESOLVED_REFERENCE.registerFactory(AddTestLibQuickFix)
UNRESOLVED_REFERENCE_WRONG_RECEIVER.registerFactory(AutoImportFix) UNRESOLVED_REFERENCE_WRONG_RECEIVER.registerFactory(AutoImportFix)
FUNCTION_EXPECTED.registerFactory(MissingInvokeAutoImportFix) FUNCTION_EXPECTED.registerFactory(MissingInvokeAutoImportFix)