Create From Usage: Do not suggest Java classes as receiver type candidates (for now)

This commit is contained in:
Alexey Sedunov
2014-10-06 18:54:27 +04:00
parent 0dafcb6728
commit 77a5ddbcd0
6 changed files with 93 additions and 11 deletions
@@ -37,12 +37,16 @@ public class CreateCallableFromUsageFix(
val popupTitle = JetBundle.message("choose.target.class.or.trait.title")
val receiverTypeCandidates = callableBuilder.computeTypeCandidates(callableInfo.receiverTypeInfo)
if (receiverTypeCandidates.isNotEmpty()) {
val toPsi: (TypeCandidate) -> JetClassOrObject = {
val descriptor = DescriptorUtils.getClassDescriptorForType(it.theType)
DescriptorToDeclarationUtil.getDeclaration(file, descriptor) as JetClassOrObject
}
chooseContainerElementIfNecessary(receiverTypeCandidates, editor, popupTitle, false, toPsi) {
runBuilder(CallablePlacement.WithReceiver(it))
// TODO: Support generation of Java class members
val containers = receiverTypeCandidates
.map { candidate ->
val descriptor = DescriptorUtils.getClassDescriptorForType(candidate.theType)
(DescriptorToDeclarationUtil.getDeclaration(file, descriptor) as? JetClassOrObject)?.let { candidate to it }
}
.filterNotNull()
chooseContainerElementIfNecessary(containers, editor, popupTitle, false, { it.second }) {
runBuilder(CallablePlacement.WithReceiver(it.first))
}
}
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.
}
@@ -0,0 +1,6 @@
// "Create function 'foo' from usage" "true"
// ERROR: Unresolved reference: foo
fun test(): Int {
return A().<caret>foo(1, "2")
}
@@ -24,8 +24,16 @@ import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.Pair;
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 jet.runtime.typeinfo.JetValueParameter;
import junit.framework.ComparisonFailure;
import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.InTextDirectivesUtils;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.lang.psi.JetFile;
@@ -35,6 +43,7 @@ import org.jetbrains.jet.plugin.PluginTestCaseBase;
import org.jetbrains.jet.testing.ConfigLibraryUtil;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -62,14 +71,44 @@ public abstract class AbstractQuickFixMultiFileTest extends KotlinDaemonAnalyzer
}
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) {
ConfigLibraryUtil.configureKotlinRuntime(myModule, PluginTestCaseBase.fullJdk());
}
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 {
configureByFiles(null, beforeFileName);
@@ -79,12 +118,16 @@ public abstract class AbstractQuickFixMultiFileTest extends KotlinDaemonAnalyzer
@Override
public void run() {
try {
Pair<String, Boolean> pair = LightQuickFixTestCase.parseActionHint(getFile(), originalFileText);
PsiFile psiFile = getFile();
Pair<String, Boolean> pair = LightQuickFixTestCase.parseActionHint(psiFile, originalFileText);
String text = pair.getFirst();
boolean actionShouldBeAvailable = pair.getSecond();
DirectiveBasedActionUtils.checkForUnexpectedErrors((JetFile) getFile());
if (psiFile instanceof JetFile) {
DirectiveBasedActionUtils.checkForUnexpectedErrors((JetFile) psiFile);
}
doAction(text, actionShouldBeAvailable, beforeFileName);
}
@@ -227,13 +227,29 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({})
@InnerTestClasses({CreateFunction.Call.class})
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
public static class CreateFunction extends AbstractQuickFixMultiFileTest {
public void testAllFilesPresentInCreateFunction() throws Exception {
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")