@Override public void visitNamedFunction(JetNamedFunction function) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, function); // working around a problem with shallow analysis if (functionDescriptor == null) return; DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); if (containingDeclaration instanceof ClassDescriptor) { nameStack.push(peekFromStack(nameStack) + '$' + function.getName()); super.visitNamedFunction(function); nameStack.pop(); } else if (containingDeclaration instanceof NamespaceDescriptor) { String peek = peekFromStack(nameStack); if (peek.isEmpty()) { peek = JvmAbi.PACKAGE_CLASS; } else { peek += "/" + JvmAbi.PACKAGE_CLASS; } nameStack.push(peek + '$' + function.getName()); super.visitNamedFunction(function); nameStack.pop(); } else { String name = inventAnonymousClassName(function); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor); recordClosure( bindingTrace, function, classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), true); classStack.push(classDescriptor); nameStack.push(name); super.visitNamedFunction(function); nameStack.pop(); classStack.pop(); } }
@NotNull public Collection<FunctionDescriptor> getTopLevelFunctionDescriptorsByName( @NotNull String name, @NotNull JetSimpleNameExpression expression, @NotNull ResolveSession resolveSession, @NotNull GlobalSearchScope scope) { // name parameter can differ from expression.getReferenceName() when expression contains // completion suffix Name referenceName = expression.getIdentifier() == null ? JetPsiUtil.getConventionName(expression) : Name.identifier(name); if (referenceName == null || referenceName.toString().isEmpty()) { return Collections.emptyList(); } BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression); JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); if (jetScope == null) { return Collections.emptyList(); } Set<FunctionDescriptor> result = Sets.newHashSet(); Collection<PsiMethod> topLevelFunctionPrototypes = JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName( referenceName.getName(), project, scope); for (PsiMethod method : topLevelFunctionPrototypes) { FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method); if (functionFQN != null) { JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, new ImportPath(functionFQN, false)); Collection<? extends DeclarationDescriptor> declarationDescriptors = new QualifiedExpressionResolver() .analyseImportReference( importDirective, jetScope, new BindingTraceContext(), resolveSession.getModuleConfiguration()); for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) { if (declarationDescriptor instanceof FunctionDescriptor) { result.add((FunctionDescriptor) declarationDescriptor); } } } } Set<FqName> affectedPackages = Sets.newHashSet(); Collection<JetNamedFunction> jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(referenceName.getName(), project, scope); for (JetNamedFunction jetNamedFunction : jetNamedFunctions) { PsiFile containingFile = jetNamedFunction.getContainingFile(); if (containingFile instanceof JetFile) { JetFile jetFile = (JetFile) containingFile; String packageName = jetFile.getPackageName(); if (packageName != null) { affectedPackages.add(new FqName(packageName)); } } } for (FqName affectedPackage : affectedPackages) { NamespaceDescriptor packageDescriptor = resolveSession.getPackageDescriptorByFqName(affectedPackage); assert packageDescriptor != null : "There's a function in stub index with invalid package: " + affectedPackage; JetScope memberScope = packageDescriptor.getMemberScope(); result.addAll(memberScope.getFunctions(referenceName)); } return result; }