Converted more completion code to Kotlin
This commit is contained in:
@@ -27,6 +27,18 @@
|
||||
name='com.intellij.codeInsight.completion.CompletionSorter com.intellij.codeInsight.completion.CompletionSorter weighBefore(java.lang.String, com.intellij.codeInsight.lookup.LookupElementWeigher...)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.completion.CompletionUtil java.lang.String findIdentifierPrefix(com.intellij.psi.PsiElement, int, com.intellij.patterns.ElementPattern<java.lang.Character>, com.intellij.patterns.ElementPattern<java.lang.Character>)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.completion.CompletionUtil java.lang.String findJavaIdentifierPrefix(com.intellij.codeInsight.completion.CompletionParameters)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.completion.CompletionUtil java.lang.String findJavaIdentifierPrefix(com.intellij.psi.PsiElement, int)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.completion.InsertHandler void handleInsert(com.intellij.codeInsight.completion.InsertionContext, T) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
@@ -41,6 +53,10 @@
|
||||
<item name='com.intellij.codeInsight.completion.InsertionContext com.intellij.openapi.project.Project getProject()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.completion.JavaCompletionSorting com.intellij.codeInsight.completion.CompletionResultSet addJavaSorting(com.intellij.codeInsight.completion.CompletionParameters, com.intellij.codeInsight.completion.CompletionResultSet)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='com.intellij.codeInsight.completion.OffsetKey com.intellij.codeInsight.completion.OffsetKey create(java.lang.String)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
|
||||
@@ -63,6 +63,7 @@ import static org.jetbrains.jet.plugin.caches.JetFromJavaDescriptorHelper.getTop
|
||||
*/
|
||||
public class JetShortNamesCache extends PsiShortNamesCache {
|
||||
|
||||
@NotNull
|
||||
public static JetShortNamesCache getKotlinInstance(@NotNull Project project) {
|
||||
PsiShortNamesCache[] extensions = Extensions.getArea(project).getExtensionPoint(PsiShortNamesCache.EP_NAME).getExtensions();
|
||||
for (PsiShortNamesCache extension : extensions) {
|
||||
@@ -354,6 +355,7 @@ public class JetShortNamesCache extends PsiShortNamesCache {
|
||||
return functionFQNs;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ClassDescriptor> getJetClassesDescriptors(
|
||||
@NotNull Condition<String> acceptedShortNameCondition,
|
||||
@NotNull KotlinCodeAnalyzer analyzer,
|
||||
|
||||
@@ -1,303 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.completion;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import kotlin.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.caches.JetShortNamesCache;
|
||||
import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage;
|
||||
import org.jetbrains.jet.plugin.codeInsight.TipsManager;
|
||||
import org.jetbrains.jet.plugin.completion.smart.SmartCompletion;
|
||||
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies;
|
||||
import org.jetbrains.jet.plugin.references.JetSimpleNameReference;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
class CompletionSession {
|
||||
@Nullable
|
||||
private final DeclarationDescriptor inDescriptor;
|
||||
private final CompletionParameters parameters;
|
||||
private final JetCompletionResultSet jetResult;
|
||||
private final JetSimpleNameReference jetReference;
|
||||
|
||||
public CompletionSession(
|
||||
@NotNull CompletionParameters parameters,
|
||||
@NotNull CompletionResultSet result,
|
||||
@NotNull JetSimpleNameReference jetReference,
|
||||
@NotNull PsiElement position
|
||||
) {
|
||||
this.parameters = parameters;
|
||||
this.jetReference = jetReference;
|
||||
|
||||
ResolveSessionForBodies resolveSession =
|
||||
ResolvePackage.getLazyResolveSession((JetFile) position.getContainingFile());
|
||||
BindingContext expressionBindingContext = resolveSession.resolveToElement(jetReference.getExpression());
|
||||
JetScope scope = expressionBindingContext.get(BindingContext.RESOLUTION_SCOPE, jetReference.getExpression());
|
||||
|
||||
inDescriptor = scope != null ? scope.getContainingDeclaration() : null;
|
||||
Condition<DeclarationDescriptor> descriptorFilter = new Condition<DeclarationDescriptor>() {
|
||||
@Override
|
||||
public boolean value(DeclarationDescriptor descriptor) {
|
||||
return isVisibleDescriptor(descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
// set prefix matcher here to override default one which relies on CompletionUtil.findReferencePrefix()
|
||||
// which sometimes works incorrectly for Kotlin
|
||||
result = result.withPrefixMatcher(CompletionUtil.findJavaIdentifierPrefix(parameters));
|
||||
|
||||
result = CompletionPackage.addKotlinSorting(result, parameters);
|
||||
|
||||
this.jetResult = new JetCompletionResultSet(result, resolveSession, expressionBindingContext, descriptorFilter);
|
||||
}
|
||||
|
||||
public void completeForReference() {
|
||||
assert parameters.getCompletionType() == CompletionType.BASIC;
|
||||
|
||||
if (isOnlyKeywordCompletion(getPosition())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldRunOnlyTypeCompletion()) {
|
||||
if (parameters.getInvocationCount() >= 2) {
|
||||
JetTypesCompletionHelper.addJetTypes(parameters, jetResult);
|
||||
}
|
||||
else {
|
||||
addReferenceVariants(new Condition<DeclarationDescriptor>() {
|
||||
@Override
|
||||
public boolean value(DeclarationDescriptor descriptor) {
|
||||
return isPartOfTypeDeclaration(descriptor);
|
||||
}
|
||||
});
|
||||
JavaCompletionContributor.advertiseSecondCompletion(parameters.getPosition().getProject(), jetResult.getResult());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
addReferenceVariants(Conditions.<DeclarationDescriptor>alwaysTrue());
|
||||
|
||||
String prefix = jetResult.getResult().getPrefixMatcher().getPrefix();
|
||||
|
||||
// Try to avoid computing not-imported descriptors for empty prefix
|
||||
if (prefix.isEmpty()) {
|
||||
if (parameters.getInvocationCount() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PsiTreeUtil.getParentOfType(jetReference.getExpression(), JetDotQualifiedExpression.class) == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldRunTopLevelCompletion()) {
|
||||
JetTypesCompletionHelper.addJetTypes(parameters, jetResult);
|
||||
addJetTopLevelFunctions();
|
||||
addJetTopLevelObjects();
|
||||
}
|
||||
|
||||
if (shouldRunExtensionsCompletion()) {
|
||||
addJetExtensions();
|
||||
}
|
||||
}
|
||||
|
||||
public void completeSmart() {
|
||||
assert parameters.getCompletionType() == CompletionType.SMART;
|
||||
|
||||
Collection<DeclarationDescriptor> descriptors = TipsManager.getReferenceVariants(
|
||||
jetReference.getExpression(), getExpressionBindingContext());
|
||||
Function1<DeclarationDescriptor, Boolean> visibilityFilter = new Function1<DeclarationDescriptor, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(DeclarationDescriptor descriptor) {
|
||||
return isVisibleDescriptor(descriptor);
|
||||
}
|
||||
};
|
||||
SmartCompletion completion = new SmartCompletion(jetReference.getExpression(), getResolveSession(), visibilityFilter, (JetFile)parameters.getOriginalFile());
|
||||
Collection<LookupElement> elements = completion.buildLookupElements(descriptors);
|
||||
if (elements != null) {
|
||||
for (LookupElement element : elements) {
|
||||
jetResult.addElement(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isOnlyKeywordCompletion(PsiElement position) {
|
||||
return PsiTreeUtil.getParentOfType(position, JetModifierList.class) != null;
|
||||
}
|
||||
|
||||
private void addJetExtensions() {
|
||||
Project project = getPosition().getProject();
|
||||
JetShortNamesCache namesCache = JetShortNamesCache.getKotlinInstance(project);
|
||||
|
||||
Collection<DeclarationDescriptor> jetCallableExtensions = namesCache.getJetCallableExtensions(
|
||||
jetResult.getShortNameFilter(),
|
||||
jetReference.getExpression(),
|
||||
getResolveSession(),
|
||||
GlobalSearchScope.allScope(project));
|
||||
|
||||
jetResult.addAllElements(jetCallableExtensions);
|
||||
}
|
||||
|
||||
private static boolean isPartOfTypeDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof PackageViewDescriptor || descriptor instanceof TypeParameterDescriptor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
||||
|
||||
if (KotlinBuiltIns.getInstance().isUnit(classDescriptor.getDefaultType())) return true;
|
||||
|
||||
ClassKind kind = classDescriptor.getKind();
|
||||
return !(kind == ClassKind.OBJECT || kind == ClassKind.CLASS_OBJECT);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addJetTopLevelFunctions() {
|
||||
String actualPrefix = jetResult.getResult().getPrefixMatcher().getPrefix();
|
||||
Project project = getPosition().getProject();
|
||||
|
||||
JetShortNamesCache namesCache = JetShortNamesCache.getKotlinInstance(project);
|
||||
GlobalSearchScope scope = GlobalSearchScope.allScope(project);
|
||||
Collection<String> functionNames = namesCache.getAllTopLevelFunctionNames();
|
||||
|
||||
// TODO: Fix complete extension not only on contains
|
||||
for (String name : functionNames) {
|
||||
if (name.contains(actualPrefix)) {
|
||||
jetResult.addAllElements(namesCache.getTopLevelFunctionDescriptorsByName(
|
||||
name, jetReference.getExpression(), getResolveSession(), scope));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addJetTopLevelObjects() {
|
||||
Project project = getPosition().getProject();
|
||||
JetShortNamesCache namesCache = JetShortNamesCache.getKotlinInstance(project);
|
||||
GlobalSearchScope scope = GlobalSearchScope.allScope(project);
|
||||
Collection<String> objectNames = namesCache.getAllTopLevelObjectNames();
|
||||
|
||||
for (String name : objectNames) {
|
||||
if (jetResult.getResult().getPrefixMatcher().prefixMatches(name)) {
|
||||
jetResult.addAllElements(namesCache.getTopLevelObjectsByName(name, jetReference.getExpression(), getResolveSession(), scope));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldRunOnlyTypeCompletion() {
|
||||
// Check that completion in the type annotation context and if there's a qualified
|
||||
// expression we are at first of it
|
||||
JetTypeReference typeReference = PsiTreeUtil.getParentOfType(getPosition(), JetTypeReference.class);
|
||||
if (typeReference != null) {
|
||||
JetSimpleNameExpression firstPartReference = PsiTreeUtil.findChildOfType(typeReference, JetSimpleNameExpression.class);
|
||||
return firstPartReference == jetReference.getExpression();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean shouldRunTopLevelCompletion() {
|
||||
if (parameters.getInvocationCount() < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PsiElement element = getPosition();
|
||||
if (getPosition().getNode().getElementType() == JetTokens.IDENTIFIER) {
|
||||
if (element.getParent() instanceof JetSimpleNameExpression) {
|
||||
if (!JetPsiUtil.isSelectorInQualified((JetSimpleNameExpression) element.getParent())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean shouldRunExtensionsCompletion() {
|
||||
return parameters.getInvocationCount() > 1 || jetResult.getResult().getPrefixMatcher().getPrefix().length() >= 3;
|
||||
}
|
||||
|
||||
private void addReferenceVariants(@NotNull final Condition<DeclarationDescriptor> filterCondition) {
|
||||
Collection<DeclarationDescriptor> descriptors = TipsManager.getReferenceVariants(
|
||||
jetReference.getExpression(), getExpressionBindingContext());
|
||||
|
||||
Collection<DeclarationDescriptor> filterDescriptors = Collections2.filter(descriptors, new Predicate<DeclarationDescriptor>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
|
||||
return descriptor != null && filterCondition.value(descriptor);
|
||||
}
|
||||
});
|
||||
|
||||
jetResult.addAllElements(filterDescriptors);
|
||||
}
|
||||
|
||||
private boolean isVisibleDescriptor(DeclarationDescriptor descriptor) {
|
||||
if (parameters.getInvocationCount() >= 2) {
|
||||
// Show everything if user insist on showing completion list
|
||||
return true;
|
||||
}
|
||||
|
||||
if (descriptor instanceof DeclarationDescriptorWithVisibility) {
|
||||
if (inDescriptor != null) {
|
||||
//noinspection ConstantConditions
|
||||
return Visibilities.isVisible((DeclarationDescriptorWithVisibility) descriptor, inDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private BindingContext getExpressionBindingContext() {
|
||||
return jetResult.getBindingContext();
|
||||
}
|
||||
|
||||
private ResolveSessionForBodies getResolveSession() {
|
||||
return jetResult.getResolveSession();
|
||||
}
|
||||
|
||||
private PsiElement getPosition() {
|
||||
return parameters.getPosition();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetCompletionResultSet getJetResult() {
|
||||
return jetResult;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompletionParameters getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.completion
|
||||
|
||||
import com.intellij.codeInsight.completion.*
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.jet.lang.descriptors.*
|
||||
import org.jetbrains.jet.lang.psi.*
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.lexer.JetTokens
|
||||
import org.jetbrains.jet.plugin.caches.JetShortNamesCache
|
||||
import org.jetbrains.jet.plugin.caches.resolve.*
|
||||
import org.jetbrains.jet.plugin.codeInsight.TipsManager
|
||||
import org.jetbrains.jet.plugin.completion.smart.SmartCompletion
|
||||
import org.jetbrains.jet.plugin.references.JetSimpleNameReference
|
||||
|
||||
class CompletionSession(public val parameters: CompletionParameters,
|
||||
resultSet: CompletionResultSet,
|
||||
private val jetReference: JetSimpleNameReference,
|
||||
position: PsiElement) {
|
||||
private val inDescriptor: DeclarationDescriptor?
|
||||
public val jetResult: JetCompletionResultSet
|
||||
|
||||
private val resolveSession = (position.getContainingFile() as JetFile).getLazyResolveSession()
|
||||
private val bindingContext = resolveSession.resolveToElement(jetReference.expression)
|
||||
private val position = parameters.getPosition()
|
||||
|
||||
;{
|
||||
inDescriptor = bindingContext.get<JetExpression, JetScope>(BindingContext.RESOLUTION_SCOPE, jetReference.expression)?.getContainingDeclaration()
|
||||
|
||||
// set prefix matcher here to override default one which relies on CompletionUtil.findReferencePrefix()
|
||||
// which sometimes works incorrectly for Kotlin
|
||||
var result = resultSet.withPrefixMatcher(CompletionUtil.findJavaIdentifierPrefix(parameters))
|
||||
|
||||
result = result.addKotlinSorting(parameters)
|
||||
|
||||
this.jetResult = JetCompletionResultSet(result, resolveSession, bindingContext, { isVisibleDescriptor(it) })
|
||||
}
|
||||
|
||||
public fun completeForReference() {
|
||||
assert(parameters.getCompletionType() == CompletionType.BASIC)
|
||||
|
||||
if (isOnlyKeywordCompletion(position)) return
|
||||
|
||||
if (shouldRunOnlyTypeCompletion()) {
|
||||
if (parameters.getInvocationCount() >= 2) {
|
||||
JetTypesCompletionHelper.addJetTypes(parameters, jetResult)
|
||||
}
|
||||
else {
|
||||
addReferenceVariants { isPartOfTypeDeclaration(it) }
|
||||
JavaCompletionContributor.advertiseSecondCompletion(parameters.getPosition().getProject(), jetResult.result)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
addReferenceVariants { true }
|
||||
|
||||
val prefix = jetResult.result.getPrefixMatcher().getPrefix()
|
||||
|
||||
// Try to avoid computing not-imported descriptors for empty prefix
|
||||
if (prefix.isEmpty()) {
|
||||
if (parameters.getInvocationCount() < 2) return
|
||||
|
||||
if (PsiTreeUtil.getParentOfType(jetReference.expression, javaClass<JetDotQualifiedExpression>()) == null) return
|
||||
}
|
||||
|
||||
if (shouldRunTopLevelCompletion()) {
|
||||
JetTypesCompletionHelper.addJetTypes(parameters, jetResult)
|
||||
addJetTopLevelFunctions()
|
||||
addJetTopLevelObjects()
|
||||
}
|
||||
|
||||
if (shouldRunExtensionsCompletion()) {
|
||||
addJetExtensions()
|
||||
}
|
||||
}
|
||||
|
||||
public fun completeSmart() {
|
||||
assert(parameters.getCompletionType() == CompletionType.SMART)
|
||||
|
||||
val descriptors = TipsManager.getReferenceVariants(jetReference.expression, jetResult.bindingContext)
|
||||
val completion = SmartCompletion(jetReference.expression, resolveSession, { isVisibleDescriptor(it) }, parameters.getOriginalFile() as JetFile)
|
||||
completion.buildLookupElements(descriptors)?.forEach { jetResult.addElement(it) }
|
||||
}
|
||||
|
||||
private fun isOnlyKeywordCompletion(position: PsiElement)
|
||||
= PsiTreeUtil.getParentOfType(position, javaClass<JetModifierList>()) != null
|
||||
|
||||
private fun addJetExtensions() {
|
||||
val project = position.getProject()
|
||||
val namesCache = JetShortNamesCache.getKotlinInstance(project)
|
||||
jetResult.addAllElements(namesCache.getJetCallableExtensions({ jetResult.shortNameFilter(it!!) }, jetReference.expression, resolveSession, GlobalSearchScope.allScope(project)))
|
||||
}
|
||||
|
||||
private fun isPartOfTypeDeclaration(descriptor: DeclarationDescriptor): Boolean {
|
||||
return when (descriptor) {
|
||||
is PackageViewDescriptor, is TypeParameterDescriptor -> true
|
||||
|
||||
is ClassDescriptor -> {
|
||||
val kind = descriptor.getKind()
|
||||
KotlinBuiltIns.getInstance().isUnit(descriptor.getDefaultType()) ||
|
||||
kind != ClassKind.OBJECT && kind != ClassKind.CLASS_OBJECT
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun addJetTopLevelFunctions() {
|
||||
val actualPrefix = jetResult.result.getPrefixMatcher().getPrefix()
|
||||
val project = position.getProject()
|
||||
val namesCache = JetShortNamesCache.getKotlinInstance(project)
|
||||
val scope = GlobalSearchScope.allScope(project)
|
||||
val functionNames = namesCache.getAllTopLevelFunctionNames()
|
||||
|
||||
// TODO: Fix complete extension not only on contains
|
||||
for (name in functionNames) {
|
||||
if (name.contains(actualPrefix)) {
|
||||
jetResult.addAllElements(namesCache.getTopLevelFunctionDescriptorsByName(name, jetReference.expression, resolveSession, scope))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addJetTopLevelObjects() {
|
||||
val project = position.getProject()
|
||||
val namesCache = JetShortNamesCache.getKotlinInstance(project)
|
||||
val scope = GlobalSearchScope.allScope(project)
|
||||
val objectNames = namesCache.getAllTopLevelObjectNames()
|
||||
|
||||
for (name in objectNames) {
|
||||
if (jetResult.result.getPrefixMatcher().prefixMatches(name)) {
|
||||
jetResult.addAllElements(namesCache.getTopLevelObjectsByName(name, jetReference.expression, resolveSession, scope))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun shouldRunOnlyTypeCompletion(): Boolean {
|
||||
// Check that completion in the type annotation context and if there's a qualified
|
||||
// expression we are at first of it
|
||||
val typeReference = PsiTreeUtil.getParentOfType(position, javaClass<JetTypeReference>())
|
||||
if (typeReference != null) {
|
||||
val firstPartReference = PsiTreeUtil.findChildOfType<JetSimpleNameExpression>(typeReference, javaClass<JetSimpleNameExpression>())
|
||||
return firstPartReference == jetReference.expression
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun shouldRunTopLevelCompletion(): Boolean {
|
||||
if (parameters.getInvocationCount() < 2) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (position.getNode()!!.getElementType() == JetTokens.IDENTIFIER) {
|
||||
val parent = position.getParent()
|
||||
if (parent is JetSimpleNameExpression && !JetPsiUtil.isSelectorInQualified(parent)) return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun shouldRunExtensionsCompletion(): Boolean {
|
||||
return parameters.getInvocationCount() > 1 || jetResult.result.getPrefixMatcher().getPrefix().length >= 3
|
||||
}
|
||||
|
||||
private fun addReferenceVariants(filterCondition: (DeclarationDescriptor) -> Boolean) {
|
||||
val descriptors = TipsManager.getReferenceVariants(jetReference.expression, jetResult.bindingContext)
|
||||
jetResult.addAllElements(descriptors.filter { filterCondition(it) })
|
||||
}
|
||||
|
||||
private fun isVisibleDescriptor(descriptor: DeclarationDescriptor): Boolean {
|
||||
// Show everything if user insist on showing completion list
|
||||
if (parameters.getInvocationCount() >= 2) return true
|
||||
|
||||
if (descriptor is DeclarationDescriptorWithVisibility && inDescriptor != null) {
|
||||
return Visibilities.isVisible(descriptor as DeclarationDescriptorWithVisibility, inDescriptor)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -83,13 +83,12 @@ public class JetCompletionContributor : CompletionContributor() {
|
||||
}
|
||||
|
||||
val expressionEnd = expression.getTextRange()!!.getEndOffset()
|
||||
val suggestedReplacementOffset: Int
|
||||
if (expression is JetCallExpression) {
|
||||
val suggestedReplacementOffset = if (expression is JetCallExpression) {
|
||||
val calleeExpression = (expression as JetCallExpression).getCalleeExpression()
|
||||
suggestedReplacementOffset = if (calleeExpression != null) calleeExpression.getTextRange()!!.getEndOffset() else expressionEnd
|
||||
if (calleeExpression != null) calleeExpression.getTextRange()!!.getEndOffset() else expressionEnd
|
||||
}
|
||||
else {
|
||||
suggestedReplacementOffset = expressionEnd
|
||||
expressionEnd
|
||||
}
|
||||
if (suggestedReplacementOffset > context.getReplacementOffset()) {
|
||||
context.setReplacementOffset(suggestedReplacementOffset)
|
||||
@@ -123,7 +122,7 @@ public class JetCompletionContributor : CompletionContributor() {
|
||||
if (parameters.getCompletionType() == CompletionType.BASIC) {
|
||||
session.completeForReference()
|
||||
|
||||
if (!session.getJetResult().isSomethingAdded() && session.getParameters().getInvocationCount() < 2) {
|
||||
if (!session.jetResult.isSomethingAdded && session.parameters.getInvocationCount() < 2) {
|
||||
// Rerun completion if nothing was found
|
||||
session = CompletionSession(parameters.withInvocationCount(2), result, jetReference, position)
|
||||
session.completeForReference()
|
||||
@@ -139,22 +138,8 @@ public class JetCompletionContributor : CompletionContributor() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getJetReference(parameters: CompletionParameters): JetSimpleNameReference? {
|
||||
val element = parameters.getPosition()
|
||||
val parent = element.getParent()
|
||||
if (parent != null) {
|
||||
val references = parent.getReferences()
|
||||
if (references.size != 0) {
|
||||
for (reference in references) {
|
||||
if (reference is JetSimpleNameReference) {
|
||||
return reference as JetSimpleNameReference
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
private fun getJetReference(parameters: CompletionParameters): JetSimpleNameReference?
|
||||
= parameters.getPosition().getParent()?.getReferences()?.filterIsInstance(javaClass<JetSimpleNameReference>())?.firstOrNull()
|
||||
|
||||
private fun isAtEndOfLine(offset: Int, document: Document): Boolean {
|
||||
var i = offset
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.completion;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionResultSet;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator;
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.CaretPosition;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.GenerateLambdaInfo;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.HandlersPackage;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler;
|
||||
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class JetCompletionResultSet {
|
||||
private final ResolveSessionForBodies resolveSession;
|
||||
private final BindingContext bindingContext;
|
||||
private final Condition<DeclarationDescriptor> descriptorFilter;
|
||||
private final CompletionResultSet result;
|
||||
private boolean isSomethingAdded;
|
||||
|
||||
public JetCompletionResultSet(
|
||||
@NotNull CompletionResultSet result,
|
||||
@NotNull ResolveSessionForBodies resolveSession,
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull Condition<DeclarationDescriptor> descriptorFilter) {
|
||||
this.result = result;
|
||||
this.resolveSession = resolveSession;
|
||||
this.bindingContext = bindingContext;
|
||||
this.descriptorFilter = descriptorFilter;
|
||||
}
|
||||
|
||||
public ResolveSessionForBodies getResolveSession() {
|
||||
return resolveSession;
|
||||
}
|
||||
|
||||
public BindingContext getBindingContext() {
|
||||
return bindingContext;
|
||||
}
|
||||
|
||||
public CompletionResultSet getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addAllElements(@NotNull Iterable<? extends DeclarationDescriptor> descriptors) {
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
addElement(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
public void addElement(DeclarationDescriptor descriptor) {
|
||||
if (!descriptorFilter.value(descriptor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
addElement(DescriptorLookupConverter.createLookupElement(resolveSession, descriptor));
|
||||
|
||||
// add special item for function with one argument of function type with more than one parameter
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
||||
if (parameters.size() == 1) {
|
||||
final JetType parameterType = parameters.get(0).getType();
|
||||
if (KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(parameterType)) {
|
||||
int parameterCount = KotlinBuiltIns.getInstance().getParameterTypeProjectionsFromFunctionType(parameterType).size();
|
||||
if (parameterCount > 1) {
|
||||
LookupElement lookupElement = DescriptorLookupConverter.createLookupElement(resolveSession, descriptor);
|
||||
addElement(new LookupElementDecorator<LookupElement>(lookupElement) {
|
||||
@Override
|
||||
public void renderElement(@NotNull LookupElementPresentation presentation) {
|
||||
super.renderElement(presentation);
|
||||
presentation.setItemText(getLookupString() + " " + HandlersPackage.buildLambdaPresentation(parameterType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context) {
|
||||
new JetFunctionInsertHandler(CaretPosition.IN_BRACKETS, new GenerateLambdaInfo(parameterType, true))
|
||||
.handleInsert(context, this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addElement(@NotNull LookupElement element) {
|
||||
if (!result.getPrefixMatcher().prefixMatches(element)) return;
|
||||
|
||||
result.addElement(element);
|
||||
isSomethingAdded = true;
|
||||
}
|
||||
|
||||
public boolean isSomethingAdded() {
|
||||
return isSomethingAdded;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Condition<String> getShortNameFilter() {
|
||||
return new Condition<String>() {
|
||||
@Override
|
||||
public boolean value(String s) {
|
||||
return result.getPrefixMatcher().prefixMatches(s);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.completion
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionResultSet
|
||||
import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||
import com.intellij.openapi.util.Condition
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.plugin.completion.handlers.*
|
||||
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
|
||||
|
||||
public class JetCompletionResultSet(public val result: CompletionResultSet,
|
||||
public val resolveSession: ResolveSessionForBodies,
|
||||
public val bindingContext: BindingContext,
|
||||
private val descriptorFilter: (DeclarationDescriptor) -> Boolean) {
|
||||
public var isSomethingAdded: Boolean = false
|
||||
private set
|
||||
|
||||
public fun addAllElements(descriptors: Iterable<DeclarationDescriptor>) {
|
||||
for (descriptor in descriptors) {
|
||||
addElement(descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
public fun addElement(descriptor: DeclarationDescriptor) {
|
||||
if (!descriptorFilter(descriptor)) return
|
||||
|
||||
addElement(DescriptorLookupConverter.createLookupElement(resolveSession, descriptor))
|
||||
|
||||
// add special item for function with one argument of function type with more than one parameter
|
||||
if (descriptor is FunctionDescriptor) {
|
||||
val parameters = descriptor.getValueParameters()
|
||||
if (parameters.size() == 1) {
|
||||
val parameterType = parameters.get(0).getType()
|
||||
if (KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(parameterType)) {
|
||||
val parameterCount = KotlinBuiltIns.getInstance().getParameterTypeProjectionsFromFunctionType(parameterType).size()
|
||||
if (parameterCount > 1) {
|
||||
val lookupElement = DescriptorLookupConverter.createLookupElement(resolveSession, descriptor)
|
||||
addElement(object : LookupElementDecorator<LookupElement>(lookupElement) {
|
||||
override fun renderElement(presentation: LookupElementPresentation) {
|
||||
super.renderElement(presentation)
|
||||
presentation.setItemText(getLookupString() + " " + buildLambdaPresentation(parameterType))
|
||||
}
|
||||
|
||||
override fun handleInsert(context: InsertionContext) {
|
||||
JetFunctionInsertHandler(CaretPosition.IN_BRACKETS, GenerateLambdaInfo(parameterType, true)).handleInsert(context, this)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun addElement(element: LookupElement) {
|
||||
if (!result.getPrefixMatcher().prefixMatches(element)) return
|
||||
|
||||
result.addElement(element)
|
||||
isSomethingAdded = true
|
||||
}
|
||||
|
||||
public val shortNameFilter: (String) -> Boolean = { result.getPrefixMatcher().prefixMatches(it) }
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.completion;
|
||||
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.asJava.KotlinLightClass;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaResolverPsiUtils;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.plugin.caches.JetFromJavaDescriptorHelper;
|
||||
import org.jetbrains.jet.plugin.caches.JetShortNamesCache;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.JetJavaClassInsertHandler;
|
||||
import org.jetbrains.jet.plugin.project.ProjectStructureUtil;
|
||||
|
||||
public class JetTypesCompletionHelper {
|
||||
private JetTypesCompletionHelper() {
|
||||
}
|
||||
|
||||
static void addJetTypes(
|
||||
@NotNull CompletionParameters parameters,
|
||||
@NotNull JetCompletionResultSet jetCompletionResult
|
||||
) {
|
||||
assert parameters.getInvocationCount() >= 2: "Method should be used only for force completion. In other case complete classes from scope";
|
||||
|
||||
jetCompletionResult.addAllElements(KotlinBuiltIns.getInstance().getNonPhysicalClasses());
|
||||
|
||||
Project project = parameters.getOriginalFile().getProject();
|
||||
JetShortNamesCache namesCache = JetShortNamesCache.getKotlinInstance(project);
|
||||
jetCompletionResult.addAllElements(namesCache.getJetClassesDescriptors(
|
||||
jetCompletionResult.getShortNameFilter(), jetCompletionResult.getResolveSession(), GlobalSearchScope.allScope(project)));
|
||||
|
||||
if (!ProjectStructureUtil.isJsKotlinModule((JetFile) parameters.getOriginalFile())) {
|
||||
addAdaptedJavaCompletion(parameters, jetCompletionResult);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add java elements with performing conversion to kotlin elements if necessary.
|
||||
*/
|
||||
private static void addAdaptedJavaCompletion(
|
||||
@NotNull CompletionParameters parameters,
|
||||
@NotNull final JetCompletionResultSet jetCompletionResult
|
||||
) {
|
||||
JavaClassNameCompletionContributor.addAllClasses(
|
||||
parameters,
|
||||
false,
|
||||
JavaCompletionSorting.addJavaSorting(parameters, jetCompletionResult.getResult()).getPrefixMatcher(),
|
||||
new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement lookupElement) {
|
||||
if (lookupElement instanceof JavaPsiClassReferenceElement) {
|
||||
final JavaPsiClassReferenceElement javaPsiReferenceElement = (JavaPsiClassReferenceElement) lookupElement;
|
||||
|
||||
PsiClass psiClass = javaPsiReferenceElement.getObject();
|
||||
if (addJavaClassAsJetLookupElement(psiClass, jetCompletionResult)) {
|
||||
return;
|
||||
}
|
||||
|
||||
jetCompletionResult.addElement(new LookupElementDecorator<LookupElement>(javaPsiReferenceElement) {
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context) {
|
||||
JetJavaClassInsertHandler.INSTANCE.handleInsert(context, javaPsiReferenceElement);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean addJavaClassAsJetLookupElement(PsiClass aClass, JetCompletionResultSet jetCompletionResult) {
|
||||
if (aClass instanceof KotlinLightClass) {
|
||||
// Do nothing. Kotlin not-compiled class should have already been added as kotlin element before.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (JavaResolverPsiUtils.isCompiledKotlinClass(aClass)) {
|
||||
if (JetFromJavaDescriptorHelper.getCompiledClassKind(aClass) != ClassKind.CLASS_OBJECT) {
|
||||
String qualifiedName = aClass.getQualifiedName();
|
||||
if (qualifiedName != null) {
|
||||
FqName fqName = new FqName(qualifiedName);
|
||||
jetCompletionResult.addAllElements(
|
||||
ResolveSessionUtils.getClassDescriptorsByFqName(jetCompletionResult.getResolveSession(), fqName));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.plugin.completion
|
||||
|
||||
import com.intellij.codeInsight.completion.*
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.util.Consumer
|
||||
import org.jetbrains.jet.asJava.KotlinLightClass
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind
|
||||
import org.jetbrains.jet.lang.psi.JetFile
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaResolverPsiUtils
|
||||
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.plugin.caches.JetFromJavaDescriptorHelper
|
||||
import org.jetbrains.jet.plugin.caches.JetShortNamesCache
|
||||
import org.jetbrains.jet.plugin.completion.handlers.JetJavaClassInsertHandler
|
||||
import org.jetbrains.jet.plugin.project.ProjectStructureUtil
|
||||
|
||||
object JetTypesCompletionHelper {
|
||||
fun addJetTypes(parameters: CompletionParameters, jetCompletionResult: JetCompletionResultSet) {
|
||||
assert(parameters.getInvocationCount() >= 2, "Method should be used only for force completion. In other case complete classes from scope")
|
||||
|
||||
jetCompletionResult.addAllElements(KotlinBuiltIns.getInstance().getNonPhysicalClasses())
|
||||
|
||||
val project = parameters.getOriginalFile().getProject()
|
||||
val namesCache = JetShortNamesCache.getKotlinInstance(project)
|
||||
jetCompletionResult.addAllElements(namesCache.getJetClassesDescriptors({ jetCompletionResult.shortNameFilter(it!!) }, jetCompletionResult.resolveSession, GlobalSearchScope.allScope(project)))
|
||||
|
||||
if (!ProjectStructureUtil.isJsKotlinModule(parameters.getOriginalFile() as JetFile)) {
|
||||
addAdaptedJavaCompletion(parameters, jetCompletionResult)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add java elements with performing conversion to kotlin elements if necessary.
|
||||
*/
|
||||
private fun addAdaptedJavaCompletion(parameters: CompletionParameters, jetCompletionResult: JetCompletionResultSet) {
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters, false, JavaCompletionSorting.addJavaSorting(parameters, jetCompletionResult.result).getPrefixMatcher(), object : Consumer<LookupElement> {
|
||||
override fun consume(lookupElement: LookupElement?) {
|
||||
if (lookupElement is JavaPsiClassReferenceElement) {
|
||||
val psiClass = lookupElement.getObject()
|
||||
|
||||
if (addJavaClassAsJetLookupElement(psiClass, jetCompletionResult)) return
|
||||
|
||||
jetCompletionResult.addElement(object : LookupElementDecorator<LookupElement>(lookupElement) {
|
||||
override fun handleInsert(context: InsertionContext) {
|
||||
JetJavaClassInsertHandler.INSTANCE.handleInsert(context, lookupElement)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun addJavaClassAsJetLookupElement(aClass: PsiClass, jetCompletionResult: JetCompletionResultSet): Boolean {
|
||||
if (aClass is KotlinLightClass) {
|
||||
// Do nothing. Kotlin not-compiled class should have already been added as kotlin element before.
|
||||
return true
|
||||
}
|
||||
|
||||
if (JavaResolverPsiUtils.isCompiledKotlinClass(aClass)) {
|
||||
if (JetFromJavaDescriptorHelper.getCompiledClassKind(aClass) != ClassKind.CLASS_OBJECT) {
|
||||
val qualifiedName = aClass.getQualifiedName()
|
||||
if (qualifiedName != null) {
|
||||
jetCompletionResult.addAllElements(ResolveSessionUtils.getClassDescriptorsByFqName(jetCompletionResult.resolveSession, FqName(qualifiedName)))
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user