public static void checkFieldConflicts( @Nullable PsiClass aClass, String newName, final Map<PsiElement, String> conflicts) { PsiField existingField = aClass != null ? aClass.findFieldByName(newName, true) : null; if (existingField != null) { if (aClass.equals(existingField.getContainingClass())) { String className = aClass instanceof PsiAnonymousClass ? RefactoringBundle.message("current.class") : RefactoringUIUtil.getDescription(aClass, false); final String conflict = RefactoringBundle.message( "field.0.is.already.defined.in.the.1", existingField.getName(), className); conflicts.put(existingField, conflict); } else { // method somewhere in base class if (!existingField.hasModifierProperty(PsiModifier.PRIVATE)) { String fieldInfo = PsiFormatUtil.formatVariable( existingField, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER, PsiSubstitutor.EMPTY); String className = RefactoringUIUtil.getDescription(existingField.getContainingClass(), false); final String descr = RefactoringBundle.message( "field.0.will.hide.field.1.of.the.base.class", newName, fieldInfo, className); conflicts.put(existingField, descr); } } } }
public static void checkMethodConflicts( @Nullable PsiClass aClass, PsiMethod refactoredMethod, PsiMethod prototype, final MultiMap<PsiElement, String> conflicts) { if (prototype == null) return; PsiMethod method = aClass != null ? aClass.findMethodBySignature(prototype, true) : null; if (method != null && method != refactoredMethod) { if (aClass.equals(method.getContainingClass())) { final String classDescr = aClass instanceof PsiAnonymousClass ? RefactoringBundle.message("current.class") : RefactoringUIUtil.getDescription(aClass, false); conflicts.putValue( method, RefactoringBundle.message( "method.0.is.already.defined.in.the.1", getMethodPrototypeString(prototype), classDescr)); } else { // method somewhere in base class if (JavaPsiFacade.getInstance(method.getProject()) .getResolveHelper() .isAccessible(method, aClass, null)) { String protoMethodInfo = getMethodPrototypeString(prototype); String className = CommonRefactoringUtil.htmlEmphasize( UsageViewUtil.getDescriptiveName(method.getContainingClass())); if (PsiUtil.getAccessLevel(prototype.getModifierList()) >= PsiUtil.getAccessLevel(method.getModifierList())) { boolean isMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); boolean isMyMethodAbstract = refactoredMethod != null && refactoredMethod.hasModifierProperty(PsiModifier.ABSTRACT); final String conflict = isMethodAbstract != isMyMethodAbstract ? RefactoringBundle.message( "method.0.will.implement.method.of.the.base.class", protoMethodInfo, className) : RefactoringBundle.message( "method.0.will.override.a.method.of.the.base.class", protoMethodInfo, className); conflicts.putValue(method, conflict); } else { // prototype is private, will be compile-error conflicts.putValue( method, RefactoringBundle.message( "method.0.will.hide.method.of.the.base.class", protoMethodInfo, className)); } } } } }
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) { final UsageInfo[] usages = refUsages.get(); MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); final Set<PsiMember> members = new HashSet<PsiMember>(); members.add(myMethod); if (myTargetVariable instanceof PsiField) members.add((PsiMember) myTargetVariable); if (!myTargetClass.isInterface()) { RefactoringConflictsUtil.analyzeAccessibilityConflicts( members, myTargetClass, conflicts, myNewVisibility); } else { for (final UsageInfo usage : usages) { if (usage instanceof InheritorUsageInfo) { RefactoringConflictsUtil.analyzeAccessibilityConflicts( members, ((InheritorUsageInfo) usage).getInheritor(), conflicts, myNewVisibility); } } } if (myTargetVariable instanceof PsiParameter) { PsiParameter parameter = (PsiParameter) myTargetVariable; for (final UsageInfo usageInfo : usages) { if (usageInfo instanceof MethodCallUsageInfo) { final PsiElement methodCall = ((MethodCallUsageInfo) usageInfo).getMethodCallExpression(); if (methodCall instanceof PsiMethodCallExpression) { final PsiExpression[] expressions = ((PsiMethodCallExpression) methodCall).getArgumentList().getExpressions(); final int index = myMethod.getParameterList().getParameterIndex(parameter); if (index < expressions.length) { PsiExpression instanceValue = expressions[index]; instanceValue = RefactoringUtil.unparenthesizeExpression(instanceValue); if (instanceValue instanceof PsiLiteralExpression && ((PsiLiteralExpression) instanceValue).getValue() == null) { String message = RefactoringBundle.message( "0.contains.call.with.null.argument.for.parameter.1", RefactoringUIUtil.getDescription( ConflictsUtil.getContainer(methodCall), true), CommonRefactoringUtil.htmlEmphasize(parameter.getName())); conflicts.putValue(instanceValue, message); } } } else if (methodCall instanceof PsiMethodReferenceExpression) { conflicts.putValue(methodCall, "Method reference would be broken after move"); } } } } try { ConflictsUtil.checkMethodConflicts(myTargetClass, myMethod, getPatternMethod(), conflicts); } catch (IncorrectOperationException e) { } return showConflicts(conflicts, usages); }
private void detectAccessibilityConflicts( final UsageInfo[] usageArray, MultiMap<PsiElement, String> conflicts) { if (myParameterInitializer != null) { final ReferencedElementsCollector collector = new ReferencedElementsCollector(); myParameterInitializer.accept(collector); final Set<PsiElement> result = collector.myResult; if (!result.isEmpty()) { for (final UsageInfo usageInfo : usageArray) { if (usageInfo instanceof ExternalUsageInfo && IntroduceParameterUtil.isMethodUsage(usageInfo)) { final PsiElement place = usageInfo.getElement(); for (PsiElement element : result) { if (element instanceof PsiField && myReplaceFieldsWithGetters != IntroduceParameterRefactoring .REPLACE_FIELDS_WITH_GETTERS_NONE) { // check getter access instead final PsiClass psiClass = ((PsiField) element).getContainingClass(); LOG.assertTrue(psiClass != null); final PsiMethod method = psiClass.findMethodBySignature( PropertyUtil.generateGetterPrototype((PsiField) element), true); if (method != null) { element = method; } } if (element instanceof PsiMember && !JavaPsiFacade.getInstance(myProject) .getResolveHelper() .isAccessible((PsiMember) element, place, null)) { String message = RefactoringBundle.message( "0.is.not.accessible.from.1.value.for.introduced.parameter.in.that.method.call.will.be.incorrect", RefactoringUIUtil.getDescription(element, true), RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(place), true)); conflicts.putValue(element, message); } } } } } } }
@Override public void visitVariable(PsiVariable variable) { if (variable == myLocalVariable) return; if (myParameterName.equals(variable.getName())) { String descr = RefactoringBundle.message( "there.is.already.a.0.it.will.conflict.with.an.introduced.parameter", RefactoringUIUtil.getDescription(variable, true)); conflict = Pair.<PsiElement, String>create(variable, CommonRefactoringUtil.capitalize(descr)); } }
private void addInaccessibilityDescriptions( Set<UsageInfo> usages, MultiMap<PsiElement, String> conflictDescriptions) throws IncorrectOperationException { PsiMethod method = myChangeInfo.getMethod(); PsiModifierList modifierList = (PsiModifierList) method.getModifierList().copy(); VisibilityUtil.setVisibility(modifierList, myChangeInfo.getNewVisibility()); for (Iterator<UsageInfo> iterator = usages.iterator(); iterator.hasNext(); ) { UsageInfo usageInfo = iterator.next(); PsiElement element = usageInfo.getElement(); if (element != null) { if (element instanceof PsiQualifiedReference) { PsiClass accessObjectClass = null; PsiElement qualifier = ((PsiQualifiedReference) element).getQualifier(); if (qualifier instanceof PsiExpression) { accessObjectClass = (PsiClass) PsiUtil.getAccessObjectClass((PsiExpression) qualifier).getElement(); } if (!JavaPsiFacade.getInstance(element.getProject()) .getResolveHelper() .isAccessible(method, modifierList, element, accessObjectClass, null)) { String message = RefactoringBundle.message( "0.with.1.visibility.is.not.accessible.from.2", RefactoringUIUtil.getDescription(method, true), myChangeInfo.getNewVisibility(), RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true)); conflictDescriptions.putValue(method, message); if (!needToChangeCalls()) { iterator.remove(); } } } } } }