private void doMoveClass(PsiSubstitutor substitutor, GrMemberInfo info) { GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); GrTypeDefinition aClass = (GrTypeDefinition) info.getMember(); if (Boolean.FALSE.equals(info.getOverrides())) { final GrReferenceList sourceReferenceList = info.getSourceReferenceList(); LOG.assertTrue(sourceReferenceList != null); GrCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ? removeFromReferenceList(sourceReferenceList, aClass) : findReferenceToClass(sourceReferenceList, aClass); if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) { replaceMovedMemberTypeParameters( ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); GrReferenceList referenceList; if (myTargetSuperClass.isInterface()) { referenceList = myTargetSuperClass.getExtendsClause(); if (referenceList == null) { GrExtendsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createExtendsClause(); PsiElement anchor = myTargetSuperClass.getTypeParameterList() != null ? myTargetSuperClass.getTypeParameterList() : myTargetSuperClass.getNameIdentifierGroovy(); referenceList = (GrReferenceList) myTargetSuperClass.addAfter(newClause, anchor); addSpacesAround(referenceList); } } else { referenceList = myTargetSuperClass.getImplementsClause(); if (referenceList == null) { GrImplementsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createImplementsClause(); PsiElement anchor = myTargetSuperClass.getExtendsClause() != null ? myTargetSuperClass.getExtendsClause() : myTargetSuperClass.getTypeParameterList() != null ? myTargetSuperClass.getTypeParameterList() : myTargetSuperClass.getNameIdentifierGroovy(); referenceList = (GrReferenceList) myTargetSuperClass.addAfter(newClause, anchor); addSpacesAround(referenceList); } } assert referenceList != null; referenceList.add(ref); } } else { replaceMovedMemberTypeParameters( aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); // fixReferencesToStatic(aClass, movedMembers); PsiMember movedElement = (PsiMember) myTargetSuperClass.addAfter(aClass, null); // movedElement = (PsiMember)CodeStyleManager.getInstance(myProject).reformat(movedElement); myMembersAfterMove.add(movedElement); deleteMemberWithDocComment(aClass); } }
@NotNull @Override protected UsageInfo[] findUsages() { final List<UsageInfo> result = new ArrayList<UsageInfo>(); for (GrMemberInfo info : myMembersToMove) { final PsiMember member = info.getMember(); if (member.hasModifierProperty(PsiModifier.STATIC)) { for (PsiReference reference : ReferencesSearch.search(member)) { result.add(new UsageInfo(reference)); } } } return DefaultGroovyMethods.asType(result, UsageInfo[].class); }
public void setCorrectVisibility(final HashSet<PsiMember> movedMembers, GrMemberInfo info) { PsiModifierListOwner modifierListOwner = info.getMember(); if (myTargetSuperClass.isInterface()) { PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true); } else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) { if (info.isToAbstract() || willBeUsedInSubclass( modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) { PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true); } if (modifierListOwner instanceof GrTypeDefinition) { ((GrTypeDefinition) modifierListOwner) .accept( new GroovyRecursiveElementVisitor() { @Override public void visitMethod(GrMethod method) { check(method); } @Override public void visitField(GrField field) { check(field); } @Override public void visitTypeDefinition(GrTypeDefinition typeDefinition) { check(typeDefinition); super.visitTypeDefinition(typeDefinition); } private void check(PsiMember member) { if (member.hasModifierProperty(PsiModifier.PRIVATE)) { if (willBeUsedInSubclass( member, movedMembers, myTargetSuperClass, mySourceClass)) { PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true); } } } }); } } }
private void doMoveField(PsiSubstitutor substitutor, GrMemberInfo info) { GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); GrField field = (GrField) info.getMember(); field.normalizeDeclaration(); replaceMovedMemberTypeParameters( field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); // fixReferencesToStatic(field, movedMembers); if (myTargetSuperClass.isInterface()) { PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true); } final PsiMember movedElement = (PsiMember) myTargetSuperClass.add(field); myMembersAfterMove.add(movedElement); deleteMemberWithDocComment(field); }
private void doMoveMethod(PsiSubstitutor substitutor, GrMemberInfo info) { GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); GrMethod method = (GrMethod) info.getMember(); PsiMethod sibling = method; PsiMethod anchor = null; while (sibling != null) { sibling = PsiTreeUtil.getNextSiblingOfType(sibling, PsiMethod.class); if (sibling != null) { anchor = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived( method.getContainingClass(), myTargetSuperClass, sibling.getSignature(PsiSubstitutor.EMPTY), false); if (anchor != null) { break; } } } GrMethod methodCopy = (GrMethod) method.copy(); if (method.findSuperMethods(myTargetSuperClass).length == 0) { deleteOverrideAnnotationIfFound(methodCopy); } final boolean isOriginalMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.DEFAULT); if (myTargetSuperClass.isInterface() || info.isToAbstract()) { GroovyChangeContextUtil.clearContextInfo(method); RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy); if (myTargetSuperClass.isInterface()) { PsiUtil.setModifierProperty(methodCopy, PsiModifier.ABSTRACT, false); } replaceMovedMemberTypeParameters( methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); final GrMethod movedElement = anchor != null ? (GrMethod) myTargetSuperClass.addBefore(methodCopy, anchor) : (GrMethod) myTargetSuperClass.add(methodCopy); CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject()); if (styleSettings.INSERT_OVERRIDE_ANNOTATION) { if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface() || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) { new AddAnnotationFix(CommonClassNames.JAVA_LANG_OVERRIDE, method) .invoke(method.getProject(), null, mySourceClass.getContainingFile()); } } GrDocComment oldDoc = method.getDocComment(); if (oldDoc != null) { GrDocCommentUtil.setDocComment(movedElement, oldDoc); } myDocCommentPolicy.processCopiedJavaDoc( methodCopy.getDocComment(), oldDoc, isOriginalMethodAbstract); myMembersAfterMove.add(movedElement); if (isOriginalMethodAbstract) { deleteMemberWithDocComment(method); } } else { if (isOriginalMethodAbstract) { PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true); } // fixReferencesToStatic(methodCopy, movedMembers); replaceMovedMemberTypeParameters( methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false); final GrMethod movedElement; if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { movedElement = (GrMethod) superClassMethod.replace(methodCopy); } else { movedElement = anchor != null ? (GrMethod) myTargetSuperClass.addBefore(methodCopy, anchor) : (GrMethod) myTargetSuperClass.add(methodCopy); myMembersAfterMove.add(movedElement); } GrDocCommentUtil.setDocComment(movedElement, method.getDocComment()); deleteMemberWithDocComment(method); } }
public void moveMembersToBase() throws IncorrectOperationException { final HashSet<PsiMember> movedMembers = ContainerUtil.newHashSet(); myMembersAfterMove = ContainerUtil.newHashSet(); // build aux sets for (GrMemberInfo info : myMembersToMove) { movedMembers.add(info.getMember()); } // correct private member visibility for (GrMemberInfo info : myMembersToMove) { if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue; setCorrectVisibility(movedMembers, info); GroovyChangeContextUtil.encodeContextInfo(info.getMember()); info.getMember().accept(new QualifiedThisSuperSearcher()); fixReferencesToStatic(info.getMember(), movedMembers); } final PsiSubstitutor substitutor = upDownSuperClassSubstitutor(); // do actual move for (GrMemberInfo info : myMembersToMove) { if (info.getMember() instanceof PsiMethod) { doMoveMethod(substitutor, info); } else if (info.getMember() instanceof GrField) { doMoveField(substitutor, info); } else if (info.getMember() instanceof PsiClass) { doMoveClass(substitutor, info); } } ExplicitSuperDeleter explicitSuperDeleter = new ExplicitSuperDeleter(); for (PsiMember member : myMembersAfterMove) { ((GrMember) member).accept(explicitSuperDeleter); } explicitSuperDeleter.fixSupers(); final QualifiedThisSuperAdjuster qualifiedThisSuperAdjuster = new QualifiedThisSuperAdjuster(); for (PsiMember member : myMembersAfterMove) { ((GrMember) member).accept(qualifiedThisSuperAdjuster); } for (PsiMember member : myMembersAfterMove) { GroovyChangeContextUtil.decodeContextInfo(member, null, null); } final JavaRefactoringListenerManagerImpl listenerManager = (JavaRefactoringListenerManagerImpl) JavaRefactoringListenerManager.getInstance(myProject); for (final PsiMember movedMember : myMembersAfterMove) { ((GroovyPsiElement) movedMember) .accept( new GroovyRecursiveElementVisitor() { @Override public void visitReferenceExpression(GrReferenceExpression referenceExpression) { if (processRef(referenceExpression)) return; super.visitReferenceExpression(referenceExpression); } @Override public void visitCodeReferenceElement(GrCodeReferenceElement refElement) { if (processRef(refElement)) return; super.visitCodeReferenceElement(refElement); } private boolean processRef( @NotNull GrReferenceElement<? extends GroovyPsiElement> refElement) { final PsiElement qualifier = refElement.getQualifier(); if (qualifier != null) { final Boolean preserveQualifier = qualifier.getCopyableUserData(PRESERVE_QUALIFIER); if (preserveQualifier != null && !preserveQualifier) { refElement.setQualifier(null); return true; } } return false; } }); listenerManager.fireMemberMoved(mySourceClass, movedMember); } }