@Nullable private static PsiMethod findOverridingMethod(PsiClass inheritor, @NotNull PsiClass parentClass, PsiMethod method) { String name = method.getName(); if (inheritor.findMethodsByName(name, false).length > 0) { PsiMethod found = MethodSignatureUtil.findMethodBySuperSignature(inheritor, getSuperSignature(inheritor, parentClass, method), false); if (found != null && isAcceptable(found, method)) { return found; } } if (parentClass.isInterface() && !inheritor.isInterface()) { //check for sibling implementation final PsiClass superClass = inheritor.getSuperClass(); if (superClass != null && !superClass.isInheritor(parentClass, true) && superClass.findMethodsByName(name, true).length > 0) { MethodSignature signature = getSuperSignature(inheritor, parentClass, method); PsiMethod derived = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(inheritor, superClass, signature, true); if (derived != null && isAcceptable(derived, method)) { return derived; } } } return null; }
@Override public boolean execute(@NotNull final SuperMethodsSearch.SearchParameters queryParameters, @NotNull final Processor<MethodSignatureBackedByPsiMethod> consumer) { final PsiClass parentClass = queryParameters.getPsiClass(); final PsiMethod method = queryParameters.getMethod(); return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() { @Override public Boolean compute() { HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature(); final boolean checkBases = queryParameters.isCheckBases(); final boolean allowStaticMethod = queryParameters.isAllowStaticMethod(); final List<HierarchicalMethodSignature> supers = signature.getSuperSignatures(); for (HierarchicalMethodSignature superSignature : supers) { if (MethodSignatureUtil.isSubsignature(superSignature, signature)) { if (!addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer)) return false; } } return true; } }); }
private static boolean addSuperMethods(final HierarchicalMethodSignature signature, final PsiMethod method, final PsiClass parentClass, final boolean allowStaticMethod, final boolean checkBases, final Processor<MethodSignatureBackedByPsiMethod> consumer) { PsiMethod signatureMethod = signature.getMethod(); PsiClass hisClass = signatureMethod.getContainingClass(); if (parentClass == null || InheritanceUtil.isInheritorOrSelf(parentClass, hisClass, true)) { if (isAcceptable(signatureMethod, method, allowStaticMethod)) { if (parentClass != null && !parentClass.equals(hisClass) && !checkBases) { return true; } LOG.assertTrue(signatureMethod != method, method); // method != method.getsuper() return consumer.process(signature); //no need to check super classes } } for (HierarchicalMethodSignature superSignature : signature.getSuperSignatures()) { if (MethodSignatureUtil.isSubsignature(superSignature, signature)) { addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer); } } return true; }
@Override public boolean isCallToSuperMethod(PsiExpression expression, PsiMethod method) { if (expression instanceof PsiMethodCallExpression) { PsiMethodCallExpression methodCall = (PsiMethodCallExpression)expression; if (methodCall.getMethodExpression().getQualifierExpression() instanceof PsiSuperExpression) { PsiMethod superMethod = (PsiMethod)methodCall.getMethodExpression().resolve(); if (superMethod == null || !MethodSignatureUtil.areSignaturesEqual(method, superMethod)) return false; PsiExpression[] args = methodCall.getArgumentList().getExpressions(); PsiParameter[] parms = method.getParameterList().getParameters(); for (int i = 0; i < args.length; i++) { PsiExpression arg = args[i]; if (!(arg instanceof PsiReferenceExpression)) return false; if (!parms[i].equals(((PsiReferenceExpression)arg).resolve())) return false; } return true; } } return false; }
private PsiMethod createHashCode() throws IncorrectOperationException { @NonNls StringBuilder buffer = new StringBuilder(); final HashMap<String, Object> contextMap = new HashMap<String, Object>(); contextMap.put(SUPER_HAS_HASH_CODE, mySuperHasHashCode); final String methodText = GenerationUtil .velocityGenerateCode(myClass, Arrays.asList(myHashCodeFields), myNonNullSet, new HashMap<String, String>(), contextMap, EqualsHashCodeTemplatesManager.getInstance().getDefaultHashcodeTemplate().getTemplate(), 0, false, myUseAccessors); buffer.append(methodText); PsiMethod hashCode; try { hashCode = myFactory.createMethodFromText(buffer.toString(), null); } catch (IncorrectOperationException e) { return null; } final PsiMethod superHashCode = MethodSignatureUtil.findMethodBySignature(myClass, getHashCodeSignature(), true); if (superHashCode != null) { OverrideImplementUtil.annotateOnOverrideImplement(hashCode, myClass, superHashCode); } hashCode = (PsiMethod)myJavaCodeStyleManager.shortenClassReferences(hashCode); return (PsiMethod)myCodeStyleManager.reformat(hashCode); }
private boolean leaveOverrideAnnotation(PsiSubstitutor substitutor, PsiMethod method) { final PsiMethod methodBySignature = MethodSignatureUtil.findMethodBySignature(myClass, method.getSignature(substitutor), false); if (methodBySignature == null) return false; final PsiMethod[] superMethods = methodBySignature.findDeepestSuperMethods(); if (superMethods.length == 0) return false; final boolean is15 = !PsiUtil.isLanguageLevel6OrHigher(methodBySignature); if (is15) { for (PsiMethod psiMethod : superMethods) { final PsiClass aClass = psiMethod.getContainingClass(); if (aClass != null && aClass.isInterface()) { return false; } } } return true; }
private static void findSubmemberHidesMemberCollisions(final PsiMethod method, final String newName, final List<UsageInfo> result) { final PsiClass containingClass = method.getContainingClass(); if (containingClass == null) return; if (method.hasModifierProperty(PsiModifier.PRIVATE)) return; Collection<PsiClass> inheritors = ClassInheritorsSearch.search(containingClass, true).findAll(); MethodSignature oldSignature = method.getSignature(PsiSubstitutor.EMPTY); MethodSignature newSignature = MethodSignatureUtil.createMethodSignature(newName, oldSignature.getParameterTypes(), oldSignature.getTypeParameters(), oldSignature.getSubstitutor(), method.isConstructor()); for (PsiClass inheritor : inheritors) { PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(containingClass, inheritor, PsiSubstitutor.EMPTY); final PsiMethod[] methodsByName = inheritor.findMethodsByName(newName, false); for (PsiMethod conflictingMethod : methodsByName) { if (newSignature.equals(conflictingMethod.getSignature(superSubstitutor))) { result.add(new SubmemberHidesMemberUsageInfo(conflictingMethod, method)); break; } } } }
@Override public boolean isMemberEnabled(MemberInfo member) { final PsiClass currentSuperClass = getSuperClass(); if(currentSuperClass == null) return true; if (myMemberInfoStorage.getDuplicatedMemberInfos(currentSuperClass).contains(member)) return false; if (myMemberInfoStorage.getExtending(currentSuperClass).contains(member.getMember())) return false; final boolean isInterface = currentSuperClass.isInterface(); if (!isInterface) return true; PsiElement element = member.getMember(); if (element instanceof PsiClass && ((PsiClass) element).isInterface()) return true; if (element instanceof PsiField) { return ((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); } if (element instanceof PsiMethod) { final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(currentSuperClass, myClass, PsiSubstitutor.EMPTY); final MethodSignature signature = ((PsiMethod) element).getSignature(superSubstitutor); final PsiMethod superClassMethod = MethodSignatureUtil.findMethodBySignature(currentSuperClass, signature, false); if (superClassMethod != null && !PsiUtil.isLanguageLevel8OrHigher(currentSuperClass)) return false; return !((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC) || PsiUtil.isLanguageLevel8OrHigher(currentSuperClass); } return true; }
private boolean shouldFixSuper(PsiMethod method) { for (PsiMember element : myMembersAfterMove) { if (element instanceof PsiMethod) { PsiMethod member = (PsiMethod)element; // if there is such member among moved members, super qualifier // should not be removed final PsiManager manager = method.getManager(); if (manager.areElementsEquivalent(member.getContainingClass(), method.getContainingClass()) && MethodSignatureUtil.areSignaturesEqual(member, method)) { return false; } } } final PsiMethod methodFromSuper = myTargetSuperClass.findMethodBySignature(method, false); return methodFromSuper == null; }
@Override public void visitMethod(@NotNull PsiMethod method) { if (!method.isVarArgs()) { return; } final PsiClass aClass = method.getContainingClass(); if (aClass == null) { return; } final String methodName = method.getName(); final PsiMethod[] sameNameMethods = aClass.findMethodsByName(methodName, true); for (PsiMethod sameNameMethod : sameNameMethods) { if (!MethodSignatureUtil.areSignaturesEqual(sameNameMethod, method)) { registerMethodError(method, method); return; } } }
public boolean isSuperMethod(PsiMethod superMethodCandidate, PsiMethod derivedMethod) { final PsiClass superClassCandidate = superMethodCandidate.getContainingClass(); final PsiClass derivedClass = derivedMethod.getContainingClass(); if (derivedClass == null || superClassCandidate == null) { return false; } if (!derivedClass.isInheritor(superClassCandidate, false)) { return false; } final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor( superClassCandidate, derivedClass, PsiSubstitutor.EMPTY); final MethodSignature superSignature = superMethodCandidate.getSignature(superSubstitutor); final MethodSignature derivedSignature = derivedMethod.getSignature(PsiSubstitutor.EMPTY); return MethodSignatureUtil.isSubsignature(superSignature, derivedSignature); }
@Override public void collectMethods(@NotNull final GrTypeDefinition clazz, @NotNull Collection<PsiMethod> collector) { Set<PsiClass> processed = new HashSet<PsiClass>(); if (!checkForDelegate(clazz)) return; Map<MethodSignature, PsiMethod> signatures = new THashMap<MethodSignature, PsiMethod>(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY); initializeSignatures(clazz, PsiSubstitutor.EMPTY, signatures, processed); List<PsiMethod> methods = new ArrayList<PsiMethod>(); process(clazz, PsiSubstitutor.EMPTY, true, new HashSet<PsiClass>(), processed, methods, clazz, false); final Set<PsiMethod> result = new LinkedHashSet<PsiMethod>(); for (PsiMethod method : methods) { addMethodChecked(signatures, method, PsiSubstitutor.EMPTY, result); } collector.addAll(result); }
@Override public boolean isMemberEnabled(GrMemberInfo member) { PsiClass currentSuperClass = getSuperClass(); if(currentSuperClass == null) return true; if (myMemberInfoStorage.getDuplicatedMemberInfos(currentSuperClass).contains(member)) return false; if (myMemberInfoStorage.getExtending(currentSuperClass).contains(member.getMember())) return false; if (!currentSuperClass.isInterface()) return true; PsiElement element = member.getMember(); if (element instanceof PsiClass && ((PsiClass) element).isInterface()) return true; if (element instanceof PsiField) { return ((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); } if (element instanceof PsiMethod) { if (currentSuperClass.isInterface()) { final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(currentSuperClass, myClass, PsiSubstitutor.EMPTY); final MethodSignature signature = ((PsiMethod)element).getSignature(superSubstitutor); final PsiMethod superClassMethod = MethodSignatureUtil.findMethodBySignature(currentSuperClass, signature, false); if (superClassMethod != null) return false; } return !((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); } return true; }
@Override public boolean execute(@NotNull final SuperMethodsSearch.SearchParameters queryParameters, @NotNull final Processor<MethodSignatureBackedByPsiMethod> consumer) { final PsiClass parentClass = queryParameters.getPsiClass(); final PsiMethod method = queryParameters.getMethod(); HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature(); final boolean checkBases = queryParameters.isCheckBases(); final boolean allowStaticMethod = queryParameters.isAllowStaticMethod(); final List<HierarchicalMethodSignature> supers = signature.getSuperSignatures(); for (HierarchicalMethodSignature superSignature : supers) { if (MethodSignatureUtil.isSubsignature(superSignature, signature)) { if (!addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer)) return false; } } return true; }
@Nullable private static PsiMethod findOverridingMethod(PsiClass inheritor, @NotNull PsiClass parentClass, PsiMethod method) { PsiSubstitutor substitutor = inheritor.isInheritor(parentClass, true) ? TypeConversionUtil.getSuperClassSubstitutor(parentClass, inheritor, PsiSubstitutor.EMPTY) : PsiSubstitutor.EMPTY; MethodSignature signature = method.getSignature(substitutor); PsiMethod found = MethodSignatureUtil.findMethodBySuperSignature(inheritor, signature, false); if (found != null && isAcceptable(found, method)) { return found; } if (parentClass.isInterface() && !inheritor.isInterface()) { //check for sibling implementation final PsiClass superClass = inheritor.getSuperClass(); if (superClass != null && !superClass.isInheritor(parentClass, true)) { PsiMethod derived = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(inheritor, superClass, signature, true); if (derived != null && isAcceptable(derived, method)) { return derived; } } } return null; }
public boolean isMemberEnabled(MemberInfo member) { PsiClass currentSuperClass = getSuperClass(); if(currentSuperClass == null) return true; if (myMemberInfoStorage.getDuplicatedMemberInfos(currentSuperClass).contains(member)) return false; if (myMemberInfoStorage.getExtending(currentSuperClass).contains(member.getMember())) return false; if (!currentSuperClass.isInterface()) return true; PsiElement element = member.getMember(); if (element instanceof PsiClass && ((PsiClass) element).isInterface()) return true; if (element instanceof PsiField) { return ((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); } if (element instanceof PsiMethod) { if (currentSuperClass.isInterface()) { final PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(currentSuperClass, myClass, PsiSubstitutor.EMPTY); final MethodSignature signature = ((PsiMethod) element).getSignature(superSubstitutor); final PsiMethod superClassMethod = MethodSignatureUtil.findMethodBySignature(currentSuperClass, signature, false); if (superClassMethod != null) return false; } return !((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); } return true; }
@Override public void collectMethods(@NotNull final GrTypeDefinition clazz, @NotNull Collection<PsiMethod> collector) { Set<PsiClass> processed = new HashSet<PsiClass>(); if (!checkForDelegate(clazz)) return; Map<MethodSignature, PsiMethod> signatures = new THashMap<MethodSignature, PsiMethod>(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY); initializeSignatures(clazz, PsiSubstitutor.EMPTY, signatures, processed); List<PsiMethod> methods = new ArrayList<PsiMethod>(); process(clazz, PsiSubstitutor.EMPTY, true, new HashSet<PsiClass>(), processed, methods, clazz); final Set<PsiMethod> result = new LinkedHashSet<PsiMethod>(); for (PsiMethod method : methods) { addMethodChecked(signatures, method, PsiSubstitutor.EMPTY, result); } collector.addAll(result); }
@NotNull private static PsiMethod[] findSuperMethodsInternal(PsiMethod method, PsiClass parentClass) { if (null == parentClass || null == method) return PsiMethod.EMPTY_ARRAY; List<PsiMethod> sooperMethods = new ArrayList<PsiMethod>(); LinkedList<PsiClass> soopers = new LinkedList<PsiClass>(Arrays.asList(parentClass.getSupers())); while (!soopers.isEmpty()) { PsiClass sooper = soopers.pollFirst(); // Get the super-method on the closest superclass that contains the method. PsiMethod sooperMethod = MethodSignatureUtil.findMethodBySignature(sooper, method, true); if (null != sooperMethod) { sooperMethods.add(sooperMethod); soopers.addAll(Arrays.asList(sooperMethod.getContainingClass().getSupers())); } } return sooperMethods.toArray(PsiMethod.EMPTY_ARRAY); }
@Override public boolean isMemberEnabled(MemberInfo member) { final PsiClass currentSuperClass = getSuperClass(); if(currentSuperClass == null) return true; if (myMemberInfoStorage.getDuplicatedMemberInfos(currentSuperClass).contains(member)) return false; if (myMemberInfoStorage.getExtending(currentSuperClass).contains(member.getMember())) return false; final boolean isInterface = currentSuperClass.isInterface(); if (!isInterface) return true; PsiElement element = member.getMember(); if (element instanceof PsiClass && ((PsiClass) element).isInterface()) return true; if (element instanceof PsiField) { return ((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC); } if (element instanceof PsiMethod) { final PsiSubstitutor superSubstitutor = TypeConversionUtil .getSuperClassSubstitutor(currentSuperClass, myClass, PsiSubstitutor.EMPTY); final MethodSignature signature = ((PsiMethod) element).getSignature(superSubstitutor); final PsiMethod superClassMethod = MethodSignatureUtil.findMethodBySignature(currentSuperClass, signature, false); if (superClassMethod != null && !PsiUtil.isLanguageLevel8OrHigher(currentSuperClass)) return false; return !((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC) || PsiUtil.isLanguageLevel8OrHigher(currentSuperClass); } return true; }
@Nullable private PsiMethod calcSourceMirrorMethod() { PsiClass sourceClassMirror = ((ClsClassImpl) getParent()).getSourceMirrorClass(); if(sourceClassMirror == null) { return null; } for(PsiMethod sourceMethod : sourceClassMirror.findMethodsByName(getName(), false)) { if(MethodSignatureUtil.areParametersErasureEqual(this, sourceMethod)) { return sourceMethod; } } return null; }
private static boolean isAppMain(PsiMethod psiMethod, RefMethod refMethod) { if(!refMethod.isStatic()) { return false; } if(!PsiType.VOID.equals(psiMethod.getReturnType())) { return false; } PsiMethod appMainPattern = ((RefMethodImpl) refMethod).getRefJavaManager().getAppMainPattern(); if(MethodSignatureUtil.areSignaturesEqual(psiMethod, appMainPattern)) { return true; } PsiMethod appPremainPattern = ((RefMethodImpl) refMethod).getRefJavaManager().getAppPremainPattern(); return MethodSignatureUtil.areSignaturesEqual(psiMethod, appPremainPattern); }
@Override public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) { if(mySuperCallFound) { return; } final PsiExpression qualifier = expression.getQualifierExpression(); if(qualifier instanceof PsiSuperExpression) { final PsiElement target = expression.resolve(); if(target instanceof PsiMethod) { if(MethodSignatureUtil.isSuperMethod((PsiMethod) target, myMethod)) { mySuperCallFound = true; return; } } } super.visitMethodReferenceExpression(expression); }
@Override public boolean equals(Object obj) { if(obj == this) { return true; } if(!(obj instanceof CompletionElement)) { return false; } Object thatObj = ((CompletionElement) obj).myEqualityObject; if(myEqualityObject instanceof MethodSignature) { return thatObj instanceof MethodSignature && MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY.equals((MethodSignature) myEqualityObject, (MethodSignature) thatObj); } return Comparing.equal(myEqualityObject, thatObj); }
private boolean shouldFixSuper(PsiMethod method) { for(PsiMember element : myMembersAfterMove) { if(element instanceof PsiMethod) { PsiMethod member = (PsiMethod) element; // if there is such member among moved members, super qualifier // should not be removed final PsiManager manager = method.getManager(); if(manager.areElementsEquivalent(member.getContainingClass(), method.getContainingClass()) && MethodSignatureUtil.areSignaturesEqual(member, method)) { return false; } } } final PsiMethod methodFromSuper = myTargetSuperClass.findMethodBySignature(method, false); return methodFromSuper == null; }
protected boolean processInexactReference(PsiReference ref, PsiElement refElement, PsiMethod method, Processor<PsiReference> consumer) { if (refElement instanceof PsiMethod) { PsiMethod refMethod = (PsiMethod)refElement; PsiClass refMethodClass = refMethod.getContainingClass(); if (refMethodClass == null) return true; if (!refMethod.hasModifierProperty(PsiModifier.STATIC)) { PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(myContainingClass, refMethodClass, PsiSubstitutor.EMPTY); if (substitutor != null) { MethodSignature superSignature = method.getSignature(substitutor); MethodSignature refSignature = refMethod.getSignature(PsiSubstitutor.EMPTY); if (MethodSignatureUtil.isSubsignature(superSignature, refSignature)) { if (!consumer.process(ref)) return false; } } } if (!myStrictSignatureSearch) { PsiManager manager = method.getManager(); if (manager.areElementsEquivalent(refMethodClass, myContainingClass)) { if (!consumer.process(ref)) return false; } } } return true; }
@NotNull public static Query<MethodSignatureBackedByPsiMethod> search(@NotNull PsiMethod derivedMethod, @Nullable final PsiClass psiClass, boolean checkBases, boolean allowStaticMethod) { final SearchParameters parameters = new SearchParameters(derivedMethod, psiClass, checkBases, allowStaticMethod); return SUPER_METHODS_SEARCH_INSTANCE.createUniqueResultsQuery(parameters, MethodSignatureUtil.METHOD_BASED_HASHING_STRATEGY); }
private static void processClass(final PsiClass aClass, final boolean[] hasEquals, final boolean[] hasHashCode, PsiMethod equals, PsiMethod hashcode) { final PsiMethod[] methods = aClass.getMethods(); for (PsiMethod method : methods) { if (MethodSignatureUtil.areSignaturesEqual(method, equals)) { hasEquals[0] = true; } else if (MethodSignatureUtil.areSignaturesEqual(method, hashcode)) { hasHashCode[0] = true; } } }
private boolean superMethodExists(MethodSignature methodSignature) { LOG.assertTrue(myClass.isValid()); PsiMethod superEquals = MethodSignatureUtil.findMethodBySignature(myClass, methodSignature, true); if (superEquals == null) return true; if (superEquals.hasModifierProperty(PsiModifier.ABSTRACT)) return false; return !CommonClassNames.JAVA_LANG_OBJECT.equals(superEquals.getContainingClass().getQualifiedName()); }
@Override public boolean isAvailable(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) { final PsiClass myClass = (PsiClass)startElement; return myMethodPrototype.isValid() && myClass.isValid() && myClass.getManager().isInProject(myClass) && myText != null && MethodSignatureUtil.findMethodBySignature(myClass, myMethodPrototype, false) == null ; }