No more java lookup elements in code completion (except for one case)

This commit is contained in:
Valentin Kipyatkov
2014-04-30 17:37:04 +04:00
parent 33de0e8393
commit 717977af61
18 changed files with 102 additions and 119 deletions
Binary file not shown.
@@ -56,7 +56,7 @@ public interface DescriptorRenderer extends Renderer<DeclarationDescriptor> {
DescriptorRenderer FQ_NAMES_IN_TYPES = new DescriptorRendererBuilder().build();
DescriptorRenderer SHORT_NAMES_IN_TYPES = new DescriptorRendererBuilder().setShortNames(true).build();
DescriptorRenderer SHORT_NAMES_IN_TYPES = new DescriptorRendererBuilder().setShortNames(true).setIncludeSynthesizedParameterNames(false).build();
DescriptorRenderer DEBUG_TEXT = new DescriptorRendererBuilder().setDebugMode(true).build();
@@ -38,6 +38,7 @@ public class DescriptorRendererBuilder {
private boolean prettyFunctionTypes = true;
private boolean uninferredTypeParameterAsName = false;
private boolean includePropertyConstant = false;
private boolean includeSynthesizedParameterNames = true;
@NotNull
private DescriptorRenderer.OverrideRenderingPolicy overrideRenderingPolicy = DescriptorRenderer.OverrideRenderingPolicy.RENDER_OPEN;
@NotNull
@@ -156,12 +157,18 @@ public class DescriptorRendererBuilder {
return this;
}
public DescriptorRendererBuilder setIncludeSynthesizedParameterNames(boolean includeSynthesizedParameterNames) {
this.includeSynthesizedParameterNames = includeSynthesizedParameterNames;
return this;
}
@NotNull
public DescriptorRenderer build() {
return new DescriptorRendererImpl(
shortNames, withDefinedIn, modifiers, startFromName, debugMode, classWithPrimaryConstructor, verbose, unitReturnType,
normalizedVisibilities, showInternalKeyword, prettyFunctionTypes, uninferredTypeParameterAsName,
overrideRenderingPolicy, valueParametersHandler, textFormat, excludedAnnotationClasses, includePropertyConstant);
overrideRenderingPolicy, valueParametersHandler, textFormat, excludedAnnotationClasses, includePropertyConstant,
includeSynthesizedParameterNames);
}
}
@@ -57,6 +57,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
private final boolean showInternalKeyword;
private final boolean prettyFunctionTypes;
private final boolean uninferredTypeParameterAsName;
private final boolean includeSynthesizedParameterNames;
@NotNull
private final OverrideRenderingPolicy overrideRenderingPolicy;
@@ -85,7 +86,8 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
@NotNull ValueParametersHandler handler,
@NotNull TextFormat textFormat,
@NotNull Collection<FqName> excludedAnnotationClasses,
boolean includePropertyConstant
boolean includePropertyConstant,
boolean includeSynthesizedParameterNames
) {
this.shortNames = shortNames;
this.withDefinedIn = withDefinedIn;
@@ -104,6 +106,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
this.excludedAnnotationClasses = Sets.newHashSet(excludedAnnotationClasses);
this.prettyFunctionTypes = prettyFunctionTypes;
this.uninferredTypeParameterAsName = uninferredTypeParameterAsName;
this.includeSynthesizedParameterNames = includeSynthesizedParameterNames;
}
/* FORMATTING */
@@ -322,7 +325,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
sb.append("(");
appendTypeProjections(KotlinBuiltIns.getInstance().getParameterTypeProjectionsFromFunctionType(type), sb);
sb.append(") " + arrow() + " ");
sb.append(") ").append(arrow()).append(" ");
sb.append(renderType(KotlinBuiltIns.getInstance().getReturnTypeFromFunctionType(type)));
if (type.isNullable()) {
@@ -582,7 +585,9 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
}
renderName(function, builder);
renderValueParameters(function, builder);
JetType returnType = function.getReturnType();
if (unitReturnType || !KotlinBuiltIns.getInstance().isUnit(returnType)) {
builder.append(": ").append(returnType == null ? "[NULL]" : escape(renderType(returnType)));
@@ -635,17 +640,18 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
}
private void renderValueParameters(@NotNull FunctionDescriptor function, @NotNull StringBuilder builder) {
boolean includeNames = includeSynthesizedParameterNames || !function.hasSynthesizedParameterNames();
handler.appendBeforeValueParameters(function, builder);
for (ValueParameterDescriptor parameter : function.getValueParameters()) {
handler.appendBeforeValueParameter(parameter, builder);
renderValueParameter(parameter, builder, false);
renderValueParameter(parameter, includeNames, builder, false);
handler.appendAfterValueParameter(parameter, builder);
}
handler.appendAfterValueParameters(function, builder);
}
/* VARIABLES */
private void renderValueParameter(@NotNull ValueParameterDescriptor valueParameter, @NotNull StringBuilder builder, boolean topLevel) {
private void renderValueParameter(@NotNull ValueParameterDescriptor valueParameter, boolean includeName, @NotNull StringBuilder builder, boolean topLevel) {
if (topLevel) {
builder.append(renderKeyword("value-parameter")).append(" ");
}
@@ -655,7 +661,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
}
renderAnnotations(valueParameter, builder);
renderVariable(valueParameter, builder, topLevel);
renderVariable(valueParameter, includeName, builder, topLevel);
boolean withDefaultValue = debugMode ? valueParameter.declaresDefaultValue() : valueParameter.hasDefaultValue();
if (withDefaultValue) {
builder.append(" = ...");
@@ -666,7 +672,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
builder.append(renderKeyword(variable.isVar() ? "var" : "val")).append(" ");
}
private void renderVariable(@NotNull VariableDescriptor variable, @NotNull StringBuilder builder, boolean topLevel) {
private void renderVariable(@NotNull VariableDescriptor variable, boolean includeName, @NotNull StringBuilder builder, boolean topLevel) {
JetType realType = variable.getType();
JetType varargElementType = variable instanceof ValueParameterDescriptor
@@ -681,8 +687,12 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
renderValVarPrefix(variable, builder);
}
renderName(variable, builder);
builder.append(": ").append(escape(renderType(typeToRender)));
if (includeName) {
renderName(variable, builder);
builder.append(": ");
}
builder.append(escape(renderType(typeToRender)));
renderInitializer(variable, builder);
@@ -824,13 +834,13 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
private class RenderDeclarationDescriptorVisitor extends DeclarationDescriptorVisitorEmptyBodies<Void, StringBuilder> {
@Override
public Void visitValueParameterDescriptor(ValueParameterDescriptor descriptor, StringBuilder builder) {
renderValueParameter(descriptor, builder, true);
renderValueParameter(descriptor, true, builder, true);
return null;
}
@Override
public Void visitVariableDescriptor(VariableDescriptor descriptor, StringBuilder builder) {
renderVariable(descriptor, builder, true);
renderVariable(descriptor, true, builder, true);
return null;
}
@@ -253,6 +253,7 @@ public class GenerateMockJdk {
"java/util/Set.class",
"java/util/SortedMap.class",
"java/util/SortedSet.class",
"java/util/TimeZone.class",
"java/util/TreeMap.class",
"javax/swing/AbstractButton.class",
"javax/swing/Icon.class",
@@ -18,11 +18,17 @@ package org.jetbrains.jet.plugin;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Iconable;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMember;
import com.intellij.ui.RowIcon;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.resolve.java.JavaResolverPsiUtils;
import javax.swing.*;
@@ -33,7 +39,11 @@ public final class JetDescriptorIconProvider {
private JetDescriptorIconProvider() {
}
public static Icon getIcon(@NotNull DeclarationDescriptor descriptor, @Iconable.IconFlags int flags) {
public static Icon getIcon(@NotNull DeclarationDescriptor descriptor, @Nullable PsiElement declaration, @Iconable.IconFlags int flags) {
if (declaration != null && !isKotlinDeclaration(declaration)) {
return declaration.getIcon(flags);
}
Icon result = getBaseIcon(descriptor);
if ((flags & Iconable.ICON_FLAG_VISIBILITY) > 0) {
RowIcon rowIcon = new RowIcon(2);
@@ -45,7 +55,7 @@ public final class JetDescriptorIconProvider {
return result;
}
public static Icon getVisibilityIcon(@NotNull DeclarationDescriptor descriptor) {
private static Icon getVisibilityIcon(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof DeclarationDescriptorWithVisibility) {
DeclarationDescriptorWithVisibility descriptorWithVisibility = (DeclarationDescriptorWithVisibility) descriptor;
Visibility visibility = descriptorWithVisibility.getVisibility();
@@ -69,7 +79,7 @@ public final class JetDescriptorIconProvider {
return null;
}
public static Icon getBaseIcon(@NotNull DeclarationDescriptor descriptor) {
private static Icon getBaseIcon(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof PackageFragmentDescriptor || descriptor instanceof PackageViewDescriptor) {
return PlatformIcons.PACKAGE_ICON;
}
@@ -131,4 +141,20 @@ public final class JetDescriptorIconProvider {
LOG.warn("No icon for descriptor: " + descriptor);
return null;
}
private static boolean isKotlinDeclaration(@NotNull PsiElement declaration) {
if (declaration instanceof JetElement) {
return true;
}
else if (declaration instanceof PsiClass) {
return JavaResolverPsiUtils.isCompiledKotlinClassOrPackageClass((PsiClass) declaration);
}
else if (declaration instanceof PsiMember) {
PsiClass containingClass = ((PsiMember) declaration).getContainingClass();
return containingClass != null && JavaResolverPsiUtils.isCompiledKotlinClassOrPackageClass(containingClass);
}
else {
return false;
}
}
}
@@ -54,7 +54,7 @@ public class DescriptorClassMember extends MemberChooserObjectBase implements Cl
int flags = isClass ? 0 : Iconable.ICON_FLAG_VISIBILITY;
if (element instanceof JetDeclaration) { // kotlin declaration
// visibility and abstraction better detect by a descriptor
return JetDescriptorIconProvider.getIcon(declarationDescriptor, flags);
return JetDescriptorIconProvider.getIcon(declarationDescriptor, element, flags);
}
else {
// it is better to show java icons for java code
@@ -62,7 +62,7 @@ public class DescriptorClassMember extends MemberChooserObjectBase implements Cl
}
}
return JetDescriptorIconProvider.getIcon(declarationDescriptor, 0);
return JetDescriptorIconProvider.getIcon(declarationDescriptor, element, 0);
}
@Override
@@ -18,26 +18,24 @@ package org.jetbrains.jet.plugin.completion;
import com.google.common.collect.Lists;
import com.intellij.codeInsight.completion.InsertHandler;
import com.intellij.codeInsight.completion.InsertionContext;
import com.intellij.codeInsight.completion.JavaMethodCallElement;
import com.intellij.codeInsight.completion.JavaPsiClassReferenceElement;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.lookup.VariableLookupItem;
import com.intellij.openapi.util.Iconable;
import com.intellij.psi.*;
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.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JavaResolverPsiUtils;
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.*;
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;
@@ -48,13 +46,6 @@ public final class DescriptorLookupConverter {
@NotNull
public static LookupElement createLookupElement(@NotNull KotlinCodeAnalyzer analyzer,
@NotNull DeclarationDescriptor descriptor, @Nullable PsiElement declaration) {
if (declaration != null) {
LookupElement javaLookupElement = createJavaLookupElementIfPossible(declaration, descriptor);
if (javaLookupElement != null) {
return javaLookupElement;
}
}
LookupElementBuilder element = LookupElementBuilder.create(
new JetLookupObject(descriptor, analyzer, declaration), descriptor.getName().asString());
@@ -94,7 +85,7 @@ public final class DescriptorLookupConverter {
element.putUserData(JetCompletionCharFilter.ACCEPT_OPENING_BRACE, true);
}
element = element.withTailText(tailText, true).withTypeText(typeText).withPresentableText(presentableText);
element = element.withIcon(JetDescriptorIconProvider.getIcon(descriptor, Iconable.ICON_FLAG_VISIBILITY));
element = element.withIcon(JetDescriptorIconProvider.getIcon(descriptor, declaration, Iconable.ICON_FLAG_VISIBILITY));
element = element.withStrikeoutness(KotlinBuiltIns.getInstance().isDeprecated(descriptor));
return element;
@@ -130,40 +121,6 @@ public final class DescriptorLookupConverter {
return null;
}
@Nullable
private static LookupElement createJavaLookupElementIfPossible(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor) {
if (declaration instanceof PsiClass) {
PsiClass psiClass = (PsiClass) declaration;
if (!JavaResolverPsiUtils.isCompiledKotlinClassOrPackageClass(psiClass)) {
return setCustomInsertHandler(new JavaPsiClassReferenceElement(psiClass));
}
}
if (declaration instanceof PsiMember) {
PsiClass containingClass = ((PsiMember) declaration).getContainingClass();
if (containingClass != null && !JavaResolverPsiUtils.isCompiledKotlinClassOrPackageClass(containingClass)) {
if (declaration instanceof PsiMethod) {
InsertHandler<LookupElement> handler = getDefaultInsertHandler(descriptor);
assert handler != null:
"Special kotlin handler is expected for function: " + declaration.getText() +
" and descriptor: " + DescriptorRenderer.FQ_NAMES_IN_TYPES.render(descriptor);
return new JavaMethodCallElementWithCustomHandler(declaration).setInsertHandler(handler);
}
if (declaration instanceof PsiField) {
return new JavaVariableLookupItemWithCustomHandler(declaration);
}
}
}
return null;
}
public static LookupElement setCustomInsertHandler(JavaPsiClassReferenceElement javaPsiReferenceElement) {
return javaPsiReferenceElement.setInsertHandler(JetJavaClassInsertHandler.INSTANCE);
}
@NotNull
public static LookupElement createLookupElement(
@NotNull KotlinCodeAnalyzer analyzer,
@@ -187,40 +144,4 @@ public final class DescriptorLookupConverter {
return result.toArray(new LookupElement[result.size()]);
}
private static class JavaMethodCallElementWithCustomHandler extends JavaMethodCallElement {
public JavaMethodCallElementWithCustomHandler(PsiElement declaration) {
super((PsiMethod) declaration);
}
@Override
public void handleInsert(InsertionContext context) {
InsertHandler<? extends LookupElement> handler = getInsertHandler();
if (handler != null) {
//noinspection unchecked
((InsertHandler)handler).handleInsert(context, this);
return;
}
super.handleInsert(context);
}
}
private static class JavaVariableLookupItemWithCustomHandler extends VariableLookupItem {
public JavaVariableLookupItemWithCustomHandler(PsiElement declaration) {
super((PsiField) declaration);
}
@Override
public void handleInsert(InsertionContext context) {
InsertHandler<? extends LookupElement> handler = getInsertHandler();
if (handler != null) {
//noinspection unchecked
((InsertHandler)handler).handleInsert(context, this);
return;
}
super.handleInsert(context);
}
}
}
@@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer;
import org.jetbrains.jet.renderer.DescriptorRenderer;
/**
* Stores information about resolved descriptor and position of that descriptor.
@@ -63,9 +62,7 @@ public final class JetLookupObject {
@Override
public int hashCode() {
int result = descriptor != null ? descriptor.hashCode() : 0;
result = 31 * result + (psiElement != null ? psiElement.hashCode() : 0);
return result;
return descriptor != null ? descriptor.hashCode() : 0;
}
@Override
@@ -80,9 +77,6 @@ public final class JetLookupObject {
return false;
}
if (descriptor != null ? !descriptor.equals(lookupObject.descriptor) : lookupObject.descriptor != null) return false;
if (psiElement != null ? !psiElement.equals(lookupObject.psiElement) : lookupObject.psiElement != null) return false;
return true;
return descriptor != null ? descriptor.equals(lookupObject.descriptor) : lookupObject.descriptor == null;
}
}
@@ -18,6 +18,7 @@ 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;
@@ -32,6 +33,7 @@ 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 {
@@ -73,14 +75,19 @@ public class JetTypesCompletionHelper {
@Override
public void consume(LookupElement lookupElement) {
if (lookupElement instanceof JavaPsiClassReferenceElement) {
JavaPsiClassReferenceElement javaPsiReferenceElement = (JavaPsiClassReferenceElement) lookupElement;
final JavaPsiClassReferenceElement javaPsiReferenceElement = (JavaPsiClassReferenceElement) lookupElement;
PsiClass psiClass = javaPsiReferenceElement.getObject();
if (addJavaClassAsJetLookupElement(psiClass, jetCompletionResult)) {
return;
}
jetCompletionResult.addElement(DescriptorLookupConverter.setCustomInsertHandler(javaPsiReferenceElement));
jetCompletionResult.addElement(new LookupElementDecorator<LookupElement>(javaPsiReferenceElement) {
@Override
public void handleInsert(InsertionContext context) {
JetJavaClassInsertHandler.INSTANCE.handleInsert(context, javaPsiReferenceElement);
}
});
}
}
});
@@ -2,5 +2,4 @@ fun foo(){
val l : java.util.Calendar = <caret>
}
// ELEMENT: Calendar.getInstance
// TAIL_TEXT: (TimeZone)
// ELEMENT_TEXT: Calendar.getInstance(TimeZone)
@@ -4,5 +4,4 @@ fun foo(){
val l : java.util.Calendar = Calendar.getInstance(<caret>)
}
// ELEMENT: Calendar.getInstance
// TAIL_TEXT: (TimeZone)
// ELEMENT_TEXT: Calendar.getInstance(TimeZone)
@@ -0,0 +1,3 @@
var a : Runnable = <caret>
// ELEMENT: Runnable
@@ -0,0 +1,3 @@
var a : Runnable = Runnable { <caret> }
// ELEMENT: Runnable
@@ -2,6 +2,6 @@ fun foo(){
val l : java.util.Calendar = <caret>
}
// EXIST: { lookupString:"Calendar.getInstance", itemText:"Calendar.getInstance", tailText:"() (java.util)", typeText:"Calendar" }
// EXIST: { lookupString:"Calendar.getInstance", itemText:"Calendar.getInstance", tailText:"(TimeZone) (java.util)", typeText:"Calendar" }
// EXIST: { lookupString:"Calendar.getInstance", itemText:"Calendar.getInstance", tailText:"(TimeZone, Locale) (java.util)", typeText:"Calendar" }
// EXIST: { lookupString:"Calendar.getInstance", itemText:"Calendar.getInstance()", tailText:" (java.util)", typeText:"Calendar" }
// EXIST: { lookupString:"Calendar.getInstance", itemText:"Calendar.getInstance(TimeZone)", tailText:" (java.util)", typeText:"Calendar" }
// EXIST: { lookupString:"Calendar.getInstance", itemText:"Calendar.getInstance(TimeZone, Locale)", tailText:" (java.util)", typeText:"Calendar" }
@@ -0,0 +1,3 @@
var a : Runnable = <caret>
// EXIST: {"lookupString":"Runnable", "tailText":"", "typeText":"Runnable", "itemText":"Runnable(function: () -> Unit)"}
@@ -386,6 +386,11 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
doTest("idea/testData/completion/smart/QualifiedThisOfExtensionLambda3.kt");
}
@TestMetadata("SAMExpected1.kt")
public void testSAMExpected1() throws Exception {
doTest("idea/testData/completion/smart/SAMExpected1.kt");
}
@TestMetadata("SkipUnresolvedTypes.kt")
public void testSkipUnresolvedTypes() throws Exception {
doTest("idea/testData/completion/smart/SkipUnresolvedTypes.kt");
@@ -321,6 +321,11 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion
doTest("idea/testData/completion/handlers/smart/NullableValueKeepOldArguments.kt");
}
@TestMetadata("SAMExpected1.kt")
public void testSAMExpected1() throws Exception {
doTest("idea/testData/completion/handlers/smart/SAMExpected1.kt");
}
@TestMetadata("TabReplaceComma1.kt")
public void testTabReplaceComma1() throws Exception {
doTest("idea/testData/completion/handlers/smart/TabReplaceComma1.kt");