boolean (@NotNull Ref<UsageInfo[]> refUsages) { final MultiMap<PsiElement, String> conflicts = new MultiMap<>(); final HashMap<PsiElement,HashSet<PsiElement>> reported = new HashMap<>(); class Visitor extends JavaRecursiveElementWalkingVisitor { @Override public void visitReferenceElement(@NotNull PsiJavaCodeReferenceElement reference) { PsiElement resolved = reference.resolve(); if (resolved instanceof PsiMember && PsiTreeUtil.isAncestor(myInnerClass, resolved, true) && becomesInaccessible((PsiMember)resolved)) { registerConflict(reference, resolved, reported, conflicts); } } @Override public void visitClass(@NotNull PsiClass aClass) { if (aClass == myInnerClass) return; super.visitClass(aClass); } } // if (myInnerClass.hasModifierProperty(PsiModifier.)) { myOuterClass.accept(new Visitor()); myInnerClass.accept(new JavaRecursiveElementWalkingVisitor() { @Override public void visitReferenceElement(@NotNull PsiJavaCodeReferenceElement reference) { super.visitReferenceElement(reference); final PsiElement resolve = reference.resolve(); if (resolve instanceof PsiMember) { if (PsiTreeUtil.isAncestor(myOuterClass, resolve, true) && !PsiTreeUtil.isAncestor(myInnerClass, resolve, false)) { if (becomesInaccessible((PsiMember)resolve)) { registerConflict(reference, resolve, reported, conflicts); } } } } }); return showConflicts(conflicts, refUsages.get()); } private static void registerConflict(PsiJavaCodeReferenceElement reference, PsiElement resolved, HashMap<PsiElement, HashSet<PsiElement>> reported, MultiMap<PsiElement, String> conflicts) { final PsiElement container = ConflictsUtil.getContainer(reference); HashSet<PsiElement> containerSet = reported.get(container); if (containerSet == null) { containerSet = new HashSet<>(); reported.put(container, containerSet); } if (!containerSet.contains(resolved)) { containerSet.add(resolved); String message = JavaRefactoringBundle.message("0.will.become.inaccessible.from.1", RefactoringUIUtil.getDescription(resolved, true), RefactoringUIUtil.getDescription(container, true)); conflicts.putValue(reference, message); } } private boolean becomesInaccessible(PsiMember element) { final String visibilityModifier = VisibilityUtil.getVisibilityModifier(element.getModifierList()); if (PsiModifier.PRIVATE.equals(visibilityModifier)) return true; if (PsiModifier.PUBLIC.equals(visibilityModifier)) return false; if (PsiModifier.PROTECTED.equals(visibilityModifier)) { if (InheritanceUtil.isInheritorOrSelf(myInnerClass, myOuterClass, true)) { return false; } PsiClass memberClass = element.getContainingClass(); if (memberClass != null && InheritanceUtil.hasEnclosingInstanceInScope(memberClass, myInnerClass, true, false)) { return false; } } final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); if (myTargetContainer instanceof PsiDirectory) { final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)myTargetContainer); assert aPackage != null : myTargetContainer; return !psiFacade.isInPackage(myOuterClass, aPackage); } // target container is a class PsiFile targetFile = myTargetContainer.getContainingFile(); if (targetFile != null) { final PsiDirectory containingDirectory = targetFile.getContainingDirectory(); if (containingDirectory != null) { final PsiPackage targetPackage = JavaDirectoryService.getInstance().getPackage(containingDirectory); assert targetPackage != null : myTargetContainer; return psiFacade.isInPackage(myOuterClass, targetPackage); } } return false; } public void setup(final PsiClass innerClass, final String className, final boolean passOuterClass, final String parameterName, boolean searchInComments, boolean searchInNonJava, @NotNull final PsiElement targetContainer) { myNewClassName = className; myInnerClass = innerClass; myDescriptiveName = DescriptiveNameUtil.getDescriptiveName(myInnerClass); myOuterClass = myInnerClass.getContainingClass(); myTargetContainer = targetContainer; JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myProject); myParameterNameOuterClass = passOuterClass ? parameterName : null; if (myParameterNameOuterClass != null) { myFieldNameOuterClass = codeStyleManager.variableNameToPropertyName(myParameterNameOuterClass, VariableKind.PARAMETER); myFieldNameOuterClass = codeStyleManager.propertyNameToVariableName(myFieldNameOuterClass, VariableKind.FIELD); } mySearchInComments = searchInComments; mySearchInNonJavaFiles = searchInNonJava; } private void addFieldInitializationToConstructors(PsiClass aClass, PsiField field, String parameterName) throws IncorrectOperationException { PsiMethod[] constructors = aClass.getConstructors(); PsiElementFactory factory = JavaPsiFacade.getElementFactory(myProject); if (constructors.length > 0) { for (PsiMethod constructor : constructors) { if (parameterName != null) { PsiParameterList parameterList = constructor.getParameterList(); PsiParameter parameter = factory.createParameter(parameterName, field.getType()); parameterList.addAfter(parameter, null); } PsiCodeBlock body = constructor.getBody(); if (body == null) continue; PsiStatement[] statements = body.getStatements(); if (statements.length > 0) { PsiStatement first = statements[0]; if (first instanceof PsiExpressionStatement) { PsiExpression expression = ((PsiExpressionStatement)first).getExpression(); if (expression instanceof PsiMethodCallExpression) { @NonNls String text = ((PsiMethodCallExpression)expression).getMethodExpression().getText(); if ("this".equals(text)) { continue; } } } } createAssignmentStatement(constructor, field.getName(), parameterName); } } else { PsiMethod constructor = factory.createConstructor(); if (parameterName != null) { PsiParameterList parameterList = constructor.getParameterList(); PsiParameter parameter = factory.createParameter(parameterName, field.getType()); parameterList.add(parameter); } createAssignmentStatement(constructor, field.getName(), parameterName); aClass.add(constructor); } } private PsiStatement createAssignmentStatement(PsiMethod constructor, String fieldName, String parameterName) throws IncorrectOperationException { PsiElementFactory factory = JavaPsiFacade.getElementFactory(myProject); @NonNls String pattern = fieldName + "=a;"; if (fieldName.equals(parameterName)) { pattern = "this." + pattern; } PsiExpressionStatement statement = (PsiExpressionStatement)factory.createStatementFromText(pattern, null); statement = (PsiExpressionStatement)CodeStyleManager.getInstance(myProject).reformat(statement); PsiCodeBlock body = constructor.getBody(); assert body != null : constructor; statement = (PsiExpressionStatement)body.addAfter(statement, getAnchorElement(body)); PsiAssignmentExpression assignment = (PsiAssignmentExpression)statement.getExpression(); PsiReferenceExpression rExpr = (PsiReferenceExpression)assignment.getRExpression(); assert rExpr != null : assignment; PsiIdentifier identifier = (PsiIdentifier)rExpr.getReferenceNameElement(); assert identifier != null : assignment; identifier.replace(factory.createIdentifier(parameterName)); return statement; } @Nullable private static PsiElement getAnchorElement(PsiCodeBlock body) { PsiStatement[] statements = body.getStatements(); if (statements.length > 0) { PsiStatement first = statements[0]; if (first instanceof PsiExpressionStatement) { PsiExpression expression = ((PsiExpressionStatement)first).getExpression(); if (expression instanceof PsiMethodCallExpression) { PsiReferenceExpression methodCall = ((PsiMethodCallExpression)expression).getMethodExpression(); @NonNls String text = methodCall.getText(); if ("super".equals(text)) { return first; } } } } return null; } public PsiClass getInnerClass() { return myInnerClass; } public String getNewClassName() { return myNewClassName; } public boolean shouldPassParameter() { return myParameterNameOuterClass != null; } public String getParameterName() { return myParameterNameOuterClass; } public void setOpenInEditor(boolean openInEditor) { myOpenInEditor = openInEditor; } }