- KT-1147 Can't see local variable in completion
- Disable class level keywords from method parameters list - Reorganize completion tests to separate methods
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.descriptors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.util.QualifiedNamesUtil;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko
|
||||
@@ -28,7 +29,7 @@ public final class DescriptorsUtils {
|
||||
public static String getFQName(@NotNull NamedFunctionDescriptor functionDescriptor) {
|
||||
if (functionDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor) {
|
||||
final String namespaceFQN = getFQName((NamespaceDescriptor) functionDescriptor.getContainingDeclaration());
|
||||
return !namespaceFQN.isEmpty() ? namespaceFQN + "." + functionDescriptor.getName() : functionDescriptor.getName();
|
||||
return QualifiedNamesUtil.combine(namespaceFQN, functionDescriptor.getName());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Currently supported only for top level functions");
|
||||
|
||||
@@ -32,7 +32,9 @@ public class JetSimpleNameExpression extends JetReferenceExpression {
|
||||
PsiElement parent = getParent();
|
||||
if (parent instanceof JetQualifiedExpression && !isImportDirectiveExpression()) {
|
||||
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) parent;
|
||||
return qualifiedExpression.getReceiverExpression();
|
||||
if (!isFirstPartInQualifiedExpression(qualifiedExpression)) {
|
||||
return qualifiedExpression.getReceiverExpression();
|
||||
}
|
||||
} else if (parent instanceof JetCallExpression) {
|
||||
//This is in case `a().b()`
|
||||
JetCallExpression callExpression = (JetCallExpression) parent;
|
||||
@@ -45,6 +47,15 @@ public class JetSimpleNameExpression extends JetReferenceExpression {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check that this is simple name expression is first part in full qualified name: firstPart.otherPart.otherPart.call()
|
||||
private boolean isFirstPartInQualifiedExpression(JetQualifiedExpression qualifiedExpression) {
|
||||
if (qualifiedExpression.getParent() instanceof JetQualifiedExpression) {
|
||||
return isFirstPartInQualifiedExpression((JetQualifiedExpression) qualifiedExpression.getParent());
|
||||
}
|
||||
|
||||
return qualifiedExpression.getFirstChild() == this;
|
||||
}
|
||||
|
||||
public boolean isImportDirectiveExpression() {
|
||||
PsiElement parent = getParent();
|
||||
if (parent == null) return false;
|
||||
|
||||
@@ -123,7 +123,7 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
|
||||
public boolean isAcceptable(Object element, PsiElement context) {
|
||||
//noinspection unchecked
|
||||
return PsiTreeUtil.getParentOfType(context, JetClassBody.class, true,
|
||||
JetBlockExpression.class, JetProperty.class) != null;
|
||||
JetBlockExpression.class, JetProperty.class, JetParameterList.class) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package testing
|
||||
|
||||
fun testTop() {
|
||||
|
||||
}
|
||||
|
||||
class TestSample() {
|
||||
fun main(args : Array<String>) {
|
||||
val testVar = ""
|
||||
test<caret>.testFun()
|
||||
}
|
||||
|
||||
fun testFun() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// TIME: 2
|
||||
// EXIST: testVar, testFun, testTop
|
||||
@@ -0,0 +1,9 @@
|
||||
package testdata.kotlin.data
|
||||
|
||||
class TestSample() {
|
||||
fun main(args : Array<String>) {
|
||||
testdata.kot<caret>lin.data.TestSample()
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: kotlin
|
||||
@@ -0,0 +1,55 @@
|
||||
package TestData
|
||||
|
||||
class TestSample() {
|
||||
fun test(<caret>) {
|
||||
}
|
||||
}
|
||||
|
||||
// ABSENT: abstract
|
||||
// ABSENT: annotation
|
||||
// ABSENT: as
|
||||
// ABSENT: break
|
||||
// ABSENT: by
|
||||
// ABSENT: catch
|
||||
// ABSENT: class
|
||||
// ABSENT: continue
|
||||
// ABSENT: do
|
||||
// ABSENT: else
|
||||
// ABSENT: enum
|
||||
// ABSENT: false
|
||||
// ABSENT: final
|
||||
// ABSENT: finally
|
||||
// ABSENT: for
|
||||
// ABSENT: fun
|
||||
// ABSENT: get
|
||||
// ABSENT: if
|
||||
// ABSENT: import
|
||||
// ABSENT: in
|
||||
// ABSENT: inline
|
||||
// ABSENT: internal
|
||||
// ABSENT: is
|
||||
// ABSENT: null
|
||||
// ABSENT: object
|
||||
// ABSENT: open
|
||||
// EXIST: out
|
||||
// ABSENT: override
|
||||
// ABSENT: package
|
||||
// ABSENT: private
|
||||
// ABSENT: protected
|
||||
// ABSENT: public
|
||||
// ABSENT: return
|
||||
// ABSENT: set
|
||||
// ABSENT: super
|
||||
// ABSENT: This
|
||||
// ABSENT: this
|
||||
// ABSENT: throw
|
||||
// ABSENT: trait
|
||||
// ABSENT: true
|
||||
// ABSENT: try
|
||||
// ABSENT: type
|
||||
// ABSENT: val
|
||||
// ABSENT: var
|
||||
// ABSENT: vararg
|
||||
// ABSENT: when
|
||||
// ABSENT: where
|
||||
// ABSENT: while
|
||||
@@ -20,20 +20,22 @@ public class ExpectedCompletionUtils {
|
||||
public static final String EXIST_LINE_PREFIX = "// EXIST:";
|
||||
public static final String ABSENT_LINE_PREFIX = "// ABSENT:";
|
||||
public static final String NUMBER_LINE_PREFIX = "// NUMBER:";
|
||||
public static final String EXECUTION_TIME_PREFIX = "// TIME:";
|
||||
|
||||
private final String existLinePrefix;
|
||||
private final String absentLinePrefix;
|
||||
private final String numberLinePrefix;
|
||||
private final String executionTimePrefix;
|
||||
|
||||
public ExpectedCompletionUtils() {
|
||||
this(EXIST_LINE_PREFIX, ABSENT_LINE_PREFIX, NUMBER_LINE_PREFIX);
|
||||
this(EXIST_LINE_PREFIX, ABSENT_LINE_PREFIX, NUMBER_LINE_PREFIX, EXECUTION_TIME_PREFIX);
|
||||
}
|
||||
|
||||
public ExpectedCompletionUtils(String existLinePrefix, String absentLinePrefix, String numberLinePrefix) {
|
||||
|
||||
public ExpectedCompletionUtils(String existLinePrefix, String absentLinePrefix, String numberLinePrefix, String execitionTimePrefix) {
|
||||
this.existLinePrefix = existLinePrefix;
|
||||
this.absentLinePrefix = absentLinePrefix;
|
||||
this.numberLinePrefix = numberLinePrefix;
|
||||
this.executionTimePrefix = execitionTimePrefix;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -56,6 +58,16 @@ public class ExpectedCompletionUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getExecutionTime(String fileText) {
|
||||
final String[] numberStrings = findListWithPrefix(executionTimePrefix, fileText);
|
||||
if (numberStrings.length > 0) {
|
||||
return Integer.parseInt(numberStrings[0]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String[] findListWithPrefix(String prefix, String fileText) {
|
||||
ArrayList<String> result = new ArrayList<String>();
|
||||
@@ -88,7 +100,6 @@ public class ExpectedCompletionUtils {
|
||||
private static List<String> fileNonEmptyLines(String fileText) {
|
||||
ArrayList<String> result = new ArrayList<String>();
|
||||
|
||||
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new StringReader(fileText));
|
||||
try {
|
||||
@@ -103,7 +114,7 @@ public class ExpectedCompletionUtils {
|
||||
reader.close();
|
||||
}
|
||||
} catch(IOException e) {
|
||||
assert false;
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package org.jetbrains.jet.completion;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
|
||||
import java.io.File;
|
||||
@@ -13,31 +9,45 @@ import java.io.File;
|
||||
*/
|
||||
public class ExtensionsCompletionTest extends JetCompletionTestBase {
|
||||
|
||||
// public ExtensionsCompletionTest() {
|
||||
// this("/completion/basic/extensions", "IrrelevantExtension");
|
||||
// // this("/completion/basic/extensions", "InvalidTypeParameters");
|
||||
// // this("/completion/basic/extensions", "ExtensionInExtensionThis");
|
||||
// }
|
||||
|
||||
protected ExtensionsCompletionTest(@NotNull String path, @NotNull String name) {
|
||||
super(path, name);
|
||||
public void testExtensionInExtendedClass() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TestSuite suite() {
|
||||
TestSuite suite = new TestSuite();
|
||||
public void testExtensionInExtendedClassThis() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
JetTestCaseBuilder.appendTestsInDirectory(
|
||||
PluginTestCaseBase.getTestDataPathBase(), "/completion/basic/extensions", false,
|
||||
JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() {
|
||||
public void testExtensionInExtension() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||
return new ExtensionsCompletionTest(dataPath, name);
|
||||
}
|
||||
}, suite);
|
||||
public void testExtensionInExtensionThis() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
return suite;
|
||||
public void testInvalidTypeParameters() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIrrelevantExtension() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testJavaTypeExtension() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testKotlinGenericTypeExtension() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testKotlinTypeExtension() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/basic/extensions").getPath() +
|
||||
File.separator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package org.jetbrains.jet.completion;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
|
||||
import java.io.File;
|
||||
@@ -13,25 +9,66 @@ import java.io.File;
|
||||
*/
|
||||
public class JetBasicCompletionTest extends JetCompletionTestBase {
|
||||
|
||||
protected JetBasicCompletionTest(@NotNull String path, @NotNull String name) {
|
||||
super(path, name);
|
||||
public void testBeforeDotInCall() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TestSuite suite() {
|
||||
TestSuite suite = new TestSuite();
|
||||
public void testExtendClassName() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
JetTestCaseBuilder.appendTestsInDirectory(
|
||||
PluginTestCaseBase.getTestDataPathBase(), "/completion/basic/", false,
|
||||
JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() {
|
||||
public void testExtendQualifiedClassName() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||
return new JetBasicCompletionTest(dataPath, name);
|
||||
}
|
||||
}, suite);
|
||||
public void testFromImports() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
return suite;
|
||||
public void testInCallExpression() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInEmptyImport() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInImport() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// TODO: activate this test
|
||||
public void todotestInMiddleOfNamespace() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testJavaClassNames() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testJavaPackage() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNamedObject() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testOverloadFunctions() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSubpackageInFun() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testVariableClassName() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/basic").getPath() +
|
||||
File.separator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,60 +7,48 @@ import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Nikolay.Krasko
|
||||
*/
|
||||
public abstract class JetCompletionTestBase extends LightCompletionTestCase {
|
||||
private final String myPath;
|
||||
private final String myName;
|
||||
|
||||
protected JetCompletionTestBase(@NotNull String path, @NotNull String name) {
|
||||
myPath = path;
|
||||
myName = name;
|
||||
|
||||
// Set name explicitly because otherwise there will be "TestCase.fName cannot be null"
|
||||
setName("testCompletionExecute");
|
||||
}
|
||||
|
||||
public void testCompletionExecute() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() +
|
||||
File.separator;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "test" + myName;
|
||||
}
|
||||
private final ExpectedCompletionUtils completionUtils = new ExpectedCompletionUtils();
|
||||
|
||||
private CompletionType type;
|
||||
|
||||
protected void doTest() throws Exception {
|
||||
final String testName = getTestName(false);
|
||||
@Override
|
||||
protected abstract String getTestDataPath();
|
||||
|
||||
type = (testName.startsWith("Smart")) ? CompletionType.SMART : CompletionType.BASIC;
|
||||
protected void doTest() {
|
||||
try {
|
||||
final String testName = getTestName(false);
|
||||
|
||||
configureByFile(testName + ".kt");
|
||||
type = (testName.startsWith("Smart")) ? CompletionType.SMART : CompletionType.BASIC;
|
||||
|
||||
final String fileText = getFile().getText();
|
||||
final ExpectedCompletionUtils completionUtils = new ExpectedCompletionUtils();
|
||||
configureByFileNoComplete(testName + ".kt");
|
||||
|
||||
assertContainsItems(completionUtils.itemsShouldExist(fileText));
|
||||
assertNotContainItems(completionUtils.itemsShouldAbsent(fileText));
|
||||
|
||||
Integer itemsNumber = completionUtils.getExpectedNumber(fileText);
|
||||
if (itemsNumber != null) {
|
||||
assertEquals(itemsNumber.intValue(), myItems.length);
|
||||
final String fileText = getFile().getText();
|
||||
|
||||
Integer completionTime = completionUtils.getExecutionTime(fileText);
|
||||
|
||||
complete(completionTime == null ? 1 : completionTime);
|
||||
|
||||
final String[] expected = completionUtils.itemsShouldExist(fileText);
|
||||
final String[] unexpected = completionUtils.itemsShouldAbsent(fileText);
|
||||
Integer itemsNumber = completionUtils.getExpectedNumber(fileText);
|
||||
|
||||
assertTrue("Should be some assertions about completion", expected.length != 0 || unexpected.length != 0 || itemsNumber != null);
|
||||
|
||||
assertContainsItems(expected);
|
||||
assertNotContainItems(unexpected);
|
||||
|
||||
if (itemsNumber != null) {
|
||||
assertEquals(itemsNumber.intValue(), myItems.length);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package org.jetbrains.jet.completion;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
|
||||
import java.io.File;
|
||||
@@ -15,26 +11,85 @@ import java.io.File;
|
||||
*/
|
||||
public class KeywordsCompletionTest extends JetCompletionTestBase {
|
||||
|
||||
protected KeywordsCompletionTest(@NotNull String path, @NotNull String name) {
|
||||
super(path, name);
|
||||
public void testAfterClassProperty() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TestSuite suite() {
|
||||
TestSuite suite = new TestSuite();
|
||||
public void testAfterDot() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
JetTestCaseBuilder.appendTestsInDirectory(
|
||||
PluginTestCaseBase.getTestDataPathBase(), "/completion/keywords/", false,
|
||||
JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() {
|
||||
public void testAfterSpaceAndDot() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testclassObject() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||
return new KeywordsCompletionTest(dataPath, name);
|
||||
}
|
||||
}, suite);
|
||||
public void testInBlockComment() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
return suite;
|
||||
public void testInChar() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInClassBeforeFun() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInClassProperty() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInClassScope() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInFunctionScope() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInParametersList() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInMethodParametersList() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInString() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInTopProperty() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInTopScopeAfterPackage() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInTypeScope() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testLineComment() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testPropertySetterGetter() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testTopScope() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/keywords").getPath() +
|
||||
File.separator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ public class JavaCompletionHandlerTest extends CompletionTestCase {
|
||||
configureByFiles(null, fileName + ".java", fileName + ".kt");
|
||||
complete(2);
|
||||
checkResultByFile(fileName + ".after.java");
|
||||
} catch (@SuppressWarnings("CaughtExceptionImmediatelyRethrown") AssertionError assertionError) {
|
||||
throw assertionError;
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user