@Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { if (!super.isAvailable(project, editor, file) || !(file instanceof JetFile)) { return false; } // When running single test 'isAvailable()' is invoked multiple times, so we need to clear // lists. overriddenNonOverridableMembers.clear(); containingDeclarationsNames.clear(); DeclarationDescriptor descriptor = ResolvePackage.resolveToDescriptor(element); if (!(descriptor instanceof CallableMemberDescriptor)) return false; for (CallableMemberDescriptor overriddenDescriptor : getAllDeclaredNonOverridableOverriddenDescriptors((CallableMemberDescriptor) descriptor)) { assert overriddenDescriptor.getKind() == DECLARATION : "Can only be applied to declarations."; PsiElement overriddenMember = descriptorToDeclaration(overriddenDescriptor); if (overriddenMember == null || !QuickFixUtil.canModifyElement(overriddenMember) || !(overriddenMember instanceof JetCallableDeclaration)) { return false; } String containingDeclarationName = overriddenDescriptor.getContainingDeclaration().getName().asString(); overriddenNonOverridableMembers.add((JetCallableDeclaration) overriddenMember); containingDeclarationsNames.add(containingDeclarationName); } return overriddenNonOverridableMembers.size() > 0; }
@Nullable public final FunctionDescriptor getCurrentFunctionDescriptor() { if (currentFunctionDescriptor == null) { PsiElement element = getDeclaration(); if (element instanceof JetFunction) { currentFunctionDescriptor = (FunctionDescriptor) ResolvePackage.resolveToDescriptor((JetFunction) element); } else if (element instanceof JetClass) { currentFunctionDescriptor = ((ClassDescriptor) ResolvePackage.resolveToDescriptor((JetClass) element)) .getUnsubstitutedPrimaryConstructor(); } else if (element instanceof PsiMethod) { currentFunctionDescriptor = ResolvePackage.getJavaMethodDescriptor((PsiMethod) element); } } return currentFunctionDescriptor; }
private static boolean checkIfHasExpectedType( @NotNull FunctionDescriptor functionDescriptor, boolean isInherited) { if (!(functionDescriptor instanceof AnonymousFunctionDescriptor && isInherited)) return false; JetFunctionLiteral functionLiteral = (JetFunctionLiteral) DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor); assert functionLiteral != null : "No declaration found for " + functionDescriptor; PsiElement parent = functionLiteral.getParent(); if (!(parent instanceof JetFunctionLiteralExpression)) return false; JetFunctionLiteralExpression expression = (JetFunctionLiteralExpression) parent; return ResolvePackage.analyze(expression, BodyResolveMode.PARTIAL) .get(BindingContext.EXPECTED_EXPRESSION_TYPE, expression) != null; }
private static List<FunctionDescriptor> generateFunctionsToAdd(JetNamedFunction functionElement) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) ResolvePackage.resolveToDescriptor(functionElement); DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); if (!(containingDeclaration instanceof ClassDescriptor)) return Collections.emptyList(); List<FunctionDescriptor> functions = Lists.newArrayList(); ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; // TODO: filter out impossible supertypes (for example when argument's type isn't visible in a // superclass). for (ClassDescriptor supertypeDescriptor : getSupertypes(classDescriptor)) { if (KotlinBuiltIns.isAnyOrNullableAny(supertypeDescriptor.getDefaultType())) continue; functions.add(generateFunctionSignatureForType(functionDescriptor, supertypeDescriptor)); } return functions; }
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; }