Converted more completion code to Kotlin
This commit is contained in:
@@ -19,6 +19,10 @@
|
||||
name='com.intellij.codeInsight.completion.CompletionProvider void addCompletions(V, com.intellij.util.ProcessingContext, com.intellij.codeInsight.completion.CompletionResultSet) 1'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.completion.CompletionService com.intellij.codeInsight.completion.CompletionService getCompletionService()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.codeInsight.completion.CompletionSorter com.intellij.codeInsight.completion.CompletionSorter weighAfter(java.lang.String, com.intellij.codeInsight.lookup.LookupElementWeigher...)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
|
||||
@@ -1,40 +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.CompletionProgressIndicator;
|
||||
import com.intellij.codeInsight.completion.CompletionService;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CompletionProgressIndicatorUtil {
|
||||
private CompletionProgressIndicatorUtil() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ProcessCanceledException rethrowWithCancelIndicator(ProcessCanceledException exception) {
|
||||
CompletionProgressIndicator indicator = (CompletionProgressIndicator) CompletionService.getCompletionService().getCurrentCompletion();
|
||||
assert indicator != null;
|
||||
|
||||
// Force cancel to avoid deadlock in CompletionThreading.delegateWeighing()
|
||||
if (!indicator.isCanceled()) {
|
||||
indicator.cancel();
|
||||
}
|
||||
|
||||
return exception;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,9 @@ package org.jetbrains.jet.plugin.completion
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.codeInsight.completion.CompletionService
|
||||
import com.intellij.codeInsight.completion.CompletionProgressIndicator
|
||||
|
||||
enum class ItemPriority {
|
||||
DEFAULT
|
||||
@@ -41,3 +44,13 @@ fun LookupElement.keepOldArgumentListOnTab(): LookupElement {
|
||||
return this
|
||||
}
|
||||
|
||||
fun rethrowWithCancelIndicator(exception: ProcessCanceledException): ProcessCanceledException {
|
||||
val indicator = CompletionService.getCompletionService().getCurrentCompletion() as CompletionProgressIndicator
|
||||
|
||||
// Force cancel to avoid deadlock in CompletionThreading.delegateWeighing()
|
||||
if (!indicator.isCanceled()) {
|
||||
indicator.cancel()
|
||||
}
|
||||
|
||||
return exception
|
||||
}
|
||||
|
||||
@@ -1,144 +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.collect.Lists;
|
||||
import com.intellij.codeInsight.completion.InsertHandler;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.plugin.JetDescriptorIconProvider;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.CaretPosition;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.GenerateLambdaInfo;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.JetClassInsertHandler;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class DescriptorLookupConverter {
|
||||
private DescriptorLookupConverter() {}
|
||||
|
||||
@NotNull
|
||||
public static LookupElement createLookupElement(@NotNull KotlinCodeAnalyzer analyzer,
|
||||
@NotNull DeclarationDescriptor descriptor, @Nullable PsiElement declaration) {
|
||||
LookupElementBuilder element = LookupElementBuilder.create(
|
||||
new DeclarationLookupObject(descriptor, analyzer, declaration), descriptor.getName().asString());
|
||||
|
||||
String presentableText = descriptor.getName().asString();
|
||||
String typeText = "";
|
||||
String tailText = "";
|
||||
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
JetType returnType = functionDescriptor.getReturnType();
|
||||
typeText = returnType != null ? DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(returnType) : "";
|
||||
presentableText += DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderFunctionParameters(functionDescriptor);
|
||||
|
||||
boolean extensionFunction = functionDescriptor.getReceiverParameter() != null;
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (containingDeclaration != null && extensionFunction) {
|
||||
tailText += " for " + DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(functionDescriptor.getReceiverParameter().getType());
|
||||
tailText += " in " + DescriptorUtils.getFqName(containingDeclaration);
|
||||
}
|
||||
}
|
||||
else if (descriptor instanceof VariableDescriptor) {
|
||||
JetType outType = ((VariableDescriptor) descriptor).getType();
|
||||
typeText = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(outType);
|
||||
}
|
||||
else if (descriptor instanceof ClassDescriptor) {
|
||||
DeclarationDescriptor declaredIn = descriptor.getContainingDeclaration();
|
||||
assert declaredIn != null;
|
||||
tailText = " (" + DescriptorUtils.getFqName(declaredIn) + ")";
|
||||
}
|
||||
else {
|
||||
typeText = DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(descriptor);
|
||||
}
|
||||
|
||||
InsertHandler<LookupElement> insertHandler = getDefaultInsertHandler(descriptor);
|
||||
element = element.withInsertHandler(insertHandler);
|
||||
if (insertHandler instanceof JetFunctionInsertHandler && ((JetFunctionInsertHandler)insertHandler).getLambdaInfo() != null) {
|
||||
element.putUserData(JetCompletionCharFilter.ACCEPT_OPENING_BRACE, true);
|
||||
}
|
||||
element = element.withTailText(tailText, true).withTypeText(typeText).withPresentableText(presentableText);
|
||||
element = element.withIcon(JetDescriptorIconProvider.getIcon(descriptor, declaration, Iconable.ICON_FLAG_VISIBILITY));
|
||||
element = element.withStrikeoutness(KotlinBuiltIns.getInstance().isDeprecated(descriptor));
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static InsertHandler<LookupElement> getDefaultInsertHandler(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
||||
|
||||
if (parameters.isEmpty()) {
|
||||
return JetFunctionInsertHandler.NO_PARAMETERS_HANDLER;
|
||||
}
|
||||
|
||||
if (parameters.size() == 1) {
|
||||
JetType parameterType = parameters.get(0).getType();
|
||||
if (KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(parameterType)) {
|
||||
int parameterCount = KotlinBuiltIns.getInstance().getParameterTypeProjectionsFromFunctionType(parameterType).size();
|
||||
if (parameterCount <= 1) { // otherwise additional item with lambda template is to be added
|
||||
return new JetFunctionInsertHandler(CaretPosition.IN_BRACKETS, new GenerateLambdaInfo(parameterType, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JetFunctionInsertHandler.WITH_PARAMETERS_HANDLER;
|
||||
}
|
||||
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
return JetClassInsertHandler.INSTANCE$;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LookupElement createLookupElement(@NotNull KotlinCodeAnalyzer analyzer, @NotNull DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof CallableMemberDescriptor) {
|
||||
descriptor = DescriptorUtils.unwrapFakeOverride((CallableMemberDescriptor) descriptor);
|
||||
}
|
||||
return createLookupElement(analyzer, descriptor, DescriptorToSourceUtils.descriptorToDeclaration(descriptor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LookupElement[] collectLookupElements(
|
||||
@NotNull KotlinCodeAnalyzer analyzer,
|
||||
@NotNull Iterable<DeclarationDescriptor> descriptors
|
||||
) {
|
||||
List<LookupElement> result = Lists.newArrayList();
|
||||
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
result.add(createLookupElement(analyzer, descriptor));
|
||||
}
|
||||
|
||||
return result.toArray(new LookupElement[result.size()]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.InsertHandler
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import com.intellij.openapi.util.Iconable
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.jet.lang.descriptors.*
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.plugin.JetDescriptorIconProvider
|
||||
import org.jetbrains.jet.plugin.completion.handlers.CaretPosition
|
||||
import org.jetbrains.jet.plugin.completion.handlers.GenerateLambdaInfo
|
||||
import org.jetbrains.jet.plugin.completion.handlers.JetClassInsertHandler
|
||||
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer
|
||||
|
||||
public object DescriptorLookupConverter {
|
||||
public fun createLookupElement(analyzer: KotlinCodeAnalyzer, descriptor: DeclarationDescriptor, declaration: PsiElement?): LookupElement {
|
||||
var element = LookupElementBuilder.create(DeclarationLookupObject(descriptor, analyzer, declaration), descriptor.getName().asString())
|
||||
|
||||
var presentableText = descriptor.getName().asString()
|
||||
var typeText = ""
|
||||
var tailText = ""
|
||||
|
||||
if (descriptor is FunctionDescriptor) {
|
||||
val returnType = descriptor.getReturnType()
|
||||
typeText = if (returnType != null) DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(returnType) else ""
|
||||
presentableText += DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderFunctionParameters(descriptor)
|
||||
|
||||
if (descriptor.getReceiverParameter() != null) {
|
||||
tailText += " for " + DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(descriptor.getReceiverParameter()!!.getType())
|
||||
tailText += " in " + DescriptorUtils.getFqName(descriptor.getContainingDeclaration())
|
||||
}
|
||||
}
|
||||
else if (descriptor is VariableDescriptor) {
|
||||
typeText = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(descriptor.getType())
|
||||
}
|
||||
else if (descriptor is ClassDescriptor) {
|
||||
tailText = " (" + DescriptorUtils.getFqName(descriptor.getContainingDeclaration()) + ")"
|
||||
}
|
||||
else {
|
||||
typeText = DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(descriptor)
|
||||
}
|
||||
|
||||
val insertHandler = getDefaultInsertHandler(descriptor)
|
||||
element = element.withInsertHandler(insertHandler)
|
||||
|
||||
if (insertHandler is JetFunctionInsertHandler && insertHandler.lambdaInfo != null) {
|
||||
element.putUserData<Boolean>(JetCompletionCharFilter.ACCEPT_OPENING_BRACE, true)
|
||||
}
|
||||
|
||||
element = element.withTailText(tailText, true).withTypeText(typeText).withPresentableText(presentableText)
|
||||
element = element.withIcon(JetDescriptorIconProvider.getIcon(descriptor, declaration, Iconable.ICON_FLAG_VISIBILITY))
|
||||
element = element.withStrikeoutness(KotlinBuiltIns.getInstance().isDeprecated(descriptor))
|
||||
|
||||
return element
|
||||
}
|
||||
|
||||
public fun getDefaultInsertHandler(descriptor: DeclarationDescriptor): InsertHandler<LookupElement>? {
|
||||
return when (descriptor) {
|
||||
is FunctionDescriptor -> {
|
||||
val parameters = descriptor.getValueParameters()
|
||||
when (parameters.size) {
|
||||
0 -> JetFunctionInsertHandler.NO_PARAMETERS_HANDLER
|
||||
|
||||
1 -> {
|
||||
val parameterType = parameters.single().getType()
|
||||
if (KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(parameterType)) {
|
||||
val parameterCount = KotlinBuiltIns.getInstance().getParameterTypeProjectionsFromFunctionType(parameterType).size()
|
||||
if (parameterCount <= 1) {
|
||||
// otherwise additional item with lambda template is to be added
|
||||
return JetFunctionInsertHandler(CaretPosition.IN_BRACKETS, GenerateLambdaInfo(parameterType, false))
|
||||
}
|
||||
}
|
||||
JetFunctionInsertHandler.WITH_PARAMETERS_HANDLER
|
||||
}
|
||||
|
||||
else -> JetFunctionInsertHandler.WITH_PARAMETERS_HANDLER
|
||||
}
|
||||
}
|
||||
|
||||
is ClassDescriptor -> JetClassInsertHandler
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
public fun createLookupElement(analyzer: KotlinCodeAnalyzer, descriptor: DeclarationDescriptor): LookupElement {
|
||||
val _descriptor = if (descriptor is CallableMemberDescriptor)
|
||||
DescriptorUtils.unwrapFakeOverride(descriptor)
|
||||
else
|
||||
descriptor
|
||||
return createLookupElement(analyzer, _descriptor, DescriptorToSourceUtils.descriptorToDeclaration(_descriptor))
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ public class JetCompletionContributor : CompletionContributor() {
|
||||
}
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
throw CompletionProgressIndicatorUtil.rethrowWithCancelIndicator(e)
|
||||
throw rethrowWithCancelIndicator(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,20 +17,15 @@
|
||||
package org.jetbrains.jet.plugin.completion
|
||||
|
||||
import com.intellij.codeInsight.completion.*
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.patterns.ElementPattern
|
||||
import com.intellij.patterns.PlatformPatterns
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.util.ProcessingContext
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.jet.lang.psi.JetFile
|
||||
import org.jetbrains.jet.lang.psi.JetPackageDirective
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.plugin.caches.resolve.*
|
||||
import org.jetbrains.jet.plugin.codeInsight.TipsManager
|
||||
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
|
||||
import org.jetbrains.jet.plugin.references.JetSimpleNameReference
|
||||
|
||||
/**
|
||||
@@ -47,10 +42,10 @@ public class JetPackagesContributor : CompletionContributor() {
|
||||
{
|
||||
extend(CompletionType.BASIC, ACTIVATION_PATTERN, object : CompletionProvider<CompletionParameters>() {
|
||||
override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
|
||||
val position = parameters.getPosition()
|
||||
if (position.getContainingFile() !is JetFile) return
|
||||
val file = parameters.getPosition().getContainingFile()
|
||||
if (file !is JetFile) return
|
||||
|
||||
val ref = parameters.getPosition().getContainingFile()!!.findReferenceAt(parameters.getOffset())
|
||||
val ref = file.findReferenceAt(parameters.getOffset())
|
||||
|
||||
if (ref is JetSimpleNameReference) {
|
||||
val name = ref.expression.getText() ?: return
|
||||
@@ -63,16 +58,17 @@ public class JetPackagesContributor : CompletionContributor() {
|
||||
val bindingContext = resolveSession.resolveToElement(ref.expression)
|
||||
|
||||
val variants = TipsManager.getPackageReferenceVariants(ref.expression, bindingContext)
|
||||
for (variant in DescriptorLookupConverter.collectLookupElements(resolveSession, variants)) {
|
||||
if (!variant.getLookupString().contains(DUMMY_IDENTIFIER)) {
|
||||
result.addElement(variant)
|
||||
for (variant in variants) {
|
||||
val lookupElement = DescriptorLookupConverter.createLookupElement(resolveSession, variant)
|
||||
if (!lookupElement.getLookupString().contains(DUMMY_IDENTIFIER)) {
|
||||
result.addElement(lookupElement)
|
||||
}
|
||||
}
|
||||
|
||||
result.stopHere()
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
throw CompletionProgressIndicatorUtil.rethrowWithCancelIndicator(e)
|
||||
throw rethrowWithCancelIndicator(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user