Create From Usage: Do not suggest Java classes as receiver type candidates (for now)
This commit is contained in:
+10
-6
@@ -37,12 +37,16 @@ public class CreateCallableFromUsageFix(
|
|||||||
val popupTitle = JetBundle.message("choose.target.class.or.trait.title")
|
val popupTitle = JetBundle.message("choose.target.class.or.trait.title")
|
||||||
val receiverTypeCandidates = callableBuilder.computeTypeCandidates(callableInfo.receiverTypeInfo)
|
val receiverTypeCandidates = callableBuilder.computeTypeCandidates(callableInfo.receiverTypeInfo)
|
||||||
if (receiverTypeCandidates.isNotEmpty()) {
|
if (receiverTypeCandidates.isNotEmpty()) {
|
||||||
val toPsi: (TypeCandidate) -> JetClassOrObject = {
|
// TODO: Support generation of Java class members
|
||||||
val descriptor = DescriptorUtils.getClassDescriptorForType(it.theType)
|
val containers = receiverTypeCandidates
|
||||||
DescriptorToDeclarationUtil.getDeclaration(file, descriptor) as JetClassOrObject
|
.map { candidate ->
|
||||||
}
|
val descriptor = DescriptorUtils.getClassDescriptorForType(candidate.theType)
|
||||||
chooseContainerElementIfNecessary(receiverTypeCandidates, editor, popupTitle, false, toPsi) {
|
(DescriptorToDeclarationUtil.getDeclaration(file, descriptor) as? JetClassOrObject)?.let { candidate to it }
|
||||||
runBuilder(CallablePlacement.WithReceiver(it))
|
}
|
||||||
|
.filterNotNull()
|
||||||
|
|
||||||
|
chooseContainerElementIfNecessary(containers, editor, popupTitle, false, { it.second }) {
|
||||||
|
runBuilder(CallablePlacement.WithReceiver(it.first))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
// ERROR: Unresolved reference: foo
|
||||||
|
|
||||||
|
fun test(): Int {
|
||||||
|
return A().foo(1, "2")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Any.foo(i: Int, s: String): Int {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
// ERROR: Unresolved reference: foo
|
||||||
|
|
||||||
|
fun test(): Int {
|
||||||
|
return A().<caret>foo(1, "2")
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class A {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -24,8 +24,16 @@ import com.intellij.openapi.command.CommandProcessor;
|
|||||||
import com.intellij.openapi.projectRoots.Sdk;
|
import com.intellij.openapi.projectRoots.Sdk;
|
||||||
import com.intellij.openapi.util.Pair;
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
|
import com.intellij.psi.PsiFile;
|
||||||
|
import com.intellij.util.ArrayUtil;
|
||||||
|
import com.intellij.util.Function;
|
||||||
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
import com.intellij.util.ui.UIUtil;
|
import com.intellij.util.ui.UIUtil;
|
||||||
|
import jet.runtime.typeinfo.JetValueParameter;
|
||||||
import junit.framework.ComparisonFailure;
|
import junit.framework.ComparisonFailure;
|
||||||
|
import kotlin.Function1;
|
||||||
|
import kotlin.KotlinPackage;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.InTextDirectivesUtils;
|
import org.jetbrains.jet.InTextDirectivesUtils;
|
||||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
@@ -35,6 +43,7 @@ import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
|||||||
import org.jetbrains.jet.testing.ConfigLibraryUtil;
|
import org.jetbrains.jet.testing.ConfigLibraryUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -62,14 +71,44 @@ public abstract class AbstractQuickFixMultiFileTest extends KotlinDaemonAnalyzer
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void doTest(final String beforeFileName, boolean withExtraFile) throws Exception {
|
private void doTest(final String beforeFileName, boolean withExtraFile) throws Exception {
|
||||||
final String originalFileText = FileUtil.loadFile(new File(getTestDataPath() + beforeFileName), true);
|
final String testDataPath = getTestDataPath();
|
||||||
|
File mainFile = new File(testDataPath + beforeFileName);
|
||||||
|
final String originalFileText = FileUtil.loadFile(mainFile, true);
|
||||||
|
|
||||||
if (InTextDirectivesUtils.findStringWithPrefixes(originalFileText, "// WITH_RUNTIME") != null) {
|
if (InTextDirectivesUtils.findStringWithPrefixes(originalFileText, "// WITH_RUNTIME") != null) {
|
||||||
ConfigLibraryUtil.configureKotlinRuntime(myModule, PluginTestCaseBase.fullJdk());
|
ConfigLibraryUtil.configureKotlinRuntime(myModule, PluginTestCaseBase.fullJdk());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withExtraFile) {
|
if (withExtraFile) {
|
||||||
configureByFiles(null, beforeFileName, beforeFileName.replace(".Main.", ".data.Sample."));
|
File mainFileDir = mainFile.getParentFile();
|
||||||
|
assert mainFileDir != null;
|
||||||
|
|
||||||
|
final String mainFileName = mainFile.getName();
|
||||||
|
final String extraFileNamePrefix = mainFileName.replace(".Main.kt", ".data.Sample.");
|
||||||
|
File[] extraFiles = mainFileDir.listFiles(
|
||||||
|
new FilenameFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(@NotNull File dir, @NotNull String name) {
|
||||||
|
return name.startsWith(extraFileNamePrefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert extraFiles != null;
|
||||||
|
|
||||||
|
List<String> testFiles = new ArrayList<String>();
|
||||||
|
testFiles.add(beforeFileName);
|
||||||
|
KotlinPackage.mapTo(
|
||||||
|
extraFiles,
|
||||||
|
testFiles,
|
||||||
|
new Function1<File, String>() {
|
||||||
|
@Override
|
||||||
|
public String invoke(File file) {
|
||||||
|
return beforeFileName.replace(mainFileName, file.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
configureByFiles(null, ArrayUtil.toStringArray(testFiles));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
configureByFiles(null, beforeFileName);
|
configureByFiles(null, beforeFileName);
|
||||||
@@ -79,12 +118,16 @@ public abstract class AbstractQuickFixMultiFileTest extends KotlinDaemonAnalyzer
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Pair<String, Boolean> pair = LightQuickFixTestCase.parseActionHint(getFile(), originalFileText);
|
PsiFile psiFile = getFile();
|
||||||
|
|
||||||
|
Pair<String, Boolean> pair = LightQuickFixTestCase.parseActionHint(psiFile, originalFileText);
|
||||||
String text = pair.getFirst();
|
String text = pair.getFirst();
|
||||||
|
|
||||||
boolean actionShouldBeAvailable = pair.getSecond();
|
boolean actionShouldBeAvailable = pair.getSecond();
|
||||||
|
|
||||||
DirectiveBasedActionUtils.checkForUnexpectedErrors((JetFile) getFile());
|
if (psiFile instanceof JetFile) {
|
||||||
|
DirectiveBasedActionUtils.checkForUnexpectedErrors((JetFile) psiFile);
|
||||||
|
}
|
||||||
|
|
||||||
doAction(text, actionShouldBeAvailable, beforeFileName);
|
doAction(text, actionShouldBeAvailable, beforeFileName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,13 +227,29 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
|
|||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction")
|
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@InnerTestClasses({})
|
@InnerTestClasses({CreateFunction.Call.class})
|
||||||
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
|
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
|
||||||
public static class CreateFunction extends AbstractQuickFixMultiFileTest {
|
public static class CreateFunction extends AbstractQuickFixMultiFileTest {
|
||||||
public void testAllFilesPresentInCreateFunction() throws Exception {
|
public void testAllFilesPresentInCreateFunction() throws Exception {
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createFunction"), Pattern.compile("^(\\w+)\\.before\\.Main\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createFunction"), Pattern.compile("^(\\w+)\\.before\\.Main\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction/call")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
|
||||||
|
public static class Call extends AbstractQuickFixMultiFileTest {
|
||||||
|
public void testAllFilesPresentInCall() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createFunction/call"), Pattern.compile("^(\\w+)\\.before\\.Main\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funOnJavaType.before.Main.kt")
|
||||||
|
public void testFunOnJavaType() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/funOnJavaType.before.Main.kt");
|
||||||
|
doTestWithExtraFile(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createVariable")
|
@TestMetadata("idea/testData/quickfix/createFromUsage/createVariable")
|
||||||
|
|||||||
Reference in New Issue
Block a user