KT-658 Show types in IDEA auto assist for kotlin
This commit is contained in:
+1
-1
@@ -267,7 +267,7 @@ public class JavaDescriptorResolver {
|
||||
return javaFacade.findClass(qualifiedName, javaSearchScope);
|
||||
}
|
||||
|
||||
private PsiPackage findPackage(String qualifiedName) {
|
||||
/*package*/ PsiPackage findPackage(String qualifiedName) {
|
||||
return javaFacade.findPackage(qualifiedName);
|
||||
}
|
||||
|
||||
|
||||
+43
-6
@@ -1,10 +1,17 @@
|
||||
package org.jetbrains.jet.lang.resolve.java;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -14,11 +21,13 @@ import java.util.Set;
|
||||
public class JavaPackageScope extends JetScopeImpl {
|
||||
private final JavaSemanticServices semanticServices;
|
||||
private final DeclarationDescriptor containingDescriptor;
|
||||
private final String packagePrefix;
|
||||
private final String packageFQN;
|
||||
|
||||
private Collection<DeclarationDescriptor> allDescriptors;
|
||||
|
||||
public JavaPackageScope(@NotNull String packageFQN, DeclarationDescriptor containingDescriptor, JavaSemanticServices semanticServices) {
|
||||
this.semanticServices = semanticServices;
|
||||
this.packagePrefix = packageFQN.isEmpty() ? "" : packageFQN + ".";
|
||||
this.packageFQN = packageFQN;
|
||||
this.containingDescriptor = containingDescriptor;
|
||||
}
|
||||
|
||||
@@ -36,7 +45,7 @@ public class JavaPackageScope extends JetScopeImpl {
|
||||
@Override
|
||||
public Set<FunctionDescriptor> getFunctions(@NotNull String name) {
|
||||
// TODO: what is GlobalSearchScope
|
||||
PsiClass psiClass = semanticServices.getDescriptorResolver().javaFacade.findClass(packagePrefix + "namespace");
|
||||
PsiClass psiClass = semanticServices.getDescriptorResolver().javaFacade.findClass(getQualifiedName("namespace"));
|
||||
if (psiClass == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
@@ -54,7 +63,35 @@ public class JavaPackageScope extends JetScopeImpl {
|
||||
return containingDescriptor;
|
||||
}
|
||||
|
||||
private String getQualifiedName(String name) {
|
||||
return packagePrefix + name;
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
if (allDescriptors == null) {
|
||||
allDescriptors = Sets.newHashSet();
|
||||
|
||||
final PsiPackage javaPackage = semanticServices.getDescriptorResolver().findPackage(packageFQN);
|
||||
|
||||
if (javaPackage != null) {
|
||||
final JavaDescriptorResolver descriptorResolver = semanticServices.getDescriptorResolver();
|
||||
|
||||
for (PsiPackage psiSubPackage : javaPackage.getSubPackages()) {
|
||||
allDescriptors.add(descriptorResolver.resolveNamespace(psiSubPackage.getQualifiedName()));
|
||||
}
|
||||
|
||||
for (PsiClass psiClass : javaPackage.getClasses()) {
|
||||
if (psiClass.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
allDescriptors.add(descriptorResolver.resolveClass(psiClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDescriptors;
|
||||
}
|
||||
|
||||
private String getQualifiedName(String name) {
|
||||
return (packageFQN.isEmpty() ? "" : packageFQN + ".") + name;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -199,6 +199,10 @@ public class WriteThroughScope extends WritableScopeWithImports {
|
||||
allDescriptors = Lists.newArrayList();
|
||||
allDescriptors.addAll(writableWorker.getAllDescriptors());
|
||||
allDescriptors.addAll(getWorkerScope().getAllDescriptors());
|
||||
|
||||
for (JetScope imported : getImports()) {
|
||||
allDescriptors.addAll(imported.getAllDescriptors());
|
||||
}
|
||||
}
|
||||
return allDescriptors;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.intellij.ide.IconProvider;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Icons;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -15,21 +15,21 @@ import javax.swing.*;
|
||||
* @author yole
|
||||
*/
|
||||
public class JetIconProvider extends IconProvider {
|
||||
public static final Icon ICON_FOR_OBJECT = Icons.ANONYMOUS_CLASS_ICON;
|
||||
public static final Icon ICON_FOR_OBJECT = PlatformIcons.ANONYMOUS_CLASS_ICON;
|
||||
|
||||
@Override
|
||||
public Icon getIcon(@NotNull PsiElement psiElement, int flags) {
|
||||
if (psiElement instanceof JetNamespace) {
|
||||
return (flags & Iconable.ICON_FLAG_OPEN) != 0 ? Icons.PACKAGE_OPEN_ICON : Icons.PACKAGE_ICON;
|
||||
return (flags & Iconable.ICON_FLAG_OPEN) != 0 ? PlatformIcons.PACKAGE_OPEN_ICON : PlatformIcons.PACKAGE_ICON;
|
||||
}
|
||||
if (psiElement instanceof JetNamedFunction) {
|
||||
return PsiTreeUtil.getParentOfType(psiElement, JetNamedDeclaration.class) instanceof JetClass
|
||||
? Icons.METHOD_ICON
|
||||
: Icons.FUNCTION_ICON;
|
||||
? PlatformIcons.METHOD_ICON
|
||||
: PlatformIcons.FUNCTION_ICON;
|
||||
}
|
||||
if (psiElement instanceof JetClass) {
|
||||
JetClass jetClass = (JetClass) psiElement;
|
||||
Icon icon = jetClass.hasModifier(JetTokens.ENUM_KEYWORD) ? Icons.ENUM_ICON : Icons.CLASS_ICON;
|
||||
Icon icon = jetClass.hasModifier(JetTokens.ENUM_KEYWORD) ? PlatformIcons.ENUM_ICON : PlatformIcons.CLASS_ICON;
|
||||
if (jetClass instanceof JetEnumEntry) {
|
||||
JetEnumEntry enumEntry = (JetEnumEntry) jetClass;
|
||||
if (enumEntry.getPrimaryConstructorParameterList() == null) {
|
||||
@@ -42,13 +42,13 @@ public class JetIconProvider extends IconProvider {
|
||||
if (((JetParameter) psiElement).getValOrVarNode() != null) {
|
||||
JetParameterList parameterList = PsiTreeUtil.getParentOfType(psiElement, JetParameterList.class);
|
||||
if (parameterList != null && parameterList.getParent() instanceof JetClass) {
|
||||
return Icons.PROPERTY_ICON;
|
||||
return PlatformIcons.PROPERTY_ICON;
|
||||
}
|
||||
}
|
||||
return Icons.PARAMETER_ICON;
|
||||
return PlatformIcons.PARAMETER_ICON;
|
||||
}
|
||||
if (psiElement instanceof JetProperty) {
|
||||
return Icons.PROPERTY_ICON;
|
||||
return PlatformIcons.PROPERTY_ICON;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -24,13 +24,23 @@ import java.util.Set;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class WholeProjectAnalyzerFacade {
|
||||
public static final Function<JetFile, Collection<JetDeclaration>> WHOLE_PROJECT_DECLARATION_PROVIDER = new Function<JetFile, Collection<JetDeclaration>>() {
|
||||
public final class WholeProjectAnalyzerFacade {
|
||||
|
||||
/** Forbid creating */
|
||||
private WholeProjectAnalyzerFacade() {}
|
||||
|
||||
/**
|
||||
* Will collect all root-namespaces in all kotlin files in the project.
|
||||
*/
|
||||
public static final Function<JetFile, Collection<JetDeclaration>> WHOLE_PROJECT_DECLARATION_PROVIDER =
|
||||
new Function<JetFile, Collection<JetDeclaration>>() {
|
||||
|
||||
@Override
|
||||
public Collection<JetDeclaration> fun(final JetFile rootFile) {
|
||||
final Project project = rootFile.getProject();
|
||||
final Set<JetDeclaration> namespaces = Sets.newLinkedHashSet();
|
||||
ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
|
||||
final ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
|
||||
|
||||
if (rootManager != null && !ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
VirtualFile[] contentRoots = rootManager.getContentRoots();
|
||||
|
||||
@@ -55,9 +65,9 @@ public class WholeProjectAnalyzerFacade {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@NotNull
|
||||
public static BindingContext analyzeProjectWithCacheOnAFile(@NotNull JetFile file) {
|
||||
return AnalyzerFacade.analyzeFileWithCache(file, WHOLE_PROJECT_DECLARATION_PROVIDER);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Tests
|
||||
|
||||
import java.util.*
|
||||
|
||||
fun hello() {
|
||||
val a = So<caret>
|
||||
}
|
||||
|
||||
// EXIST: SortedSet, SortedMap
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Tests
|
||||
|
||||
class A : java.<caret>
|
||||
|
||||
// EXIST: lang, util, io
|
||||
// ABSENT: fun, val, var, namespace
|
||||
@@ -1,10 +1,10 @@
|
||||
open class MyClass() {
|
||||
}
|
||||
|
||||
class A() : My<caret> {
|
||||
class A() {
|
||||
public fun test() {
|
||||
val a : MyC<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: MyClass
|
||||
// EXIST: MyClass
|
||||
|
||||
@@ -3,4 +3,4 @@ fun foo() {
|
||||
}
|
||||
|
||||
// TODO: Move all keywords to absent
|
||||
// EXPECT: fun, val, var, namespace
|
||||
// EXIST: fun, val, var, namespace
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<caret>
|
||||
|
||||
// EXPECT: namespace, as, type, class, this, super, val, var, fun, for, null, true
|
||||
// EXPECT: false, is, in, throw, return, break, continue, object, if, try, else, while
|
||||
// EXPECT: do, when, trait, This
|
||||
// EXPECT: import, where, by, get, set, abstract, enum, open, annotation, override, private
|
||||
// EXPECT: public, internal, protected, catch, out, vararg, inline, finally, final, ref
|
||||
// EXIST: namespace, as, type, class, this, super, val, var, fun, for, null, true
|
||||
// EXIST: false, is, in, throw, return, break, continue, object, if, try, else, while
|
||||
// EXIST: do, when, trait, This
|
||||
// EXIST: import, where, by, get, set, abstract, enum, open, annotation, override, private
|
||||
// EXIST: public, internal, protected, catch, out, vararg, inline, finally, final, ref
|
||||
// ABSENT: ?in, new, extends, implements
|
||||
@@ -23,7 +23,7 @@ public class JetBasicCompletionTest extends JetCompletionTestBase {
|
||||
setName("testCompletionExecute");
|
||||
}
|
||||
|
||||
public void testCompletionExecute() {
|
||||
public void testCompletionExecute() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,70 +2,64 @@ package org.jetbrains.jet.completion;
|
||||
|
||||
import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
|
||||
import com.intellij.codeInsight.completion.CompletionType;
|
||||
import com.intellij.codeInsight.completion.LightCompletionTestCase;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupEx;
|
||||
import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
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.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Nikolay.Krasko
|
||||
*/
|
||||
public abstract class JetCompletionTestBase extends LightCodeInsightTestCase {
|
||||
public abstract class JetCompletionTestBase extends LightCompletionTestCase {
|
||||
|
||||
protected void doTest() {
|
||||
private CompletionType type;
|
||||
|
||||
protected void doTest() throws Exception {
|
||||
final String testName = getTestName(false);
|
||||
|
||||
type = (testName.startsWith("Smart")) ? CompletionType.SMART : CompletionType.BASIC;
|
||||
|
||||
configureByFile(testName + ".kt");
|
||||
|
||||
CompletionType completionType = (testName.startsWith("Smart")) ? CompletionType.SMART : CompletionType.BASIC;
|
||||
new CodeCompletionHandlerBase(completionType, false, false, true).invokeCompletion(getProject(), getEditor());
|
||||
|
||||
LookupEx lookup = LookupManager.getActiveLookup(getEditor());
|
||||
assert lookup != null;
|
||||
|
||||
HashSet<String> items = new HashSet<String>(resolveLookups(lookup.getItems()));
|
||||
|
||||
List<String> shouldExist = itemsShouldExist(getFile().getText());
|
||||
for (String shouldExistItem : shouldExist) {
|
||||
assertTrue(String.format("Should contain proposal '%s'.", shouldExistItem),
|
||||
items.contains(shouldExistItem));
|
||||
}
|
||||
|
||||
List<String> shouldAbsent = itemsShouldAbsent(getFile().getText());
|
||||
for (String shouldAbsentItem : shouldAbsent) {
|
||||
assertTrue(String.format("Shouldn't contain proposal '%s'.", shouldAbsentItem),
|
||||
!items.contains(shouldAbsentItem));
|
||||
}
|
||||
assertContainsItems(itemsShouldExist(getFile().getText()));
|
||||
assertNotContainItems(itemsShouldAbsent(getFile().getText()));
|
||||
}
|
||||
|
||||
private static List<String> resolveLookups(List<LookupElement> items) {
|
||||
ArrayList<String> result = new ArrayList<String>(items.size());
|
||||
for (LookupElement item : items) {
|
||||
result.add(item.getLookupString());
|
||||
}
|
||||
|
||||
return result;
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return PluginTestCaseBase.jdkFromIdeaHome();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void complete(final int time) {
|
||||
new CodeCompletionHandlerBase(type, false, false, true).invokeCompletion(getProject(), getEditor(), time, false);
|
||||
|
||||
LookupImpl lookup = (LookupImpl) LookupManager.getActiveLookup(myEditor);
|
||||
myItems = lookup == null ? null : lookup.getItems().toArray(LookupElement.EMPTY_ARRAY);
|
||||
myPrefix = lookup == null ? null : lookup.itemPattern(lookup.getItems().get(0));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> itemsShouldExist(String fileText) {
|
||||
private static String[] itemsShouldExist(String fileText) {
|
||||
return findListWithPrefix("// EXIST:", fileText);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> itemsShouldAbsent(String fileText) {
|
||||
private static String[] itemsShouldAbsent(String fileText) {
|
||||
return findListWithPrefix("// ABSENT:", fileText);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> findListWithPrefix(String prefix, String fileText) {
|
||||
private static String[] findListWithPrefix(String prefix, String fileText) {
|
||||
ArrayList<String> result = new ArrayList<String>();
|
||||
|
||||
for (String line : findLinesWithPrefixRemoved(prefix, fileText)) {
|
||||
@@ -76,7 +70,7 @@ public abstract class JetCompletionTestBase extends LightCodeInsightTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result.toArray(new String[result.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.jet.completion;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
@@ -25,7 +26,7 @@ public class KeywordsCompletionTest extends JetCompletionTestBase {
|
||||
setName("testCompletionExecute");
|
||||
}
|
||||
|
||||
public void testCompletionExecute() {
|
||||
public void testCompletionExecute() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@@ -49,13 +50,14 @@ public class KeywordsCompletionTest extends JetCompletionTestBase {
|
||||
PluginTestCaseBase.getTestDataPathBase(), "/completion/keywords/", false,
|
||||
JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() {
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public junit.framework.Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||
return new KeywordsCompletionTest(dataPath, name);
|
||||
}
|
||||
}, suite);
|
||||
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user