Quick Fixes: Implement quickfix for missing library
This commit is contained in:
Generated
+1
@@ -6,6 +6,7 @@
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/testng/lib/testng-plugin.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/testng/lib/testng.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/testng/lib/jcommander.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
|
||||
+38
-29
@@ -25,8 +25,10 @@ import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.js.KotlinJavaScriptLibraryManager;
|
||||
import org.jetbrains.kotlin.idea.util.application.ApplicationUtilsKt;
|
||||
import org.jetbrains.kotlin.utils.PathUtil;
|
||||
|
||||
import java.io.File;
|
||||
@@ -121,42 +123,49 @@ public class ConfigLibraryUtil {
|
||||
}
|
||||
|
||||
|
||||
public static void removeLibrary(@NotNull final Module module, @NotNull final String libraryName) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
|
||||
ModifiableRootModel model = rootManager.getModifiableModel();
|
||||
public static boolean removeLibrary(@NotNull final Module module, @NotNull final String libraryName) {
|
||||
return ApplicationUtilsKt.runWriteAction(
|
||||
new Function0<Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke() {
|
||||
boolean removed = false;
|
||||
|
||||
for (OrderEntry orderEntry : model.getOrderEntries()) {
|
||||
if (orderEntry instanceof LibraryOrderEntry) {
|
||||
LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry) orderEntry;
|
||||
ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
|
||||
ModifiableRootModel model = rootManager.getModifiableModel();
|
||||
|
||||
Library library = libraryOrderEntry.getLibrary();
|
||||
if (library != null) {
|
||||
String name = library.getName();
|
||||
if (name != null && name.equals(libraryName)) {
|
||||
for (OrderEntry orderEntry : model.getOrderEntries()) {
|
||||
if (orderEntry instanceof LibraryOrderEntry) {
|
||||
LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry) orderEntry;
|
||||
|
||||
// Dispose attached roots
|
||||
Library.ModifiableModel modifiableModel = library.getModifiableModel();
|
||||
for (String rootUrl : library.getRootProvider().getUrls(OrderRootType.CLASSES)) {
|
||||
modifiableModel.removeRoot(rootUrl, OrderRootType.CLASSES);
|
||||
Library library = libraryOrderEntry.getLibrary();
|
||||
if (library != null) {
|
||||
String name = library.getName();
|
||||
if (name != null && name.equals(libraryName)) {
|
||||
|
||||
// Dispose attached roots
|
||||
Library.ModifiableModel modifiableModel = library.getModifiableModel();
|
||||
for (String rootUrl : library.getRootProvider().getUrls(OrderRootType.CLASSES)) {
|
||||
modifiableModel.removeRoot(rootUrl, OrderRootType.CLASSES);
|
||||
}
|
||||
for (String rootUrl : library.getRootProvider().getUrls(OrderRootType.SOURCES)) {
|
||||
modifiableModel.removeRoot(rootUrl, OrderRootType.SOURCES);
|
||||
}
|
||||
modifiableModel.commit();
|
||||
|
||||
model.getModuleLibraryTable().removeLibrary(library);
|
||||
|
||||
removed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (String rootUrl : library.getRootProvider().getUrls(OrderRootType.SOURCES)) {
|
||||
modifiableModel.removeRoot(rootUrl, OrderRootType.SOURCES);
|
||||
}
|
||||
modifiableModel.commit();
|
||||
|
||||
model.getModuleLibraryTable().removeLibrary(library);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
model.commit();
|
||||
|
||||
return removed;
|
||||
}
|
||||
}
|
||||
|
||||
model.commit();
|
||||
}
|
||||
});
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.quickfix
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixActionRegistrarImpl
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.PsiReferenceBase
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference.ShorteningMode
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.JetElement
|
||||
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElement
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public object KotlinAddOrderEntryActionFactory : JetIntentionActionsFactory() {
|
||||
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
|
||||
val simpleExpression = diagnostic.psiElement as? JetSimpleNameExpression ?: return emptyList()
|
||||
val refElement = simpleExpression.getQualifiedElement()
|
||||
|
||||
val reference = object: PsiReferenceBase<JetElement>(refElement) {
|
||||
override fun resolve() = null
|
||||
|
||||
override fun getVariants() = PsiReference.EMPTY_ARRAY
|
||||
|
||||
override fun getRangeInElement(): TextRange? {
|
||||
val offset = simpleExpression.startOffset - refElement.startOffset
|
||||
return TextRange(offset, offset + simpleExpression.textLength)
|
||||
}
|
||||
|
||||
override fun getCanonicalText() = refElement.text
|
||||
|
||||
override fun bindToElement(element: PsiElement): PsiElement {
|
||||
return simpleExpression.mainReference.bindToElement(element, ShorteningMode.FORCED_SHORTENING)
|
||||
}
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return OrderEntryFix.registerFixes(QuickFixActionRegistrarImpl(null), reference) as List<IntentionAction>? ?: emptyList()
|
||||
}
|
||||
}
|
||||
@@ -338,5 +338,7 @@ public class QuickFixRegistrar : QuickFixContributor {
|
||||
CALLABLE_REFERENCE_TO_MEMBER_OR_EXTENSION_WITH_EMPTY_LHS.registerFactory(AddTypeToLHSOfCallableReferenceFix)
|
||||
|
||||
DEPRECATED_TYPE_PARAMETER_SYNTAX.registerFactory(MigrateTypeParameterListFix)
|
||||
|
||||
UNRESOLVED_REFERENCE.registerFactory(KotlinAddOrderEntryActionFactory)
|
||||
}
|
||||
}
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Add 'JUnit4' to classpath" "true"
|
||||
// ERROR: Unresolved reference: Before
|
||||
// ERROR: Unresolved reference: junit
|
||||
// UNCONFIGURE_LIBRARY: JUnit4
|
||||
package some
|
||||
|
||||
import org.<caret>junit.Before
|
||||
|
||||
open class KBase {
|
||||
@Before
|
||||
fun setUp() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Add 'JUnit4' to classpath" "true"
|
||||
// ERROR: Unresolved reference: Before
|
||||
// ERROR: Unresolved reference: junit
|
||||
// UNCONFIGURE_LIBRARY: JUnit4
|
||||
package some
|
||||
|
||||
import org.junit.Before
|
||||
|
||||
open class KBase {
|
||||
@Before
|
||||
fun setUp() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Add 'testng' to classpath" "true"
|
||||
// ERROR: Unresolved reference: BeforeMethod
|
||||
// ERROR: Unresolved reference: testng
|
||||
// UNCONFIGURE_LIBRARY: testng
|
||||
package some
|
||||
|
||||
abstract class KBase {
|
||||
@<caret>BeforeMethod
|
||||
fun setUp() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// "Add 'testng' to classpath" "true"
|
||||
// ERROR: Unresolved reference: BeforeMethod
|
||||
// ERROR: Unresolved reference: testng
|
||||
// UNCONFIGURE_LIBRARY: testng
|
||||
package some
|
||||
|
||||
import org.testng.annotations.BeforeMethod
|
||||
|
||||
abstract class KBase {
|
||||
@BeforeMethod
|
||||
fun setUp() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import com.intellij.codeInspection.SuppressableProblemGroup;
|
||||
import com.intellij.ide.startup.impl.StartupManagerImpl;
|
||||
import com.intellij.lang.annotation.ProblemGroup;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.projectRoots.JavaSdk;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
@@ -95,8 +96,10 @@ public abstract class AbstractQuickFixTest extends KotlinLightQuickFixTestCase {
|
||||
@SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod", "CallToPrintStackTrace"})
|
||||
@Override
|
||||
public void run() {
|
||||
String fileText = "";
|
||||
try {
|
||||
String contents = StringUtil.convertLineSeparators(FileUtil.loadFile(testFile, CharsetToolkit.UTF8_CHARSET));
|
||||
fileText = FileUtil.loadFile(testFile, CharsetToolkit.UTF8_CHARSET);
|
||||
String contents = StringUtil.convertLineSeparators(fileText);
|
||||
quickFixTestCase.configureFromFileText(testFile.getName(), contents);
|
||||
quickFixTestCase.bringRealEditorBack();
|
||||
|
||||
@@ -110,11 +113,21 @@ public abstract class AbstractQuickFixTest extends KotlinLightQuickFixTestCase {
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
fail(testName);
|
||||
} finally {
|
||||
unconfigureLibrariesAsSpecified(fileText);
|
||||
}
|
||||
}
|
||||
}, "", "");
|
||||
}
|
||||
|
||||
private static void unconfigureLibrariesAsSpecified(String fileText) {
|
||||
Module module = getModule();
|
||||
for (String libraryName : InTextDirectivesUtils.findListWithPrefixes(fileText, "// UNCONFIGURE_LIBRARY: ")) {
|
||||
if (ConfigLibraryUtil.removeLibrary(module, libraryName)) continue;
|
||||
fail("Library '" + libraryName + "' wasn't found");
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyAction(String contents, QuickFixTestCase quickFixTestCase, String testName, String testFullPath) throws Exception {
|
||||
Pair<String, Boolean> pair = quickFixTestCase.parseActionHintImpl(quickFixTestCase.getFile(), contents);
|
||||
String text = pair.getFirst();
|
||||
|
||||
@@ -4077,6 +4077,27 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/libraries")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Libraries extends AbstractQuickFixTest {
|
||||
public void testAllFilesPresentInLibraries() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/libraries"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("junit.kt")
|
||||
public void testJunit() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/libraries/junit.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("testNG.kt")
|
||||
public void testTestNG() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/libraries/testNG.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/migration")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user