KT-983 Code completion for not-imported classes - Show kotlin classes (another temp commit)
This commit is contained in:
@@ -11,6 +11,9 @@
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.jet.plugin.compiler.JetCompilerManager</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.jet.plugin.caches.JetCacheManager</implementation-class>
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<actions>
|
||||
@@ -74,6 +77,7 @@
|
||||
<codeInsight.overrideMethod language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.OverrideMethodsHandler"/>
|
||||
|
||||
<java.elementFinder implementation="org.jetbrains.jet.asJava.JavaElementFinder"/>
|
||||
<java.shortNamesCache implementation="org.jetbrains.jet.plugin.caches.JetShortNamesCache"/>
|
||||
|
||||
<psi.treeChangePreprocessor implementation="org.jetbrains.jet.asJava.JetCodeBlockModificationListener"/>
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.jetbrains.jet.plugin.caches;
|
||||
|
||||
import com.intellij.openapi.components.ProjectComponent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko
|
||||
*/
|
||||
public class JetCacheManager implements ProjectComponent {
|
||||
private Project myProject;
|
||||
private JetShortNamesCache myCache;
|
||||
|
||||
public static JetCacheManager getInstance(Project project) {
|
||||
return project.getComponent(JetCacheManager.class);
|
||||
}
|
||||
|
||||
public JetCacheManager(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void projectOpened() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void projectClosed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getComponentName() {
|
||||
return "Kotlin caches manager";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initComponent() {
|
||||
myCache = new JetShortNamesCache(myProject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeComponent() {
|
||||
|
||||
}
|
||||
|
||||
public JetShortNamesCache getNamesCache() {
|
||||
return myCache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package org.jetbrains.jet.plugin.caches;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiShortNamesCache;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko
|
||||
*/
|
||||
public class JetShortNamesCache extends PsiShortNamesCache {
|
||||
|
||||
private final Project project;
|
||||
|
||||
public JetShortNamesCache(Project project) {
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass[] getClassesByName(@NotNull @NonNls String name, @NotNull GlobalSearchScope scope) {
|
||||
return new PsiClass[0];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String[] getAllClassNames() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAllClassNames(@NotNull HashSet<String> dest) {
|
||||
}
|
||||
|
||||
public List<String> getAllJetClassNames() {
|
||||
final BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCache(project, GlobalSearchScope.allScope(project));
|
||||
final Collection<String> fqNames = context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR);
|
||||
|
||||
final ArrayList<String> classNames = new ArrayList<String>();
|
||||
|
||||
for (String fqName : fqNames) {
|
||||
int lastDotIndex = fqName.lastIndexOf('.');
|
||||
if (lastDotIndex != -1) {
|
||||
classNames.add(fqName.substring(lastDotIndex + 1, fqName.length()));
|
||||
}
|
||||
else {
|
||||
classNames.add(fqName);
|
||||
}
|
||||
}
|
||||
|
||||
return classNames;
|
||||
}
|
||||
|
||||
public Collection<ClassDescriptor> getClassDescriptors() {
|
||||
final BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCache(project, GlobalSearchScope.allScope(project));
|
||||
|
||||
final Collection<String> fqNames = context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR);
|
||||
return Collections2.transform(fqNames, new Function<String, ClassDescriptor>() {
|
||||
@Override
|
||||
public ClassDescriptor apply(String fqName) {
|
||||
return context.get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, fqName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<JetClass> getJetClassesByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
|
||||
final BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCache(project, scope);
|
||||
final ArrayList<JetClass> classesResult = new ArrayList<JetClass>();
|
||||
|
||||
for (String fqn : getFQNamesByName(name, scope)) {
|
||||
final ClassDescriptor descriptor = context.get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, fqn);
|
||||
final PsiElement declaration = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
|
||||
|
||||
if (declaration instanceof JetClass) {
|
||||
classesResult.add((JetClass) declaration);
|
||||
}
|
||||
}
|
||||
|
||||
return classesResult;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<String> getFQNamesByName(@NotNull final String name, @NotNull GlobalSearchScope scope) {
|
||||
final BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCache(project, scope);
|
||||
return Collections2.filter(context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR), new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable String fqName) {
|
||||
return fqName != null && (fqName.endsWith('.' + name) || fqName.equals(name));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiMethod[] getMethodsByName(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope) {
|
||||
return new PsiMethod[0];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope, int maxCount) {
|
||||
return new PsiMethod[0];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String[] getAllMethodNames() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAllMethodNames(@NotNull HashSet<String> set) {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiField[] getFieldsByName(@NotNull @NonNls String name, @NotNull GlobalSearchScope scope) {
|
||||
return new PsiField[0];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String[] getAllFieldNames() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAllFieldNames(@NotNull HashSet<String> set) {
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,10 @@ import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.asJava.JetFileUtil;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
|
||||
@@ -63,9 +65,13 @@ public final class WholeProjectAnalyzerFacade {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@NotNull
|
||||
public static BindingContext analyzeProjectWithCacheOnAFile(@NotNull JetFile file) {
|
||||
return AnalyzerFacade.analyzeFileWithCache(file, WHOLE_PROJECT_DECLARATION_PROVIDER);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static BindingContext analyzeProjectWithCache(@NotNull Project project, @NotNull GlobalSearchScope scope) {
|
||||
return AnalyzerFacade.analyzeProjectWithCache(project, JetFileUtil.collectJetFiles(project, scope));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package org.jetbrains.jet.plugin.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko
|
||||
*/
|
||||
public final class DescriptorLookupConverter {
|
||||
|
||||
private final static JetFunctionInsertHandler EMPTY_FUNCTION_HANDLER = new JetFunctionInsertHandler(
|
||||
JetFunctionInsertHandler.CaretPosition.AFTER_BRACKETS);
|
||||
|
||||
private final static JetFunctionInsertHandler PARAMS_FUNCTION_HANDLER = new JetFunctionInsertHandler(
|
||||
JetFunctionInsertHandler.CaretPosition.IN_BRACKETS);
|
||||
|
||||
@NotNull
|
||||
public static LookupElement createLookupElement(@NotNull DeclarationDescriptor descriptor, @Nullable PsiElement declaration) {
|
||||
LookupElementBuilder element = LookupElementBuilder.create(descriptor, descriptor.getName());
|
||||
String typeText = "";
|
||||
String tailText = "";
|
||||
boolean tailTextGrayed = false;
|
||||
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
JetType returnType = functionDescriptor.getReturnType();
|
||||
typeText = DescriptorRenderer.TEXT.renderType(returnType);
|
||||
|
||||
tailText = "(" + StringUtil.join(functionDescriptor.getValueParameters(), new Function<ValueParameterDescriptor, String>() {
|
||||
@Override
|
||||
public String fun(ValueParameterDescriptor valueParameterDescriptor) {
|
||||
return valueParameterDescriptor.getName() + ":" +
|
||||
DescriptorRenderer.TEXT.renderType(valueParameterDescriptor.getOutType());
|
||||
}
|
||||
}, ",") + ")";
|
||||
|
||||
|
||||
// TODO: A special case when it's impossible to resolve type parameters from arguments. Need '<' caret '>'
|
||||
// TODO: Support omitting brackets for one argument functions
|
||||
if (functionDescriptor.getValueParameters().isEmpty()) {
|
||||
element = element.setInsertHandler(EMPTY_FUNCTION_HANDLER);
|
||||
} else {
|
||||
element = element.setInsertHandler(PARAMS_FUNCTION_HANDLER);
|
||||
}
|
||||
}
|
||||
else if (descriptor instanceof VariableDescriptor) {
|
||||
JetType outType = ((VariableDescriptor) descriptor).getOutType();
|
||||
typeText = DescriptorRenderer.TEXT.renderType(outType);
|
||||
}
|
||||
else if (descriptor instanceof ClassDescriptor) {
|
||||
tailText = " (" + DescriptorUtils.getFQName(descriptor.getContainingDeclaration()) + ")";
|
||||
tailTextGrayed = true;
|
||||
}
|
||||
else {
|
||||
typeText = DescriptorRenderer.TEXT.render(descriptor);
|
||||
}
|
||||
|
||||
element = element.setTailText(tailText, tailTextGrayed).setTypeText(typeText);
|
||||
|
||||
if (declaration != null) {
|
||||
element = element.setIcon(declaration.getIcon(Iconable.ICON_FLAG_OPEN | Iconable.ICON_FLAG_VISIBILITY));
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LookupElement createLookupElement(@NotNull BindingContext bindingContext, @NotNull DeclarationDescriptor descriptor) {
|
||||
return createLookupElement(descriptor, bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor.getOriginal()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2,17 +2,22 @@ package org.jetbrains.jet.plugin.completion;
|
||||
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.patterns.PlatformPatterns;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetUserType;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.caches.JetCacheManager;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko
|
||||
@@ -23,9 +28,9 @@ public class JetCompletionContributor extends CompletionContributor {
|
||||
new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context,
|
||||
final @NotNull CompletionResultSet _result) {
|
||||
final @NotNull CompletionResultSet result) {
|
||||
|
||||
if (_result.getPrefixMatcher().getPrefix().isEmpty()) {
|
||||
if (result.getPrefixMatcher().getPrefix().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -34,23 +39,55 @@ public class JetCompletionContributor extends CompletionContributor {
|
||||
return;
|
||||
}
|
||||
|
||||
CompletionResultSet result = _result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters));
|
||||
|
||||
if (shouldRunClassNameCompletion(parameters, context)) {
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting(
|
||||
parameters, result), parameters.getInvocationCount() <= 1, new Consumer<LookupElement>() {
|
||||
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
_result.addElement(element);
|
||||
|
||||
}
|
||||
});
|
||||
addJavaClasses(parameters, result);
|
||||
addJetClasses(result, position);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void addJetClasses(CompletionResultSet result, PsiElement position) {
|
||||
if (position.getParent() instanceof JetSimpleNameExpression) {
|
||||
final JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) position.getParent();
|
||||
if (PsiTreeUtil.getParentOfType(nameExpression, JetQualifiedExpression.class) == null) {
|
||||
Project project = position.getProject();
|
||||
|
||||
final String referencedName = nameExpression.getReferencedName();
|
||||
|
||||
if (referencedName != null && referencedName.endsWith(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED)) {
|
||||
int lastPrefixIndex = referencedName.length() -
|
||||
CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED.length();
|
||||
String actualPrefix = referencedName.substring(0, lastPrefixIndex);
|
||||
|
||||
final Collection<ClassDescriptor> classDescriptors =
|
||||
JetCacheManager.getInstance(project).getNamesCache().getClassDescriptors();
|
||||
|
||||
for (ClassDescriptor descriptor : classDescriptors) {
|
||||
if (descriptor.getName().startsWith(actualPrefix)) {
|
||||
result.addElement(DescriptorLookupConverter.createLookupElement(descriptor, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addJavaClasses(CompletionParameters parameters, final CompletionResultSet result) {
|
||||
|
||||
CompletionResultSet tempResult = result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters));
|
||||
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting(
|
||||
parameters, tempResult), parameters.getInvocationCount() <= 1, new Consumer<LookupElement>() {
|
||||
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
result.addElement(element);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean shouldRunClassNameCompletion(@NotNull CompletionParameters parameters, ProcessingContext context) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
|
||||
@@ -75,4 +112,9 @@ public class JetCompletionContributor extends CompletionContributor {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeCompletion(@NotNull CompletionInitializationContext context) {
|
||||
super.beforeCompletion(context); //To change body of overridden methods use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
@@ -25,10 +24,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
|
||||
import org.jetbrains.jet.plugin.JetFileType;
|
||||
import org.jetbrains.jet.plugin.actions.JetAddImportAction;
|
||||
import org.jetbrains.jet.plugin.caches.JetCacheManager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -56,31 +54,29 @@ public class ImportClassFix extends JetHintAction<JetSimpleNameExpression> imple
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final BindingContext context = AnalyzerFacade.analyzeFileWithCache(
|
||||
(JetFile) file, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
|
||||
|
||||
return getClassNames(element, context, file.getProject());
|
||||
return getClassNames(element, file.getProject());
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches for possible class names in kotlin context and java facade.
|
||||
*/
|
||||
public static List<String> getClassNames(@NotNull JetSimpleNameExpression expression, @NotNull BindingContext context, @NotNull Project project) {
|
||||
public static List<String> getClassNames(@NotNull JetSimpleNameExpression expression, @NotNull Project project) {
|
||||
final String referenceName = expression.getReferencedName();
|
||||
|
||||
if (referenceName == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
|
||||
Set<String> possibleResolveNames = Sets.newHashSet();
|
||||
possibleResolveNames.addAll(filterPossibleTypes(referenceName, context.getKeys(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR)));
|
||||
possibleResolveNames.addAll(getJavaClasses(referenceName, project));
|
||||
possibleResolveNames.addAll(JetCacheManager.getInstance(project).getNamesCache().getFQNamesByName(referenceName, scope));
|
||||
possibleResolveNames.addAll(getJavaClasses(referenceName, project, scope));
|
||||
|
||||
// TODO: Do appropriate sorting
|
||||
return Lists.newArrayList(possibleResolveNames);
|
||||
}
|
||||
|
||||
private static Collection<String> getJavaClasses(@NotNull final String typeName, @NotNull Project project) {
|
||||
private static Collection<String> getJavaClasses(@NotNull final String typeName, @NotNull Project project, final GlobalSearchScope scope) {
|
||||
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project);
|
||||
|
||||
PsiClass[] classes = cache.getClassesByName(typeName, new DelegatingGlobalSearchScope(GlobalSearchScope.allScope(project)) {
|
||||
@@ -100,16 +96,6 @@ public class ImportClassFix extends JetHintAction<JetSimpleNameExpression> imple
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Collection<String> filterPossibleTypes(@NotNull final String typeName, @NotNull Collection<String> variants) {
|
||||
return Collections2.filter(variants, new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable String fqName) {
|
||||
return fqName != null && (fqName.endsWith('.' + typeName) || fqName.equals(typeName));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showHint(@NotNull Editor editor) {
|
||||
if (suggestions.isEmpty()) {
|
||||
|
||||
@@ -2,23 +2,18 @@ package org.jetbrains.jet.plugin.references;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.compiler.TipsManager;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
import org.jetbrains.jet.plugin.completion.DescriptorLookupConverter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -27,12 +22,6 @@ import java.util.List;
|
||||
*/
|
||||
class JetSimpleNameReference extends JetPsiReference {
|
||||
|
||||
private final static JetFunctionInsertHandler EMPTY_FUNCTION_HANDLER = new JetFunctionInsertHandler(
|
||||
JetFunctionInsertHandler.CaretPosition.AFTER_BRACKETS);
|
||||
|
||||
private final static JetFunctionInsertHandler PARAMS_FUNCTION_HANDLER = new JetFunctionInsertHandler(
|
||||
JetFunctionInsertHandler.CaretPosition.IN_BRACKETS);
|
||||
|
||||
private final JetSimpleNameExpression myExpression;
|
||||
|
||||
public JetSimpleNameReference(JetSimpleNameExpression jetSimpleNameExpression) {
|
||||
@@ -71,54 +60,9 @@ class JetSimpleNameReference extends JetPsiReference {
|
||||
List<LookupElement> result = Lists.newArrayList();
|
||||
|
||||
for (final DeclarationDescriptor descriptor : descriptors) {
|
||||
LookupElementBuilder element = LookupElementBuilder.create(descriptor, descriptor.getName());
|
||||
String typeText = "";
|
||||
String tailText = "";
|
||||
boolean tailTextGrayed = false;
|
||||
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
JetType returnType = functionDescriptor.getReturnType();
|
||||
typeText = DescriptorRenderer.TEXT.renderType(returnType);
|
||||
|
||||
tailText = "(" + StringUtil.join(functionDescriptor.getValueParameters(), new Function<ValueParameterDescriptor, String>() {
|
||||
@Override
|
||||
public String fun(ValueParameterDescriptor valueParameterDescriptor) {
|
||||
return valueParameterDescriptor.getName() + ":" +
|
||||
DescriptorRenderer.TEXT.renderType(valueParameterDescriptor.getOutType());
|
||||
}
|
||||
}, ",") + ")";
|
||||
|
||||
|
||||
// TODO: A special case when it's impossible to resolve type parameters from arguments. Need '<' caret '>'
|
||||
// TODO: Support omitting brackets for one argument functions
|
||||
if (functionDescriptor.getValueParameters().isEmpty()) {
|
||||
element = element.setInsertHandler(EMPTY_FUNCTION_HANDLER);
|
||||
} else {
|
||||
element = element.setInsertHandler(PARAMS_FUNCTION_HANDLER);
|
||||
}
|
||||
}
|
||||
else if (descriptor instanceof VariableDescriptor) {
|
||||
JetType outType = ((VariableDescriptor) descriptor).getOutType();
|
||||
typeText = DescriptorRenderer.TEXT.renderType(outType);
|
||||
}
|
||||
else if (descriptor instanceof ClassDescriptor) {
|
||||
tailText = " (" + DescriptorUtils.getFQName(descriptor.getContainingDeclaration()) + ")";
|
||||
tailTextGrayed = true;
|
||||
}
|
||||
else {
|
||||
typeText = DescriptorRenderer.TEXT.render(descriptor);
|
||||
}
|
||||
|
||||
element = element.setTailText(tailText, tailTextGrayed).setTypeText(typeText);
|
||||
|
||||
PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor.getOriginal());
|
||||
if (declaration != null) {
|
||||
element = element.setIcon(declaration.getIcon(Iconable.ICON_FLAG_OPEN | Iconable.ICON_FLAG_VISIBILITY));
|
||||
}
|
||||
|
||||
result.add(element);
|
||||
result.add(DescriptorLookupConverter.createLookupElement(bindingContext, descriptor));
|
||||
}
|
||||
|
||||
return result.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user