private static List<FunctionDescriptor> getSuperFunctionsForMethod( @NotNull PsiMethodWrapper method, @NotNull BindingTrace trace, @NotNull ClassDescriptor containingClass) { List<FunctionDescriptor> superFunctions = Lists.newArrayList(); Map<ClassDescriptor, JetType> superclassToSupertype = getSuperclassToSupertypeMap(containingClass); Multimap<FqName, Pair<FunctionDescriptor, PsiMethod>> superclassToFunctions = getSuperclassToFunctionsMultimap(method, trace.getBindingContext(), containingClass); for (HierarchicalMethodSignature superSignature : method.getPsiMethod().getHierarchicalMethodSignature().getSuperSignatures()) { PsiMethod superMethod = superSignature.getMethod(); PsiClass psiClass = superMethod.getContainingClass(); assert psiClass != null; String classFqNameString = psiClass.getQualifiedName(); assert classFqNameString != null; FqName classFqName = new FqName(classFqNameString); if (!JavaToKotlinClassMap.getInstance().mapPlatformClass(classFqName).isEmpty()) { for (FunctionDescriptor superFun : JavaToKotlinMethodMap.INSTANCE.getFunctions(superMethod, containingClass)) { superFunctions.add(substituteSuperFunction(superclassToSupertype, superFun)); } continue; } DeclarationDescriptor superFun = superMethod instanceof JetClsMethod ? trace.get( BindingContext.DECLARATION_TO_DESCRIPTOR, ((JetClsMethod) superMethod).getOrigin()) : findSuperFunction(superclassToFunctions.get(classFqName), superMethod); if (superFun == null) { reportCantFindSuperFunction(method); continue; } assert superFun instanceof FunctionDescriptor : superFun.getClass().getName(); superFunctions.add( substituteSuperFunction(superclassToSupertype, (FunctionDescriptor) superFun)); } // sorting for diagnostic stability Collections.sort( superFunctions, new Comparator<FunctionDescriptor>() { @Override public int compare(FunctionDescriptor fun1, FunctionDescriptor fun2) { FqNameUnsafe fqName1 = getFQName(fun1.getContainingDeclaration()); FqNameUnsafe fqName2 = getFQName(fun2.getContainingDeclaration()); return fqName1.getFqName().compareTo(fqName2.getFqName()); } }); return superFunctions; }
private void appendDescriptor(DeclarationDescriptor descriptor, String indent) { int startOffset = myBuilder.length(); myBuilder.append(DescriptorRenderer.COMPACT.render(descriptor)); int endOffset = myBuilder.length(); if (descriptor instanceof FunctionDescriptor || descriptor instanceof PropertyDescriptor) { if (((CallableMemberDescriptor) descriptor).getModality() != Modality.ABSTRACT) { if (descriptor instanceof FunctionDescriptor) { myBuilder.append(" { ").append(DECOMPILED_COMMENT).append(" }"); endOffset = myBuilder.length(); } else { // descriptor instanceof PropertyDescriptor if (((PropertyDescriptor) descriptor).getModality() != Modality.ABSTRACT) { myBuilder.append(" ").append(DECOMPILED_COMMENT); } } } } else if (descriptor instanceof ClassDescriptor) { myBuilder.append(" {\n"); ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; boolean firstPassed = false; String subindent = indent + " "; if (classDescriptor.getClassObjectDescriptor() != null) { firstPassed = true; myBuilder.append(subindent).append("class "); appendDescriptor(classDescriptor.getClassObjectDescriptor(), subindent); } for (DeclarationDescriptor member : sortDeclarations(classDescriptor.getDefaultType().getMemberScope().getAllDescriptors())) { if (member.getContainingDeclaration() == descriptor) { if (firstPassed) { myBuilder.append("\n"); } else { firstPassed = true; } myBuilder.append(subindent); appendDescriptor(member, subindent); } } myBuilder.append(indent).append("}"); endOffset = myBuilder.length(); } myBuilder.append("\n"); PsiElement clsMember = myBindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); if (clsMember != null) { myClsMembersToRanges.put(clsMember, new TextRange(startOffset, endOffset)); } }
@NotNull public static LookupElement createLookupElement( @NotNull KotlinCodeAnalyzer analyzer, @NotNull DeclarationDescriptor descriptor, @Nullable PsiElement declaration) { if (declaration != null) { MutableLookupElement javaLookupElement = createJavaLookupElementIfPossible(declaration); if (javaLookupElement != null) { InsertHandler<LookupElement> customHandler = getInsertHandler(descriptor); if (customHandler != null) { return javaLookupElement.setInsertHandler(getInsertHandler(descriptor)); } else { return javaLookupElement; } } } LookupElementBuilder element = LookupElementBuilder.create( new JetLookupObject(descriptor, analyzer, declaration), descriptor.getName().getName()); String presentableText = descriptor.getName().getName(); String typeText = ""; String tailText = ""; boolean tailTextGrayed = true; if (descriptor instanceof FunctionDescriptor) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; JetType returnType = functionDescriptor.getReturnType(); typeText = DescriptorRenderer.TEXT.renderType(returnType); presentableText += DescriptorRenderer.TEXT.renderFunctionParameters(functionDescriptor); boolean extensionFunction = functionDescriptor.getReceiverParameter() != null; DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); if (containingDeclaration != null && extensionFunction) { tailText += " for " + DescriptorRenderer.TEXT.renderType( functionDescriptor.getReceiverParameter().getType()); tailText += " in " + DescriptorUtils.getFQName(containingDeclaration); } } else if (descriptor instanceof VariableDescriptor) { JetType outType = ((VariableDescriptor) descriptor).getType(); typeText = DescriptorRenderer.TEXT.renderType(outType); } else if (descriptor instanceof ClassDescriptor) { DeclarationDescriptor declaredIn = descriptor.getContainingDeclaration(); assert declaredIn != null; tailText = " (" + DescriptorUtils.getFQName(declaredIn) + ")"; tailTextGrayed = true; } else { typeText = DescriptorRenderer.TEXT.render(descriptor); } element = element.withInsertHandler(getInsertHandler(descriptor)); element = element .withTailText(tailText, tailTextGrayed) .withTypeText(typeText) .withPresentableText(presentableText); element = element.withIcon( JetDescriptorIconProvider.getIcon(descriptor, Iconable.ICON_FLAG_VISIBILITY)); element = element.withStrikeoutness(KotlinBuiltIns.getInstance().isDeprecated(descriptor)); return element; }