diff --git a/annotations/com/intellij/codeInsight/completion/annotations.xml b/annotations/com/intellij/codeInsight/completion/annotations.xml index 4ace98ca782..5b8a43d1ea4 100644 --- a/annotations/com/intellij/codeInsight/completion/annotations.xml +++ b/annotations/com/intellij/codeInsight/completion/annotations.xml @@ -19,6 +19,10 @@ name='com.intellij.codeInsight.completion.CompletionProvider void addCompletions(V, com.intellij.util.ProcessingContext, com.intellij.codeInsight.completion.CompletionResultSet) 1'> + + + diff --git a/idea/src/org/jetbrains/jet/plugin/completion/CompletionProgressIndicatorUtil.java b/idea/src/org/jetbrains/jet/plugin/completion/CompletionProgressIndicatorUtil.java deleted file mode 100644 index de312447bc2..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/completion/CompletionProgressIndicatorUtil.java +++ /dev/null @@ -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; - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/completion/CompletionUtils.kt b/idea/src/org/jetbrains/jet/plugin/completion/CompletionUtils.kt index dd4d38d83d7..bc3a4569fba 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/CompletionUtils.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/CompletionUtils.kt @@ -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 +} diff --git a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java deleted file mode 100644 index d2dd702dca3..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java +++ /dev/null @@ -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 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 getDefaultInsertHandler(@NotNull DeclarationDescriptor descriptor) { - if (descriptor instanceof FunctionDescriptor) { - FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; - List 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 descriptors - ) { - List result = Lists.newArrayList(); - - for (DeclarationDescriptor descriptor : descriptors) { - result.add(createLookupElement(analyzer, descriptor)); - } - - return result.toArray(new LookupElement[result.size()]); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.kt b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.kt new file mode 100644 index 00000000000..6567a4f017c --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.kt @@ -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(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? { + 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)) + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.kt b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.kt index 88cb66cd18b..03bd6b27950 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.kt @@ -133,7 +133,7 @@ public class JetCompletionContributor : CompletionContributor() { } } catch (e: ProcessCanceledException) { - throw CompletionProgressIndicatorUtil.rethrowWithCancelIndicator(e) + throw rethrowWithCancelIndicator(e) } } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.kt b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.kt index b2d09909ff3..21b06fce5b6 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.kt @@ -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() { 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) } } }