@NotNull @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { return new HeapPollutionVisitor() { @Override protected void registerProblem(PsiMethod method, PsiIdentifier nameIdentifier) { final LocalQuickFix quickFix; if (GenericsHighlightUtil.isSafeVarargsNoOverridingCondition(method, PsiUtil.getLanguageLevel(method))) { quickFix = new AnnotateAsSafeVarargsQuickFix(); } else { final PsiClass containingClass = method.getContainingClass(); LOG.assertTrue(containingClass != null); boolean canBeFinal = !method.hasModifierProperty(PsiModifier.ABSTRACT) && !containingClass.isInterface() && OverridingMethodsSearch.search(method).findFirst() == null; quickFix = canBeFinal ? new MakeFinalAndAnnotateQuickFix() : null; } holder.registerProblem(nameIdentifier, "Possible heap pollution from parameterized vararg type #loc", quickFix); } }; }
private static void makeMethodHierarchyVoid(Project project, @NotNull PsiMethod psiMethod) { replaceReturnStatements(psiMethod); for (final PsiMethod oMethod : OverridingMethodsSearch.search(psiMethod)) { replaceReturnStatements(oMethod); } final PsiParameter[] params = psiMethod.getParameterList().getParameters(); final ParameterInfoImpl[] infos = new ParameterInfoImpl[params.length]; for (int i = 0; i < params.length; i++) { PsiParameter param = params[i]; infos[i] = new ParameterInfoImpl(i, param.getName(), param.getType()); } final ChangeSignatureProcessor csp = new ChangeSignatureProcessor(project, psiMethod, false, null, psiMethod.getName(), PsiType.VOID, infos); csp.run(); }
private static String getOverriddenMethodTooltip(@NotNull PsiMethod method) { PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(5); OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(processor)); boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); if (processor.isOverflow()){ return isAbstract ? DaemonBundle.message("method.is.implemented.too.many") : DaemonBundle.message("method.is.overridden.too.many"); } PsiMethod[] overridings = processor.toArray(PsiMethod.EMPTY_ARRAY); if (overridings.length == 0) { final PsiClass aClass = method.getContainingClass(); if (aClass != null && FunctionalExpressionSearch.search(aClass).findFirst() != null) { return "Has functional implementations"; } return null; } Comparator<PsiMethod> comparator = new MethodCellRenderer(false).getComparator(); Arrays.sort(overridings, comparator); String start = isAbstract ? DaemonBundle.message("method.is.implemented.header") : DaemonBundle.message("method.is.overriden.header"); @NonNls String pattern = " <a href=\"#javaClass/{1}\">{1}</a>"; return composeText(overridings, start, pattern, IdeActions.ACTION_GOTO_IMPLEMENTATION); }
@NotNull private static PsiElement[] getParameterElementsToSearch(@NotNull PsiParameter parameter, @NotNull PsiMethod method) { PsiMethod[] overrides = OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY); for (int i = 0; i < overrides.length; i++) { final PsiElement navigationElement = overrides[i].getNavigationElement(); if (navigationElement instanceof PsiMethod) { overrides[i] = (PsiMethod)navigationElement; } } List<PsiElement> elementsToSearch = new ArrayList<PsiElement>(overrides.length + 1); elementsToSearch.add(parameter); int idx = method.getParameterList().getParameterIndex(parameter); for (PsiMethod override : overrides) { final PsiParameter[] parameters = override.getParameterList().getParameters(); if (idx < parameters.length) { elementsToSearch.add(parameters[idx]); } } return PsiUtilCore.toPsiElementArray(elementsToSearch); }
@Override @NotNull public PsiElement[] getPrimaryElements() { final PsiElement element = getPsiElement(); if (element instanceof PsiParameter) { final PsiParameter parameter = (PsiParameter)element; final PsiElement scope = parameter.getDeclarationScope(); if (scope instanceof PsiMethod) { final PsiMethod method = (PsiMethod)scope; if (PsiUtil.canBeOverriden(method)) { final PsiClass aClass = method.getContainingClass(); LOG.assertTrue(aClass != null); //Otherwise can not be overriden boolean hasOverridden = OverridingMethodsSearch.search(method).findFirst() != null; if (hasOverridden && askWhetherShouldSearchForParameterInOverridingMethods(element, parameter)) { return getParameterElementsToSearch(parameter, method); } } } } return myElementsToSearch.length == 0 ? new PsiElement[]{element} : myElementsToSearch; }
public void findUsages(@NotNull List<FixableUsageInfo> usages) { if (myUseExistingClass && existingClass != null) { myExistingClassCompatibleConstructor = existingClassIsCompatible(existingClass, parameters); } findUsagesForMethod(method, usages, true); if (myUseExistingClass && existingClass != null && !(paramsNeedingGetters.isEmpty() && paramsNeedingSetters.isEmpty())) { usages.add(new AppendAccessorsUsageInfo(existingClass, myGenerateAccessors, paramsNeedingGetters, paramsNeedingSetters, parameters)); } final PsiMethod[] overridingMethods = OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY); for (PsiMethod siblingMethod : overridingMethods) { findUsagesForMethod(siblingMethod, usages, false); } if (myNewVisibility != null) { usages.add(new BeanClassVisibilityUsageInfo(existingClass, usages.toArray(new UsageInfo[usages.size()]), myNewVisibility, myExistingClassCompatibleConstructor)); } }
private static void addOverriddenAndImplemented(PsiMethod methodPrototype, final String newName, final Map<PsiElement, String> allRenames) { allRenames.put(methodPrototype, newName); PsiMethod[] methods = methodPrototype.findDeepestSuperMethods(); if (methods.length == 0) { methods = new PsiMethod[] {methodPrototype}; } for (PsiMethod method : methods) { OverridingMethodsSearch.search(method).forEach(new Processor<PsiMethod>() { public boolean process(PsiMethod psiMethod) { RenameProcessor.assertNonCompileElement(psiMethod); allRenames.put(psiMethod, newName); return true; } }); allRenames.put(method, newName); } }
public AutomaticParametersRenamer(PsiParameter param, String newParamName) { final PsiElement scope = param.getDeclarationScope(); if (scope instanceof PsiMethod) { final PsiMethod method = (PsiMethod)scope; final int parameterIndex = method.getParameterList().getParameterIndex(param); if (parameterIndex < 0) return; for (PsiMethod overrider : OverridingMethodsSearch.search(method)) { final PsiParameter[] parameters = overrider.getParameterList().getParameters(); if (parameterIndex >= parameters.length) continue; final PsiParameter inheritedParam = parameters[parameterIndex]; if (!Comparing.strEqual(inheritedParam.getName(), newParamName)) { myElements.add(inheritedParam); suggestAllNames(inheritedParam.getName(), newParamName); } } } }
@Override public void prepareRenaming(PsiElement element, final String newName, final Map<PsiElement, String> allRenames, SearchScope scope) { final PsiMethod method = (PsiMethod) element; OverridingMethodsSearch.search(method, scope, true).forEach(new Processor<PsiMethod>() { public boolean process(PsiMethod overrider) { if (overrider instanceof PsiMirrorElement) { final PsiElement prototype = ((PsiMirrorElement)overrider).getPrototype(); if (prototype instanceof PsiMethod) { overrider = (PsiMethod)prototype; } } if (overrider instanceof SyntheticElement) return true; final String overriderName = overrider.getName(); final String baseName = method.getName(); final String newOverriderName = RefactoringUtil.suggestNewOverriderName(overriderName, baseName, newName); if (newOverriderName != null) { RenameProcessor.assertNonCompileElement(overrider); allRenames.put(overrider, newOverriderName); } return true; } }); }
public static Set<PsiMethod> calculateSiblingMethods(PsiMethod method) { final Set<PsiMethod> siblingMethods = new HashSet<PsiMethod>(); final Stack<PsiMethod> pendingMethods = new Stack<PsiMethod>(); pendingMethods.add(method); while(!pendingMethods.isEmpty()) { final PsiMethod methodToAnalyze = pendingMethods.pop(); siblingMethods.add(methodToAnalyze); final Iterable<PsiMethod> overridingMethods = OverridingMethodsSearch.search(methodToAnalyze, false); for (PsiMethod overridingMethod : overridingMethods) { if (!siblingMethods.contains(overridingMethod) && !pendingMethods.contains(overridingMethod)) { pendingMethods.add(overridingMethod); } } final PsiMethod[] superMethods = methodToAnalyze.findSuperMethods(); for (PsiMethod superMethod : superMethods) { if (!siblingMethods.contains(superMethod) && !pendingMethods.contains(superMethod)) { pendingMethods.add(superMethod); } } } return siblingMethods; }
@NotNull protected UsageInfo[] findUsages() { ArrayList<UsageInfo> result = new ArrayList<UsageInfo>(); ContainerUtil.addAll(result, MakeStaticUtil.findClassRefsInMember(myMember, true)); if (mySettings.isReplaceUsages()) { findExternalUsages(result); } if (myMember instanceof PsiMethod) { final PsiMethod[] overridingMethods = OverridingMethodsSearch.search((PsiMethod)myMember, myMember.getUseScope(), false).toArray(PsiMethod.EMPTY_ARRAY); for (PsiMethod overridingMethod : overridingMethods) { if (overridingMethod != myMember) { result.add(new OverridingMethodUsageInfo(overridingMethod)); } } } return result.toArray(new UsageInfo[result.size()]); }
@Nullable @Override public String fun(PsiElement element) { PsiElement parent = element.getParent(); if (!(parent instanceof GrField)) return null; final List<GrAccessorMethod> accessors = GroovyPropertyUtils.getFieldAccessors((GrField)parent); PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(5); for (GrAccessorMethod method : accessors) { OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(processor)); } if (processor.isOverflow()) { return DaemonBundle.message("method.is.overridden.too.many"); } PsiMethod[] overridings = processor.toArray(new PsiMethod[processor.getCollection().size()]); if (overridings.length == 0) return null; Comparator<PsiMethod> comparator = new MethodCellRenderer(false).getComparator(); Arrays.sort(overridings, comparator); String start = DaemonBundle.message("method.is.overriden.header"); @NonNls String pattern = " {1}"; return GutterIconTooltipHelper.composeText(overridings, start, pattern); }
@Override public void run(@NotNull final ProgressIndicator indicator) { super.run(indicator); for (PsiMethod method : PsiImplUtil.getMethodOrReflectedMethods(myMethod)) { OverridingMethodsSearch.search(method, true).forEach( new CommonProcessors.CollectProcessor<PsiMethod>() { @Override public boolean process(PsiMethod psiMethod) { if (!updateComponent(com.intellij.psi.impl.PsiImplUtil.handleMirror(psiMethod), myRenderer.getComparator())) { indicator.cancel(); } indicator.checkCanceled(); return true; } }); } }
protected boolean isPublic(PsiModifierListOwner element) { if (element.hasModifierProperty(PsiModifier.PUBLIC)){ return true; } if (element.hasModifierProperty(PsiModifier.PRIVATE)){ return false; } if (element instanceof PsiMethod){ Iterator<PsiMethod> i = OverridingMethodsSearch.search((PsiMethod)element).iterator(); while (i.hasNext()){ PsiMethod method = i.next(); if (method.hasModifierProperty(PsiModifier.PUBLIC)){ return true; } } } return false; }
@NotNull @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { return new HeapPollutionVisitor() { @Override protected void registerProblem(PsiMethod method, PsiIdentifier nameIdentifier) { final LocalQuickFix quickFix; if (method.hasModifierProperty(PsiModifier.FINAL) || method.hasModifierProperty(PsiModifier.STATIC) || method.isConstructor()) { quickFix = new AnnotateAsSafeVarargsQuickFix(); } else { final PsiClass containingClass = method.getContainingClass(); LOG.assertTrue(containingClass != null); boolean canBeFinal = !method.hasModifierProperty(PsiModifier.ABSTRACT) && !containingClass.isInterface() && OverridingMethodsSearch.search(method).findFirst() == null; quickFix = canBeFinal ? new MakeFinalAndAnnotateQuickFix() : null; } holder.registerProblem(nameIdentifier, "Possible heap pollution from parameterized vararg type #loc", quickFix); } }; }
public static String getOverriddenMethodTooltip(PsiMethod method) { PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(5); OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(processor)); boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); if (processor.isOverflow()){ return isAbstract ? DaemonBundle.message("method.is.implemented.too.many") : DaemonBundle.message("method.is.overridden.too.many"); } PsiMethod[] overridings = processor.toArray(new PsiMethod[processor.getCollection().size()]); if (overridings.length == 0) return null; Comparator<PsiMethod> comparator = new MethodCellRenderer(false).getComparator(); Arrays.sort(overridings, comparator); String start = isAbstract ? DaemonBundle.message("method.is.implemented.header") : DaemonBundle.message("method.is.overriden.header"); @NonNls String pattern = " {1}"; return GutterIconTooltipHelper.composeText(overridings, start, pattern); }
public static void navigateToOverriddenMethod(MouseEvent e, final PsiMethod method) { if (DumbService.isDumb(method.getProject())) { DumbService.getInstance(method.getProject()).showDumbModeNotification( "Navigation to overriding classes is not possible during index update"); return; } final PsiElementProcessor.CollectElementsWithLimit<PsiMethod> collectProcessor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(2, new THashSet<PsiMethod>()); if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { @Override public void run() { OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(collectProcessor)); } }, SEARCHING_FOR_OVERRIDING_METHODS, true, method.getProject(), (JComponent)e.getComponent())) { return; } PsiMethod[] overridings = collectProcessor.toArray(PsiMethod.EMPTY_ARRAY); if (overridings.length == 0) return; boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(overridings); MethodCellRenderer renderer = new MethodCellRenderer(showMethodNames); Arrays.sort(overridings, renderer.getComparator()); final OverridingMethodsUpdater methodsUpdater = new OverridingMethodsUpdater(method, renderer); PsiElementListNavigator.openTargets(e, overridings, methodsUpdater.getCaption(overridings.length), "Overriding methods of " + method.getName(), renderer, methodsUpdater); }
@NotNull private static PsiElement[] getParameterElementsToSearch(@NotNull PsiParameter parameter) { final PsiMethod method = (PsiMethod)parameter.getDeclarationScope(); PsiMethod[] overrides = OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY); for (int i = 0; i < overrides.length; i++) { overrides[i] = (PsiMethod)overrides[i].getNavigationElement(); } List<PsiElement> elementsToSearch = new ArrayList<PsiElement>(overrides.length + 1); elementsToSearch.add(parameter); int idx = method.getParameterList().getParameterIndex(parameter); for (PsiMethod override : overrides) { final PsiParameter[] parameters = override.getParameterList().getParameters(); if (idx < parameters.length) { elementsToSearch.add(parameters[idx]); } } return elementsToSearch.toArray(new PsiElement[elementsToSearch.size()]); }
@Override @NotNull public PsiElement[] getPrimaryElements() { final PsiElement element = getPsiElement(); if (element instanceof PsiParameter) { final PsiParameter parameter = (PsiParameter)element; final PsiElement scope = parameter.getDeclarationScope(); if (scope instanceof PsiMethod) { final PsiMethod method = (PsiMethod)scope; if (PsiUtil.canBeOverriden(method)) { final PsiClass aClass = method.getContainingClass(); LOG.assertTrue(aClass != null); //Otherwise can not be overriden boolean hasOverridden = OverridingMethodsSearch.search(method).findFirst() != null; if (hasOverridden && askWhetherShouldSearchForParameterInOverridingMethods(element, parameter)) { return getParameterElementsToSearch(parameter); } } } } return myElementsToSearch.length == 0 ? new PsiElement[]{element} : myElementsToSearch; }
@NotNull private static PsiElement[] getParameterElementsToSearch(@NotNull PsiParameter parameter, @NotNull PsiMethod method) { PsiMethod[] overrides = OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY); for(int i = 0; i < overrides.length; i++) { final PsiElement navigationElement = overrides[i].getNavigationElement(); if(navigationElement instanceof PsiMethod) { overrides[i] = (PsiMethod) navigationElement; } } List<PsiElement> elementsToSearch = new ArrayList<PsiElement>(overrides.length + 1); elementsToSearch.add(parameter); int idx = method.getParameterList().getParameterIndex(parameter); for(PsiMethod override : overrides) { final PsiParameter[] parameters = override.getParameterList().getParameters(); if(idx < parameters.length) { elementsToSearch.add(parameters[idx]); } } return PsiUtilCore.toPsiElementArray(elementsToSearch); }
@Override public boolean execute(@NotNull final OverridingMethodsSearch.SearchParameters p, @NotNull final Processor<PsiMethod> consumer) { final PsiMethod method = p.getMethod(); final SearchScope scope = p.getScope(); final PsiClass parentClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() { @Nullable @Override public PsiClass compute() { return method.getContainingClass(); } }); assert parentClass != null; Processor<PsiClass> inheritorsProcessor = new Processor<PsiClass>() { @Override public boolean process(final PsiClass inheritor) { PsiMethod found = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod>() { @Override @Nullable public PsiMethod compute() { return findOverridingMethod(inheritor, parentClass, method); } }); return found == null || consumer.process(found) && p.isCheckDeep(); } }; return ClassInheritorsSearch.search(parentClass, scope, true).forEach(inheritorsProcessor); }
@Override public void run(@NotNull final ProgressIndicator indicator) { super.run(indicator); OverridingMethodsSearch.search(myMethod, true).forEach( new CommonProcessors.CollectProcessor<PsiMethod>() { @Override public boolean process(PsiMethod psiMethod) { if (!updateComponent(psiMethod, myRenderer.getComparator())) { indicator.cancel(); } indicator.checkCanceled(); return super.process(psiMethod); } }); final PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() { @Override public PsiClass compute() { return myMethod.getContainingClass(); } }); FunctionalExpressionSearch.search(psiClass).forEach(new CommonProcessors.CollectProcessor<PsiFunctionalExpression>() { @Override public boolean process(final PsiFunctionalExpression expr) { if (!updateComponent(expr, myRenderer.getComparator())) { indicator.cancel(); } indicator.checkCanceled(); return super.process(expr); } }); }
@Override public void findUsages(@NotNull List<FixableUsageInfo> usages) { findUsagesForMethod(myMethod, usages); for (PsiMethod overridingMethod : OverridingMethodsSearch.search(myMethod)) { findUsagesForMethod(overridingMethod, usages); } }