@Nullable @Deprecated // Use JetPsiUtil.deparenthesize() or ExpressionTypingServices.deparenthesize() public static JetExpression deparenthesizeWithResolutionStrategy( @Nullable JetExpression expression, boolean deparenthesizeBinaryExpressionWithTypeRHS, @Nullable Function<JetTypeReference, Void> typeResolutionStrategy) { if (deparenthesizeBinaryExpressionWithTypeRHS && expression instanceof JetBinaryExpressionWithTypeRHS) { JetBinaryExpressionWithTypeRHS binaryExpression = (JetBinaryExpressionWithTypeRHS) expression; JetSimpleNameExpression operationSign = binaryExpression.getOperationReference(); if (JetTokens.COLON.equals(operationSign.getReferencedNameElementType())) { expression = binaryExpression.getLeft(); JetTypeReference typeReference = binaryExpression.getRight(); if (typeResolutionStrategy != null && typeReference != null) { typeResolutionStrategy.apply(typeReference); } } } else if (expression instanceof JetPrefixExpression) { JetExpression baseExpression = getBaseExpressionIfLabeledExpression((JetPrefixExpression) expression); if (baseExpression != null) { expression = baseExpression; } } else if (expression instanceof JetExpressionWrapper) { expression = ((JetExpressionWrapper) expression).getBaseExpression(); } if (expression instanceof JetParenthesizedExpression) { JetExpression innerExpression = ((JetParenthesizedExpression) expression).getExpression(); return innerExpression != null ? deparenthesizeWithResolutionStrategy( innerExpression, deparenthesizeBinaryExpressionWithTypeRHS, typeResolutionStrategy) : null; } return expression; }
@Nullable public static JetToken getOperationToken(@NotNull JetOperationExpression expression) { JetSimpleNameExpression operationExpression = expression.getOperationReference(); IElementType elementType = operationExpression.getReferencedNameElementType(); assert elementType == null || elementType instanceof JetToken : "JetOperationExpression should have operation token of type JetToken: " + expression; return (JetToken) elementType; }
@Nullable public static Name getAliasName(@NotNull JetImportDirective importDirective) { String aliasName = importDirective.getAliasName(); JetExpression importedReference = importDirective.getImportedReference(); if (importedReference == null) { return null; } JetSimpleNameExpression referenceExpression = getLastReference(importedReference); if (aliasName == null) { aliasName = referenceExpression != null ? referenceExpression.getReferencedName() : null; } return aliasName != null && !aliasName.isEmpty() ? Name.identifier(aliasName) : null; }
// TODO: Make it work for properties public Collection<DeclarationDescriptor> getJetCallableExtensions( @NotNull Condition<String> acceptedNameCondition, @NotNull JetSimpleNameExpression expression, @NotNull ResolveSession resolveSession, @NotNull GlobalSearchScope searchScope) { Collection<DeclarationDescriptor> resultDescriptors = new ArrayList<DeclarationDescriptor>(); BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression); JetExpression receiverExpression = expression.getReceiverExpression(); if (receiverExpression != null) { JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression); JetScope scope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression); if (expressionType != null && scope != null) { Collection<String> extensionFunctionsNames = getAllJetExtensionFunctionsNames(searchScope); Set<FqName> functionFQNs = new java.util.HashSet<FqName>(); // Collect all possible extension function qualified names for (String name : extensionFunctionsNames) { if (acceptedNameCondition.value(name)) { Collection<PsiElement> extensionFunctions = getJetExtensionFunctionsByName(name, searchScope); for (PsiElement extensionFunction : extensionFunctions) { if (extensionFunction instanceof JetNamedFunction) { functionFQNs.add(JetPsiUtil.getFQName((JetNamedFunction) extensionFunction)); } else if (extensionFunction instanceof PsiMethod) { FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN( (PsiMethod) extensionFunction); if (functionFQN != null) { functionFQNs.add(functionFQN); } } } } } // Iterate through the function with attempt to resolve found functions for (FqName functionFQN : functionFQNs) { for (CallableDescriptor functionDescriptor : ExpressionTypingUtils.canFindSuitableCall( functionFQN, project, receiverExpression, expressionType, scope, resolveSession.getModuleConfiguration())) { resultDescriptors.add(functionDescriptor); } } } } return resultDescriptors; }
@Nullable public static Name getConventionName(@NotNull JetSimpleNameExpression simpleNameExpression) { if (simpleNameExpression.getIdentifier() != null) { return simpleNameExpression.getReferencedNameAsName(); } PsiElement firstChild = simpleNameExpression.getFirstChild(); if (firstChild != null) { IElementType elementType = firstChild.getNode().getElementType(); if (elementType instanceof JetToken) { JetToken jetToken = (JetToken) elementType; return OperatorConventions.getNameForOperationSymbol(jetToken); } } return null; }
@Nullable private static FqName getFQName(@Nullable JetExpression expression) { if (expression == null) { return null; } if (expression instanceof JetDotQualifiedExpression) { JetDotQualifiedExpression dotQualifiedExpression = (JetDotQualifiedExpression) expression; FqName parentFqn = getFQName(dotQualifiedExpression.getReceiverExpression()); Name child = getName(dotQualifiedExpression.getSelectorExpression()); return parentFqn != null && child != null ? parentFqn.child(child) : null; } else if (expression instanceof JetSimpleNameExpression) { JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression; return FqName.topLevel(simpleNameExpression.getReferencedNameAsName()); } else { throw new IllegalArgumentException( "Can't construct fqn for: " + expression.getClass().toString()); } }
public static boolean isSelectorInQualified(@NotNull JetSimpleNameExpression nameExpression) { PsiElement nameExpressionParent = nameExpression.getParent(); if (nameExpressionParent instanceof JetUserType) { assert ((JetUserType) nameExpressionParent).getReferenceExpression() == nameExpression; return ((JetUserType) nameExpressionParent).getQualifier() != null; } JetExpression selector = nameExpression; if (nameExpressionParent instanceof JetCallExpression && ((JetCallExpression) nameExpressionParent).getCalleeExpression() == nameExpression) { selector = (JetCallExpression) nameExpressionParent; } PsiElement selectorParent = selector.getParent(); return selectorParent instanceof JetQualifiedExpression && (((JetQualifiedExpression) selectorParent).getSelectorExpression() == selector); }
private static JetValueArgumentList findCall(CreateParameterInfoContext context) { // todo: calls to this constructors, when we will have auxiliary constructors PsiFile file = context.getFile(); if (!(file instanceof JetFile)) { return null; } JetValueArgumentList argumentList = PsiTreeUtil.getParentOfType( file.findElementAt(context.getOffset()), JetValueArgumentList.class); if (argumentList == null) { return null; } final JetSimpleNameExpression callNameExpression = getCallSimpleNameExpression(argumentList); if (callNameExpression == null) { return null; } PsiReference[] references = callNameExpression.getReferences(); if (references.length == 0) { return null; } ResolutionFacade resolutionFacade = ResolvePackage.getResolutionFacade(callNameExpression.getContainingJetFile()); final BindingContext bindingContext = resolutionFacade.analyze(callNameExpression, BodyResolveMode.FULL); ModuleDescriptor moduleDescriptor = resolutionFacade.findModuleDescriptor(callNameExpression); JetScope scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, callNameExpression); final DeclarationDescriptor placeDescriptor; if (scope != null) { placeDescriptor = scope.getContainingDeclaration(); } else { placeDescriptor = null; } Function1<DeclarationDescriptor, Boolean> visibilityFilter = new Function1<DeclarationDescriptor, Boolean>() { @Override public Boolean invoke(DeclarationDescriptor descriptor) { if (placeDescriptor == null) return true; if (!(descriptor instanceof DeclarationDescriptorWithVisibility)) return true; return CorePackage.isVisible( (DeclarationDescriptorWithVisibility) descriptor, placeDescriptor, bindingContext, callNameExpression); } }; final Name refName = callNameExpression.getReferencedNameAsName(); Function1<Name, Boolean> nameFilter = new Function1<Name, Boolean>() { @Override public Boolean invoke(Name name) { return name.equals(refName); } }; Collection<DeclarationDescriptor> variants = new ReferenceVariantsHelper( bindingContext, moduleDescriptor, file.getProject(), visibilityFilter) .getReferenceVariants( callNameExpression, new DescriptorKindFilter( DescriptorKindFilter.FUNCTIONS_MASK | DescriptorKindFilter.CLASSIFIERS_MASK, Collections.<DescriptorKindExclude>emptyList()), nameFilter, false, false); Collection<Pair<? extends DeclarationDescriptor, ResolutionFacade>> itemsToShow = new ArrayList<Pair<? extends DeclarationDescriptor, ResolutionFacade>>(); for (DeclarationDescriptor variant : variants) { if (variant instanceof FunctionDescriptor) { // todo: renamed functions? itemsToShow.add(Pair.create((FunctionDescriptor) variant, resolutionFacade)); } else if (variant instanceof ClassDescriptor) { // todo: renamed classes? for (ConstructorDescriptor constructorDescriptor : ((ClassDescriptor) variant).getConstructors()) { itemsToShow.add(Pair.create(constructorDescriptor, resolutionFacade)); } } } context.setItemsToShow(ArrayUtil.toObjectArray(itemsToShow)); return argumentList; }
@Override public void updateUI( Pair<? extends FunctionDescriptor, ResolutionFacade> itemToShow, @NotNull ParameterInfoUIContext context) { // todo: when we will have ability to pass Array as vararg, implement such feature here too? if (context == null || context.getParameterOwner() == null || !context.getParameterOwner().isValid()) { context.setUIComponentEnabled(false); return; } PsiElement parameterOwner = context.getParameterOwner(); if (!(parameterOwner instanceof JetValueArgumentList)) { context.setUIComponentEnabled(false); return; } JetValueArgumentList argumentList = (JetValueArgumentList) parameterOwner; FunctionDescriptor functionDescriptor = itemToShow.first; ResolutionFacade resolutionFacade = itemToShow.second; List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters(); List<JetValueArgument> valueArguments = argumentList.getArguments(); int currentParameterIndex = context.getCurrentParameterIndex(); int boldStartOffset = -1; int boldEndOffset = -1; boolean isGrey = false; boolean isDeprecated = KotlinBuiltIns.isDeprecated(functionDescriptor); boolean[] usedIndexes = new boolean[valueParameters.size()]; Arrays.fill(usedIndexes, false); boolean namedMode = false; if (!isIndexValid(valueParameters, currentParameterIndex)) { isGrey = true; } StringBuilder builder = new StringBuilder(); PsiElement owner = context.getParameterOwner(); BindingContext bindingContext = resolutionFacade.analyze((JetElement) owner, BodyResolveMode.FULL); for (int i = 0; i < valueParameters.size(); ++i) { if (i != 0) { builder.append(", "); } boolean highlightParameter = i == currentParameterIndex || (!namedMode && i < currentParameterIndex && Iterables.getLast(valueParameters).getVarargElementType() != null); if (highlightParameter) { boldStartOffset = builder.length(); } if (!namedMode) { if (valueArguments.size() > i) { JetValueArgument argument = valueArguments.get(i); if (argument.isNamed()) { namedMode = true; } else { ValueParameterDescriptor param = valueParameters.get(i); builder.append(renderParameter(param, false)); if (i <= currentParameterIndex && !isArgumentTypeValid(bindingContext, argument, param)) { isGrey = true; } usedIndexes[i] = true; } } else { ValueParameterDescriptor param = valueParameters.get(i); builder.append(renderParameter(param, false)); } } if (namedMode) { boolean takeAnyArgument = true; if (valueArguments.size() > i) { JetValueArgument argument = valueArguments.get(i); if (argument.isNamed()) { for (int j = 0; j < valueParameters.size(); ++j) { JetSimpleNameExpression referenceExpression = argument.getArgumentName().getReferenceExpression(); ValueParameterDescriptor param = valueParameters.get(j); if (referenceExpression != null && !usedIndexes[j] && param.getName().equals(referenceExpression.getReferencedNameAsName())) { takeAnyArgument = false; usedIndexes[j] = true; builder.append(renderParameter(param, true)); if (i < currentParameterIndex && !isArgumentTypeValid(bindingContext, argument, param)) { isGrey = true; } break; } } } } if (takeAnyArgument) { if (i < currentParameterIndex) { isGrey = true; } for (int j = 0; j < valueParameters.size(); ++j) { ValueParameterDescriptor param = valueParameters.get(j); if (!usedIndexes[j]) { usedIndexes[j] = true; builder.append(renderParameter(param, true)); break; } } } } if (highlightParameter) { boldEndOffset = builder.length(); } } if (valueParameters.size() == 0) { builder.append(CodeInsightBundle.message("parameter.info.no.parameters")); } assert !builder.toString().isEmpty() : "A message about 'no parameters' or some parameters should be present: " + functionDescriptor; Color color = isResolvedToDescriptor(argumentList, functionDescriptor, bindingContext) ? GREEN_BACKGROUND : context.getDefaultParameterColor(); context.setupUIComponentPresentation( builder.toString(), boldStartOffset, boldEndOffset, isGrey, isDeprecated, false, color); }
private static JetValueArgumentList findCall(CreateParameterInfoContext context) { // todo: calls to this constructors, when we will have auxiliary constructors PsiFile file = context.getFile(); if (!(file instanceof JetFile)) return null; PsiElement element = file.findElementAt(context.getOffset()); while (element != null && !(element instanceof JetValueArgumentList)) { element = element.getParent(); } if (element == null) return null; JetValueArgumentList argumentList = (JetValueArgumentList) element; JetCallElement callExpression; if (element.getParent() instanceof JetCallElement) { callExpression = (JetCallElement) element.getParent(); } else { return null; } BindingContext bindingContext = AnalyzeSingleFileUtil.getContextForSingleFile((JetFile) file); JetExpression calleeExpression = callExpression.getCalleeExpression(); if (calleeExpression == null) return null; JetSimpleNameExpression refExpression = null; if (calleeExpression instanceof JetSimpleNameExpression) { refExpression = (JetSimpleNameExpression) calleeExpression; } else if (calleeExpression instanceof JetConstructorCalleeExpression) { JetConstructorCalleeExpression constructorCalleeExpression = (JetConstructorCalleeExpression) calleeExpression; if (constructorCalleeExpression.getConstructorReferenceExpression() instanceof JetSimpleNameExpression) { refExpression = (JetSimpleNameExpression) constructorCalleeExpression.getConstructorReferenceExpression(); } } if (refExpression != null) { JetScope scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, refExpression); DeclarationDescriptor placeDescriptor = null; if (scope != null) { placeDescriptor = scope.getContainingDeclaration(); } Collection<DeclarationDescriptor> variants = TipsManager.getReferenceVariants(refExpression, bindingContext); Name refName = refExpression.getReferencedNameAsName(); PsiReference[] references = refExpression.getReferences(); if (references.length == 0) return null; ArrayList<DeclarationDescriptor> itemsToShow = new ArrayList<DeclarationDescriptor>(); for (DeclarationDescriptor variant : variants) { if (variant instanceof FunctionDescriptor) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) variant; if (functionDescriptor.getName().equals(refName)) { // todo: renamed functions? if (placeDescriptor != null && !JetVisibilityChecker.isVisible(placeDescriptor, functionDescriptor)) continue; itemsToShow.add(functionDescriptor); } } else if (variant instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) variant; if (classDescriptor.getName().equals(refName)) { // todo: renamed classes? for (ConstructorDescriptor constructorDescriptor : classDescriptor.getConstructors()) { if (placeDescriptor != null && !JetVisibilityChecker.isVisible(placeDescriptor, constructorDescriptor)) continue; itemsToShow.add(constructorDescriptor); } } } } context.setItemsToShow(ArrayUtil.toObjectArray(itemsToShow)); return argumentList; } return null; }
@Override public void updateUI(Object descriptor, ParameterInfoUIContext context) { // todo: when we will have ability to pass Array as vararg, implement such feature here too? if (context == null || context.getParameterOwner() == null || !context.getParameterOwner().isValid()) { return; } PsiElement parameterOwner = context.getParameterOwner(); if (parameterOwner instanceof JetValueArgumentList) { JetValueArgumentList argumentList = (JetValueArgumentList) parameterOwner; if (descriptor instanceof FunctionDescriptor) { JetFile file = (JetFile) argumentList.getContainingFile(); BindingContext bindingContext = AnalyzeSingleFileUtil.getContextForSingleFile(file); FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; StringBuilder builder = new StringBuilder(); List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters(); List<JetValueArgument> valueArguments = argumentList.getArguments(); int currentParameterIndex = context.getCurrentParameterIndex(); int boldStartOffset = -1; int boldEndOffset = -1; boolean isGrey = false; boolean isDeprecated = false; // todo: add deprecation check Color color = context.getDefaultParameterColor(); PsiElement parent = argumentList.getParent(); if (parent instanceof JetCallElement) { JetCallElement callExpression = (JetCallElement) parent; JetExpression calleeExpression = callExpression.getCalleeExpression(); JetSimpleNameExpression refExpression = null; if (calleeExpression instanceof JetSimpleNameExpression) { refExpression = (JetSimpleNameExpression) calleeExpression; } else if (calleeExpression instanceof JetConstructorCalleeExpression) { JetConstructorCalleeExpression constructorCalleeExpression = (JetConstructorCalleeExpression) calleeExpression; if (constructorCalleeExpression.getConstructorReferenceExpression() instanceof JetSimpleNameExpression) { refExpression = (JetSimpleNameExpression) constructorCalleeExpression.getConstructorReferenceExpression(); } } if (refExpression != null) { DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, refExpression); if (declarationDescriptor != null) { if (declarationDescriptor == functionDescriptor) { color = GREEN_BACKGROUND; } } } } boolean[] usedIndexes = new boolean[valueParameters.size()]; boolean namedMode = false; Arrays.fill(usedIndexes, false); if ((currentParameterIndex >= valueParameters.size() && (valueParameters.size() > 0 || currentParameterIndex > 0)) && (valueParameters.size() == 0 || valueParameters.get(valueParameters.size() - 1).getVarargElementType() == null)) { isGrey = true; } if (valueParameters.size() == 0) builder.append(CodeInsightBundle.message("parameter.info.no.parameters")); for (int i = 0; i < valueParameters.size(); ++i) { if (i != 0) builder.append(", "); boolean highlightParameter = i == currentParameterIndex || (!namedMode && i < currentParameterIndex && valueParameters.get(valueParameters.size() - 1).getVarargElementType() != null); if (highlightParameter) boldStartOffset = builder.length(); if (!namedMode) { if (valueArguments.size() > i) { JetValueArgument argument = valueArguments.get(i); if (argument.isNamed()) { namedMode = true; } else { ValueParameterDescriptor param = valueParameters.get(i); builder.append(renderParameter(param, false, bindingContext)); if (i < currentParameterIndex) { if (argument.getArgumentExpression() != null) { // check type JetType paramType = getActualParameterType(param); JetType exprType = bindingContext.get( BindingContext.EXPRESSION_TYPE, argument.getArgumentExpression()); if (exprType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(exprType, paramType)) isGrey = true; } else isGrey = true; } usedIndexes[i] = true; } } else { ValueParameterDescriptor param = valueParameters.get(i); builder.append(renderParameter(param, false, bindingContext)); } } if (namedMode) { boolean takeAnyArgument = true; if (valueArguments.size() > i) { JetValueArgument argument = valueArguments.get(i); if (argument.isNamed()) { for (int j = 0; j < valueParameters.size(); ++j) { JetSimpleNameExpression referenceExpression = argument.getArgumentName().getReferenceExpression(); ValueParameterDescriptor param = valueParameters.get(j); if (referenceExpression != null && !usedIndexes[j] && param.getName().equals(referenceExpression.getReferencedNameAsName())) { takeAnyArgument = false; usedIndexes[j] = true; builder.append(renderParameter(param, true, bindingContext)); if (i < currentParameterIndex) { if (argument.getArgumentExpression() != null) { // check type JetType paramType = getActualParameterType(param); JetType exprType = bindingContext.get( BindingContext.EXPRESSION_TYPE, argument.getArgumentExpression()); if (exprType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(exprType, paramType)) isGrey = true; } else isGrey = true; } break; } } } } if (takeAnyArgument) { if (i < currentParameterIndex) isGrey = true; for (int j = 0; j < valueParameters.size(); ++j) { ValueParameterDescriptor param = valueParameters.get(j); if (!usedIndexes[j]) { usedIndexes[j] = true; builder.append(renderParameter(param, true, bindingContext)); break; } } } } if (highlightParameter) boldEndOffset = builder.length(); } if (builder.toString().isEmpty()) context.setUIComponentEnabled(false); else context.setupUIComponentPresentation( builder.toString(), boldStartOffset, boldEndOffset, isGrey, isDeprecated, false, color); } else context.setUIComponentEnabled(false); } }
@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; }
public static boolean isBackingFieldReference(@NotNull JetSimpleNameExpression expression) { return expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER; }
private static JetValueArgumentList findCall(CreateParameterInfoContext context) { // todo: calls to this constructors, when we will have auxiliary constructors PsiFile file = context.getFile(); if (!(file instanceof JetFile)) { return null; } JetValueArgumentList argumentList = PsiTreeUtil.getParentOfType( file.findElementAt(context.getOffset()), JetValueArgumentList.class); if (argumentList == null) { return null; } JetSimpleNameExpression callNameExpression = getCallSimpleNameExpression(argumentList); if (callNameExpression == null) { return null; } PsiReference[] references = callNameExpression.getReferences(); if (references.length == 0) { return null; } CancelableResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveResultForFile( (JetFile) callNameExpression.getContainingFile()); BindingContext bindingContext = resolveSession.resolveToElement(callNameExpression); JetScope scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, callNameExpression); DeclarationDescriptor placeDescriptor = null; if (scope != null) { placeDescriptor = scope.getContainingDeclaration(); } Collection<DeclarationDescriptor> variants = TipsManager.getReferenceVariants(callNameExpression, bindingContext); Name refName = callNameExpression.getReferencedNameAsName(); Collection<Pair<? extends DeclarationDescriptor, CancelableResolveSession>> itemsToShow = new ArrayList<Pair<? extends DeclarationDescriptor, CancelableResolveSession>>(); for (DeclarationDescriptor variant : variants) { if (variant instanceof FunctionDescriptor) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) variant; if (functionDescriptor.getName().equals(refName)) { // todo: renamed functions? if (placeDescriptor != null && !JetVisibilityChecker.isVisible(placeDescriptor, functionDescriptor)) { continue; } itemsToShow.add(Pair.create(functionDescriptor, resolveSession)); } } else if (variant instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) variant; if (classDescriptor.getName().equals(refName)) { // todo: renamed classes? for (ConstructorDescriptor constructorDescriptor : classDescriptor.getConstructors()) { if (placeDescriptor != null && !JetVisibilityChecker.isVisible(placeDescriptor, constructorDescriptor)) { continue; } itemsToShow.add(Pair.create(constructorDescriptor, resolveSession)); } } } } context.setItemsToShow(ArrayUtil.toObjectArray(itemsToShow)); return argumentList; }