mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 06:51:17 +07:00
pull-up
This commit is contained in:
@@ -1444,6 +1444,8 @@
|
||||
implementation="org.jetbrains.plugins.groovy.springloaded.SpringLoadedPositionManagerFactory"/>
|
||||
<codeStyle.ReferenceAdjuster language="Groovy" implementationClass="org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster"/>
|
||||
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.groovy.jarFinder.GroovyFindJarQuickFixProvider"/>
|
||||
<lang.refactoringSupport.classMembersRefactoringSupport language="Groovy"
|
||||
implementationClass="org.jetbrains.plugins.groovy.refactoring.classMembers.GroovyClassMembersRefactoringSupport"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij.debugger">
|
||||
|
||||
+11
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.refactoring;
|
||||
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
@@ -114,6 +115,7 @@ public class GroovyChangeContextUtil {
|
||||
final PsiElement qualifier = refExpr.getQualifier();
|
||||
if (!(qualifier instanceof GrReferenceExpression)) {
|
||||
refExpr.setQualifier(factory.createReferenceExpressionFromText(memberClass.getQualifiedName()));
|
||||
JavaCodeStyleManager.getInstance(manager.getProject()).shortenClassReferences(refExpr.getQualifier());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -140,4 +142,13 @@ public class GroovyChangeContextUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearContextInfo(PsiElement scope) {
|
||||
scope.putCopyableUserData(QUALIFIER_CLASS_KEY, null);
|
||||
scope.putCopyableUserData(REF_TO_CLASS, null);
|
||||
scope.putCopyableUserData(REF_TO_MEMBER, null);
|
||||
for (PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()) {
|
||||
clearContextInfo(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
@@ -41,6 +41,7 @@ import org.jetbrains.plugins.groovy.refactoring.introduce.constant.GrIntroduceCo
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.field.GrIntroduceFieldHandler;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrIntroduceParameterHandler;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.variable.GrIntroduceVariableHandler;
|
||||
import org.jetbrains.plugins.groovy.refactoring.memberPullUp.GrPullUpHandler;
|
||||
|
||||
/**
|
||||
* @author ilyas
|
||||
@@ -129,4 +130,17 @@ public class GroovyRefactoringSupportProvider extends RefactoringSupportProvider
|
||||
public RefactoringActionHandler getIntroduceConstantHandler() {
|
||||
return new GrIntroduceConstantHandler();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public RefactoringActionHandler getPullUpHandler() {
|
||||
return new GrPullUpHandler();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public RefactoringActionHandler getExtractInterfaceHandler() {
|
||||
//return new ExtractInterfaceHandler();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.classMembers;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public abstract class GrClassMemberReferenceVisitor extends GroovyRecursiveElementVisitor {
|
||||
private final PsiClass myClass;
|
||||
|
||||
public GrClassMemberReferenceVisitor(@NotNull PsiClass aClass) {
|
||||
myClass = aClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(GrReferenceExpression ref) {
|
||||
GrExpression qualifier = ref.getQualifier();
|
||||
|
||||
if (qualifier != null && !(PsiUtil.isThisOrSuperRef(qualifier))) {
|
||||
qualifier.accept(this);
|
||||
|
||||
if (!(qualifier instanceof GrReferenceExpression) || !(((GrReferenceExpression) qualifier).resolve() instanceof PsiClass)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PsiElement resolved = ref.resolve();
|
||||
if (resolved instanceof GrMember) {
|
||||
PsiClass containingClass = ((GrMember)resolved).getContainingClass();
|
||||
if (isPartOf(myClass, containingClass)) {
|
||||
visitClassMemberReferenceElement((GrMember)resolved, ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCodeReferenceElement(GrCodeReferenceElement reference) {
|
||||
PsiElement referencedElement = reference.resolve();
|
||||
if (referencedElement instanceof GrTypeDefinition) {
|
||||
final GrTypeDefinition referencedClass = (GrTypeDefinition)referencedElement;
|
||||
if (PsiTreeUtil.isAncestor(myClass, referencedElement, true) ||
|
||||
isPartOf(myClass, referencedClass.getContainingClass())) {
|
||||
visitClassMemberReferenceElement((GrMember)referencedElement, reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPartOf(@NotNull PsiClass aClass, @Nullable PsiClass containingClass) {
|
||||
if (containingClass == null) return false;
|
||||
return aClass.equals(containingClass) || aClass.isInheritor(containingClass, true);
|
||||
}
|
||||
|
||||
protected abstract void visitClassMemberReferenceElement(GrMember resolved, GrReferenceElement ref);
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.classMembers;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.refactoring.classMembers.DependentMembersCollectorBase;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrDependantMembersCollector extends DependentMembersCollectorBase<GrMember, PsiClass> {
|
||||
public GrDependantMembersCollector(PsiClass clazz, PsiClass superClass) {
|
||||
super(clazz, superClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(GrMember member) {
|
||||
member.accept(new GrClassMemberReferenceVisitor(getClazz()) {
|
||||
@Override
|
||||
protected void visitClassMemberReferenceElement(GrMember classMember, GrReferenceElement ref) {
|
||||
if (!existsInSuperClass(classMember)) {
|
||||
myCollection.add(classMember);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean existsInSuperClass(PsiMember classMember) {
|
||||
if (getSuperClass() == null) return false;
|
||||
if (!(classMember instanceof PsiMethod)) return false;
|
||||
final PsiMethod method = ((PsiMethod)classMember);
|
||||
final PsiMethod methodBySignature = (getSuperClass()).findMethodBySignature(method, true);
|
||||
return methodBySignature != null;
|
||||
}
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.classMembers;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoBase;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrMemberInfo extends MemberInfoBase<GrMember> {
|
||||
public GrMemberInfo(GrMember member) {
|
||||
this(member, false, null);
|
||||
}
|
||||
|
||||
public GrMemberInfo(GrMember member, boolean isSuperClass, GrReferenceList sourceReferenceList) {
|
||||
super(member);
|
||||
LOG.assertTrue(member.isValid());
|
||||
mySourceReferenceList = sourceReferenceList;
|
||||
if (member instanceof GrMethod) {
|
||||
GrMethod method = (GrMethod)member;
|
||||
displayName = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER | PsiFormatUtil.SHOW_PARAMETERS,
|
||||
PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER);
|
||||
PsiMethod[] superMethods = method.findSuperMethods();
|
||||
if (superMethods.length > 0) {
|
||||
overrides = !superMethods[0].hasModifierProperty(PsiModifier.ABSTRACT) ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
else {
|
||||
overrides = null;
|
||||
}
|
||||
|
||||
isStatic = method.hasModifierProperty(PsiModifier.STATIC);
|
||||
}
|
||||
else if (member instanceof GrField) {
|
||||
GrField field = (GrField)member;
|
||||
displayName = PsiFormatUtil
|
||||
.formatVariable(field, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER, PsiSubstitutor.EMPTY);
|
||||
isStatic = field.hasModifierProperty(PsiModifier.STATIC);
|
||||
overrides = null;
|
||||
}
|
||||
else if (member instanceof GrTypeDefinition) {
|
||||
GrTypeDefinition aClass = (GrTypeDefinition)member;
|
||||
|
||||
if (isSuperClass) {
|
||||
if (aClass.isInterface()) {
|
||||
displayName = RefactoringBundle.message("member.info.implements.0", aClass.getName());
|
||||
overrides = Boolean.FALSE;
|
||||
}
|
||||
else {
|
||||
displayName = RefactoringBundle.message("member.info.extends.0", aClass.getName());
|
||||
overrides = Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
displayName = aClass.getName();
|
||||
overrides = null;
|
||||
}
|
||||
|
||||
isStatic = aClass.hasModifierProperty(PsiModifier.STATIC);
|
||||
}
|
||||
else {
|
||||
LOG.assertTrue(false);
|
||||
isStatic = false;
|
||||
displayName = "";
|
||||
overrides = null;
|
||||
}
|
||||
}
|
||||
|
||||
public GrReferenceList getSourceReferenceList() {
|
||||
return mySourceReferenceList;
|
||||
}
|
||||
|
||||
public static List<GrMemberInfo> extractClassMembers(GrTypeDefinition subclass, Filter<GrMember> filter, boolean extractInterfacesDeep) {
|
||||
List<GrMemberInfo> members = new ArrayList<GrMemberInfo>();
|
||||
extractClassMembers(subclass, members, filter, extractInterfacesDeep);
|
||||
return members;
|
||||
}
|
||||
|
||||
public static void extractClassMembers(PsiClass subclass,
|
||||
List<GrMemberInfo> result,
|
||||
Filter<GrMember> filter,
|
||||
final boolean extractInterfacesDeep) {
|
||||
|
||||
if (!(subclass instanceof GrTypeDefinition)) return;
|
||||
|
||||
|
||||
if (extractInterfacesDeep) {
|
||||
extractSuperInterfaces(subclass, filter, result, ContainerUtil.<PsiClass>newHashSet());
|
||||
}
|
||||
else {
|
||||
PsiClass[] interfaces = subclass.getInterfaces();
|
||||
GrReferenceList sourceRefList = subclass.isInterface()
|
||||
? ((GrTypeDefinition)subclass).getExtendsClause()
|
||||
: ((GrTypeDefinition)subclass).getImplementsClause();
|
||||
for (PsiClass anInterface : interfaces) {
|
||||
if (anInterface instanceof GrTypeDefinition && filter.includeMember((GrMember)anInterface)) {
|
||||
result.add(new GrMemberInfo((GrMember)anInterface, true, sourceRefList));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PsiClass[] innerClasses = subclass.getInnerClasses();
|
||||
for (PsiClass innerClass : innerClasses) {
|
||||
if (innerClass instanceof GrTypeDefinition && filter.includeMember((GrMember)innerClass)) {
|
||||
result.add(new GrMemberInfo((GrMember)innerClass));
|
||||
}
|
||||
}
|
||||
|
||||
GrMethod[] methods = ((GrTypeDefinition)subclass).getCodeMethods();
|
||||
for (GrMethod method : methods) {
|
||||
if (!method.isConstructor() && filter.includeMember(method)) {
|
||||
result.add(new GrMemberInfo(method));
|
||||
}
|
||||
}
|
||||
|
||||
GrField[] fields = ((GrTypeDefinition)subclass).getCodeFields();
|
||||
for (final GrField field : fields) {
|
||||
if (filter.includeMember(field)) {
|
||||
result.add(new GrMemberInfo(field));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void extractSuperInterfaces(final PsiClass subclass,
|
||||
final Filter<GrMember> filter,
|
||||
final List<GrMemberInfo> result,
|
||||
Set<PsiClass> processed) {
|
||||
if (!processed.contains(subclass)) {
|
||||
processed.add(subclass);
|
||||
if (subclass instanceof GrTypeDefinition) {
|
||||
extractSuperInterfacesFromReferenceList(((GrTypeDefinition)subclass).getExtendsClause(), filter, result, processed);
|
||||
extractSuperInterfacesFromReferenceList(((GrTypeDefinition)subclass).getImplementsClause(), filter, result, processed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void extractSuperInterfacesFromReferenceList(final GrReferenceList referenceList,
|
||||
final Filter<GrMember> filter,
|
||||
final List<GrMemberInfo> result,
|
||||
final Set<PsiClass> processed) {
|
||||
if (referenceList != null) {
|
||||
final PsiClassType[] extendsListTypes = referenceList.getReferenceTypes();
|
||||
for (PsiClassType extendsListType : extendsListTypes) {
|
||||
final PsiClass aSuper = extendsListType.resolve();
|
||||
if (aSuper instanceof GrTypeDefinition) {
|
||||
if (aSuper.isInterface()) {
|
||||
if (filter.includeMember((GrMember)aSuper)) {
|
||||
result.add(new GrMemberInfo((GrMember)aSuper, true, referenceList));
|
||||
}
|
||||
}
|
||||
else {
|
||||
extractSuperInterfaces(aSuper, filter, result, processed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final GrReferenceList mySourceReferenceList;
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.classMembers;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.refactoring.classMembers.AbstractMemberInfoStorage;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoBase;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrExtendsClause;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrImplementsClause;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrMemberInfoStorage extends AbstractMemberInfoStorage<GrMember, PsiClass, GrMemberInfo> {
|
||||
public GrMemberInfoStorage(GrTypeDefinition aClass, MemberInfoBase.Filter<GrMember> memberInfoFilter) {
|
||||
super(aClass, memberInfoFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInheritor(PsiClass baseClass, PsiClass aClass) {
|
||||
return aClass.isInheritor(baseClass, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extractClassMembers(PsiClass aClass, ArrayList<GrMemberInfo> temp) {
|
||||
GrMemberInfo.extractClassMembers(aClass, temp, myFilter, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean memberConflict(GrMember member1, GrMember member) {
|
||||
if (member instanceof GrMethod && member1 instanceof GrMethod) {
|
||||
return MethodSignatureUtil.areSignaturesEqual((GrMethod)member, (GrMethod)member1);
|
||||
}
|
||||
else if (member instanceof GrField && member1 instanceof GrField ||
|
||||
member instanceof GrTypeDefinition && member1 instanceof GrTypeDefinition) {
|
||||
return member.getName().equals(member1.getName());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void buildSubClassesMap(PsiClass aClass) {
|
||||
if (aClass instanceof GrTypeDefinition) {
|
||||
final GrExtendsClause extendsList = ((GrTypeDefinition)aClass).getExtendsClause();
|
||||
if (extendsList != null) {
|
||||
buildSubClassesMapForList(extendsList.getReferenceTypes(), (GrTypeDefinition)aClass);
|
||||
}
|
||||
|
||||
final GrImplementsClause implementsList = ((GrTypeDefinition)aClass).getImplementsClause();
|
||||
if (implementsList != null) {
|
||||
buildSubClassesMapForList(implementsList.getReferenceTypes(), (GrTypeDefinition)aClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void buildSubClassesMapForList(final PsiClassType[] classesList, GrTypeDefinition aClass) {
|
||||
for (int i = 0; i < classesList.length; i++) {
|
||||
PsiClassType element = classesList[i];
|
||||
PsiClass resolved = element.resolve();
|
||||
if (resolved instanceof GrTypeDefinition) {
|
||||
GrTypeDefinition superClass = (GrTypeDefinition)resolved;
|
||||
getSubclasses(superClass).add(aClass);
|
||||
buildSubClassesMap(superClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.classMembers;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiModifierList;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoModel;
|
||||
import com.intellij.refactoring.ui.AbstractMemberSelectionTable;
|
||||
import com.intellij.ui.RowIcon;
|
||||
import com.intellij.util.IconUtil;
|
||||
import com.intellij.util.VisibilityIcons;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrMemberSelectionTable extends AbstractMemberSelectionTable<GrMember, GrMemberInfo> {
|
||||
|
||||
public GrMemberSelectionTable(final List<GrMemberInfo> memberInfos, String abstractColumnHeader) {
|
||||
this(memberInfos, null, abstractColumnHeader);
|
||||
}
|
||||
|
||||
public GrMemberSelectionTable(final List<GrMemberInfo> memberInfos, MemberInfoModel<GrMember, GrMemberInfo> memberInfoModel, String abstractColumnHeader) {
|
||||
super(memberInfos, memberInfoModel, abstractColumnHeader);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Object getAbstractColumnValue(GrMemberInfo memberInfo) {
|
||||
if (!(memberInfo.getMember() instanceof PsiMethod)) return null;
|
||||
if (memberInfo.isStatic()) return null;
|
||||
|
||||
PsiMethod method = (PsiMethod)memberInfo.getMember();
|
||||
if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
final Boolean fixedAbstract = myMemberInfoModel.isFixedAbstract(memberInfo);
|
||||
if (fixedAbstract != null) return fixedAbstract;
|
||||
}
|
||||
|
||||
if (!myMemberInfoModel.isAbstractEnabled(memberInfo)) {
|
||||
return myMemberInfoModel.isAbstractWhenDisabled(memberInfo);
|
||||
}
|
||||
else {
|
||||
return memberInfo.isToAbstract() ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAbstractColumnEditable(int rowIndex) {
|
||||
GrMemberInfo info = myMemberInfos.get(rowIndex);
|
||||
if (!(info.getMember() instanceof PsiMethod)) return false;
|
||||
if (info.isStatic()) return false;
|
||||
|
||||
PsiMethod method = (PsiMethod)info.getMember();
|
||||
if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
if (myMemberInfoModel.isFixedAbstract(info) != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return info.isChecked() && myMemberInfoModel.isAbstractEnabled(info);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void setVisibilityIcon(GrMemberInfo memberInfo, RowIcon icon) {
|
||||
PsiMember member = memberInfo.getMember();
|
||||
PsiModifierList modifiers = member != null ? member.getModifierList() : null;
|
||||
if (modifiers != null) {
|
||||
VisibilityIcons.setVisibilityIcon(modifiers, icon);
|
||||
}
|
||||
else {
|
||||
icon.setIcon(IconUtil.getEmptyIcon(true), VISIBILITY_ICON_POSITION);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Icon getOverrideIcon(GrMemberInfo memberInfo) {
|
||||
PsiMember member = memberInfo.getMember();
|
||||
Icon overrideIcon = EMPTY_OVERRIDE_ICON;
|
||||
if (member instanceof PsiMethod) {
|
||||
if (Boolean.TRUE.equals(memberInfo.getOverrides())) {
|
||||
overrideIcon = AllIcons.General.OverridingMethod;
|
||||
}
|
||||
else if (Boolean.FALSE.equals(memberInfo.getOverrides())) {
|
||||
overrideIcon = AllIcons.General.ImplementingMethod;
|
||||
}
|
||||
else {
|
||||
overrideIcon = EMPTY_OVERRIDE_ICON;
|
||||
}
|
||||
}
|
||||
return overrideIcon;
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.classMembers;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.refactoring.classMembers.ClassMembersRefactoringSupport;
|
||||
import com.intellij.refactoring.classMembers.DependentMembersCollectorBase;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoBase;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GroovyClassMembersRefactoringSupport implements ClassMembersRefactoringSupport {
|
||||
@Override
|
||||
public DependentMembersCollectorBase createDependentMembersCollector(Object clazz, Object superClass) {
|
||||
return new GrDependantMembersCollector((PsiClass)clazz, (PsiClass)superClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProperMember(MemberInfoBase member) {
|
||||
return member instanceof GrMemberInfo;
|
||||
}
|
||||
}
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.extractInterface;
|
||||
|
||||
import com.intellij.history.LocalHistory;
|
||||
import com.intellij.history.LocalHistoryAction;
|
||||
import com.intellij.lang.findUsages.DescriptiveNameUtil;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.extractInterface.ExtractClassUtil;
|
||||
import com.intellij.refactoring.extractSuperclass.ExtractSuperClassUtil;
|
||||
import com.intellij.refactoring.lang.ElementsHandler;
|
||||
import com.intellij.refactoring.memberPullUp.PullUpHelper;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.DocCommentPolicy;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfo;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrExtractInterfaceHandler implements RefactoringActionHandler, ElementsHandler {
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
while (true) {
|
||||
if (element == null || element instanceof PsiFile) {
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("error.wrong.caret.position.class"));
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.EXTRACT_INTERFACE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (element instanceof GrTypeDefinition && !(element instanceof GrAnonymousClassDefinition)) {
|
||||
invoke(project, new PsiElement[]{element}, dataContext);
|
||||
return;
|
||||
}
|
||||
|
||||
element = element.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
public void invoke(@NotNull final Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
|
||||
if (elements.length != 1) return;
|
||||
|
||||
|
||||
myProject = project;
|
||||
myClass = (PsiClass)elements[0];
|
||||
|
||||
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, myClass)) return;
|
||||
|
||||
/* todo
|
||||
final JavaExtractSuperBaseDialog dialog = new ExtractInterfaceDialog(myProject, myClass);
|
||||
dialog.show();
|
||||
if (!dialog.isOK() || !dialog.isExtractSuperclass()) return;
|
||||
|
||||
final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
|
||||
ExtractSuperClassUtil.checkSuperAccessible(dialog.getTargetDirectory(), conflicts, myClass);
|
||||
if (!ExtractSuperClassUtil.showConflicts(dialog, conflicts, myProject)) return;
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
myInterfaceName = dialog.getExtractedSuperName();
|
||||
mySelectedMembers = ArrayUtil.toObjectArray(dialog.getSelectedMemberInfos(), MemberInfo.class);
|
||||
myTargetDir = dialog.getTargetDirectory();
|
||||
myJavaDocPolicy = new DocCommentPolicy(dialog.getDocCommentPolicy());
|
||||
try {
|
||||
doRefactoring();
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, REFACTORING_NAME, null);*/
|
||||
}
|
||||
|
||||
private void doRefactoring() throws IncorrectOperationException {
|
||||
LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName());
|
||||
final PsiClass anInterface;
|
||||
try {
|
||||
anInterface = extractInterface(myTargetDir, myClass, myInterfaceName, mySelectedMembers, myJavaDocPolicy);
|
||||
}
|
||||
finally {
|
||||
a.finish();
|
||||
}
|
||||
|
||||
|
||||
if (anInterface != null) {
|
||||
final SmartPsiElementPointer<PsiClass> classPointer =
|
||||
SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(myClass);
|
||||
final SmartPsiElementPointer<PsiClass> interfacePointer =
|
||||
SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(anInterface);
|
||||
final Runnable turnRefsToSuperRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ExtractClassUtil.askAndTurnRefsToSuper(myProject, classPointer, interfacePointer);
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(turnRefsToSuperRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
public static PsiClass extractInterface(PsiDirectory targetDir,
|
||||
PsiClass aClass,
|
||||
String interfaceName,
|
||||
MemberInfo[] selectedMembers,
|
||||
DocCommentPolicy javaDocPolicy) throws IncorrectOperationException {
|
||||
PsiClass anInterface = JavaDirectoryService.getInstance().createInterface(targetDir, interfaceName);
|
||||
PsiJavaCodeReferenceElement ref = ExtractSuperClassUtil.createExtendingReference(anInterface, aClass, selectedMembers);
|
||||
final PsiReferenceList referenceList = aClass.isInterface() ? aClass.getExtendsList() : aClass.getImplementsList();
|
||||
assert referenceList != null;
|
||||
referenceList.add(ref);
|
||||
PullUpHelper pullUpHelper = new PullUpHelper(aClass, anInterface, selectedMembers, javaDocPolicy);
|
||||
pullUpHelper.moveMembersToBase();
|
||||
return anInterface;
|
||||
}
|
||||
|
||||
private String getCommandName() {
|
||||
return RefactoringBundle.message("extract.interface.command.name", myInterfaceName, DescriptiveNameUtil.getDescriptiveName(myClass));
|
||||
}
|
||||
|
||||
public boolean isEnabledOnElements(PsiElement[] elements) {
|
||||
return elements.length == 1 && elements[0] instanceof PsiClass;
|
||||
}
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(GrExtractInterfaceHandler.class);
|
||||
public static final String REFACTORING_NAME = RefactoringBundle.message("extract.interface.title");
|
||||
private Project myProject;
|
||||
private PsiClass myClass;
|
||||
private String myInterfaceName;
|
||||
private MemberInfo[] mySelectedMembers;
|
||||
private PsiDirectory myTargetDir;
|
||||
private DocCommentPolicy myJavaDocPolicy;
|
||||
}
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.memberPullUp;
|
||||
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiDocCommentOwner;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.statistics.StatisticsInfo;
|
||||
import com.intellij.psi.statistics.StatisticsManager;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.classMembers.AbstractUsesDependencyMemberInfoModel;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoModel;
|
||||
import com.intellij.refactoring.memberPullUp.PullUpDialogBase;
|
||||
import com.intellij.refactoring.memberPullUp.PullUpHelper;
|
||||
import com.intellij.refactoring.ui.AbstractMemberSelectionTable;
|
||||
import com.intellij.refactoring.ui.ClassCellRenderer;
|
||||
import com.intellij.refactoring.ui.DocCommentPanel;
|
||||
import com.intellij.refactoring.util.DocCommentPolicy;
|
||||
import com.intellij.refactoring.util.RefactoringHierarchyUtil;
|
||||
import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo;
|
||||
import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfoStorage;
|
||||
import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberSelectionTable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
class GrPullUpDialog extends PullUpDialogBase<GrMemberInfoStorage, GrMemberInfo, GrMember, PsiClass> {
|
||||
private final Callback myCallback;
|
||||
private DocCommentPanel myJavaDocPanel;
|
||||
|
||||
private final InterfaceContainmentVerifier myInterfaceContainmentVerifier = new InterfaceContainmentVerifier() {
|
||||
public boolean checkedInterfacesContain(PsiMethod psiMethod) {
|
||||
return PullUpHelper.checkedInterfacesContain(myMemberInfos, psiMethod);
|
||||
}
|
||||
};
|
||||
|
||||
private static final String PULL_UP_STATISTICS_KEY = "pull.up##";
|
||||
|
||||
public interface Callback {
|
||||
boolean checkConflicts(GrPullUpDialog dialog);
|
||||
}
|
||||
|
||||
public GrPullUpDialog(Project project,
|
||||
PsiClass typeDefinition,
|
||||
List<PsiClass> superClasses,
|
||||
GrMemberInfoStorage storage,
|
||||
GrPullUpHandler handler) {
|
||||
super(project, typeDefinition, superClasses, storage, GrPullUpHandler.REFACTORING_NAME);
|
||||
|
||||
myCallback = handler;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
public int getJavaDocPolicy() {
|
||||
return myJavaDocPanel.getPolicy();
|
||||
}
|
||||
|
||||
protected String getDimensionServiceKey() {
|
||||
return "#com.intellij.refactoring.memberPullUp.PullUpDialog";
|
||||
}
|
||||
|
||||
InterfaceContainmentVerifier getContainmentVerifier() {
|
||||
return myInterfaceContainmentVerifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initClassCombo(JComboBox classCombo) {
|
||||
classCombo.setRenderer(new ClassCellRenderer(classCombo.getRenderer()));
|
||||
classCombo.addItemListener(new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
if (myMemberSelectionPanel != null) {
|
||||
// ((MyMemberInfoModel)myMemberInfoModel).setSuperClass(getSuperClass());
|
||||
myMemberSelectionPanel.getTable().setMemberInfos(myMemberInfos);
|
||||
myMemberSelectionPanel.getTable().fireExternalDataChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected PsiClass getPreselection() {
|
||||
PsiClass preselection = RefactoringHierarchyUtil.getNearestBaseClass(myClass, false);
|
||||
|
||||
final String statKey = PULL_UP_STATISTICS_KEY + myClass.getQualifiedName();
|
||||
for (StatisticsInfo info : StatisticsManager.getInstance().getAllValues(statKey)) {
|
||||
final String superClassName = info.getValue();
|
||||
PsiClass superClass = null;
|
||||
for (PsiClass aClass : mySuperClasses) {
|
||||
if (Comparing.strEqual(superClassName, aClass.getQualifiedName())) {
|
||||
superClass = aClass;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (superClass != null && StatisticsManager.getInstance().getUseCount(info) > 0) {
|
||||
preselection = superClass;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return preselection;
|
||||
}
|
||||
|
||||
protected void doHelpAction() {
|
||||
HelpManager.getInstance().invokeHelp(HelpID.MEMBERS_PULL_UP);
|
||||
}
|
||||
|
||||
protected void doAction() {
|
||||
if (!myCallback.checkConflicts(this)) return;
|
||||
JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC = myJavaDocPanel.getPolicy();
|
||||
final PsiClass superClass = getSuperClass();
|
||||
String name = superClass.getQualifiedName();
|
||||
if (name != null) {
|
||||
StatisticsManager
|
||||
.getInstance().incUseCount(new StatisticsInfo(PULL_UP_STATISTICS_KEY + myClass.getQualifiedName(), name));
|
||||
}
|
||||
|
||||
List<GrMemberInfo> infos = getSelectedMemberInfos();
|
||||
GrPullUpHelper processor =
|
||||
new GrPullUpHelper(myClass, superClass, infos.toArray(new GrMemberInfo[infos.size()]), new DocCommentPolicy(getJavaDocPolicy()));
|
||||
invokeRefactoring(processor);
|
||||
close(OK_EXIT_CODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addCustomElementsToCentralPanel(JPanel panel) {
|
||||
myJavaDocPanel = new DocCommentPanel(RefactoringBundle.message("javadoc.for.abstracts"));
|
||||
myJavaDocPanel.setPolicy(JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC);
|
||||
boolean hasJavadoc = false;
|
||||
for (GrMemberInfo info : myMemberInfos) {
|
||||
final PsiMember member = info.getMember();
|
||||
if (myMemberInfoModel.isAbstractEnabled(info) &&
|
||||
member instanceof PsiDocCommentOwner &&
|
||||
((PsiDocCommentOwner)member).getDocComment() != null) {
|
||||
hasJavadoc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
UIUtil.setEnabled(myJavaDocPanel, hasJavadoc, true);
|
||||
panel.add(myJavaDocPanel, BorderLayout.EAST);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractMemberSelectionTable<GrMember, GrMemberInfo> createMemberSelectionTable(List<GrMemberInfo> infos) {
|
||||
return new GrMemberSelectionTable(infos, RefactoringBundle.message("make.abstract"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MemberInfoModel<GrMember, GrMemberInfo> createMemberInfoModel() {
|
||||
//return new UsedByDependencyMemberInfoModel<PyElement, PyClass, PyMemberInfo>(myClass);
|
||||
return new MyMemberInfoModel(myClass, getSuperClass(), false);
|
||||
}
|
||||
|
||||
private static class MyMemberInfoModel extends AbstractUsesDependencyMemberInfoModel<GrMember, PsiClass, GrMemberInfo> {
|
||||
public MyMemberInfoModel(PsiClass aClass, PsiClass superClass, boolean recursive) {
|
||||
super(aClass, superClass, recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doCheck(@NotNull GrMemberInfo memberInfo, int problem) {
|
||||
if (problem == ERROR && memberInfo.isStatic()) {
|
||||
return WARNING;
|
||||
}
|
||||
return problem;
|
||||
}
|
||||
}
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.memberPullUp;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.classMembers.MemberInfoBase;
|
||||
import com.intellij.refactoring.lang.ElementsHandler;
|
||||
import com.intellij.refactoring.memberPullUp.PullUpConflictsUtil;
|
||||
import com.intellij.refactoring.ui.ConflictsDialog;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.RefactoringHierarchyUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo;
|
||||
import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfoStorage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrPullUpHandler implements RefactoringActionHandler, GrPullUpDialog.Callback, ElementsHandler {
|
||||
private static final Logger LOG = Logger.getInstance(GrPullUpHandler.class);
|
||||
public static final String REFACTORING_NAME = RefactoringBundle.message("pull.members.up.title");
|
||||
|
||||
private PsiClass mySubclass;
|
||||
private Project myProject;
|
||||
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
|
||||
while (true) {
|
||||
if (element == null || element instanceof PsiFile) {
|
||||
String message = RefactoringBundle
|
||||
.getCannotRefactorMessage(RefactoringBundle.message("the.caret.should.be.positioned.inside.a.class.to.pull.members.from"));
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return;
|
||||
|
||||
|
||||
if (element instanceof GrTypeDefinition || element instanceof GrField || element instanceof GrMethod) {
|
||||
invoke(project, new PsiElement[]{element}, dataContext);
|
||||
return;
|
||||
}
|
||||
|
||||
element = element.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
public void invoke(@NotNull final Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
|
||||
if (elements.length != 1) return;
|
||||
|
||||
myProject = project;
|
||||
|
||||
PsiElement element = elements[0];
|
||||
GrTypeDefinition aClass;
|
||||
PsiElement aMember = null;
|
||||
|
||||
if (element instanceof GrTypeDefinition) {
|
||||
aClass = (GrTypeDefinition)element;
|
||||
}
|
||||
else if (element instanceof GrMethod) {
|
||||
aClass = DefaultGroovyMethods.asType(((GrMethod)element).getContainingClass(), GrTypeDefinition.class);
|
||||
aMember = element;
|
||||
}
|
||||
else if (element instanceof GrField) {
|
||||
aClass = DefaultGroovyMethods.asType(((GrField)element).getContainingClass(), GrTypeDefinition.class);
|
||||
aMember = element;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
invokeImpl(project, dataContext, aClass, aMember);
|
||||
}
|
||||
|
||||
private void invokeImpl(Project project, DataContext dataContext, GrTypeDefinition aClass, PsiElement aMember) {
|
||||
final Editor editor = dataContext != null ? PlatformDataKeys.EDITOR.getData(dataContext) : null;
|
||||
if (aClass == null) {
|
||||
String message =
|
||||
RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("is.not.supported.in.the.current.context", REFACTORING_NAME));
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ArrayList<PsiClass> bases = RefactoringHierarchyUtil.createBasesList(aClass, false, true);
|
||||
|
||||
if (bases.isEmpty()) {
|
||||
final GrTypeDefinition containingClass = DefaultGroovyMethods.asType(aClass.getContainingClass(), GrTypeDefinition.class);
|
||||
if (containingClass != null) {
|
||||
invokeImpl(project, dataContext, containingClass, aClass);
|
||||
return;
|
||||
}
|
||||
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(
|
||||
RefactoringBundle.message("class.does.not.have.base.classes.interfaces.in.current.project", aClass.getQualifiedName()));
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mySubclass = aClass;
|
||||
GrMemberInfoStorage memberInfoStorage = new GrMemberInfoStorage((GrTypeDefinition)mySubclass, new MemberInfoBase.Filter<GrMember>() {
|
||||
public boolean includeMember(GrMember element) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
List<GrMemberInfo> members = memberInfoStorage.getClassMemberInfos(mySubclass);
|
||||
PsiManager manager = mySubclass.getManager();
|
||||
|
||||
for (GrMemberInfo member : members) {
|
||||
if (manager.areElementsEquivalent(member.getMember(), aMember)) {
|
||||
member.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final GrPullUpDialog dialog = new GrPullUpDialog(project, aClass, bases, memberInfoStorage, this);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public boolean checkConflicts(final GrPullUpDialog dialog) {
|
||||
/* todo */
|
||||
List<GrMemberInfo> _infos = dialog.getSelectedMemberInfos();
|
||||
final GrMemberInfo[] infos = _infos.toArray(new GrMemberInfo[_infos.size()]);
|
||||
final PsiClass superClass = dialog.getSuperClass();
|
||||
if (!checkWritable(superClass, infos)) return false;
|
||||
final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
|
||||
public void run() {
|
||||
final PsiDirectory targetDirectory = superClass.getContainingFile().getContainingDirectory();
|
||||
final PsiPackage targetPackage = targetDirectory != null ? JavaDirectoryService.getInstance().getPackage(targetDirectory) : null;
|
||||
conflicts.putAllValues(PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, targetPackage, targetDirectory,
|
||||
dialog.getContainmentVerifier()));
|
||||
}
|
||||
}, RefactoringBundle.message("detecting.possible.conflicts"), true, myProject)) {
|
||||
return false;
|
||||
}
|
||||
if (!conflicts.isEmpty()) {
|
||||
ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts);
|
||||
conflictsDialog.show();
|
||||
final boolean ok = conflictsDialog.isOK();
|
||||
if (!ok && conflictsDialog.isShowConflicts()) dialog.close(DialogWrapper.CANCEL_EXIT_CODE);
|
||||
return ok;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkWritable(PsiClass superClass, GrMemberInfo[] infos) {
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, superClass)) return false;
|
||||
for (GrMemberInfo info : infos) {
|
||||
if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue;
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, info.getMember())) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isEnabledOnElements(PsiElement[] elements) {
|
||||
return elements.length == 1 && elements[0] instanceof PsiClass;
|
||||
}
|
||||
}
|
||||
+711
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.memberPullUp;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.intention.AddAnnotationFix;
|
||||
import com.intellij.lang.findUsages.DescriptiveNameUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.listeners.JavaRefactoringListenerManager;
|
||||
import com.intellij.refactoring.listeners.impl.JavaRefactoringListenerManagerImpl;
|
||||
import com.intellij.refactoring.util.DocCommentPolicy;
|
||||
import com.intellij.refactoring.util.RefactoringHierarchyUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUIUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usageView.UsageViewDescriptor;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrExtendsClause;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrImplementsClause;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyChangeContextUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.classMembers.GrClassMemberReferenceVisitor;
|
||||
import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrPullUpHelper extends BaseRefactoringProcessor {
|
||||
private static final Logger LOG = Logger.getInstance(GrPullUpHelper.class);
|
||||
private static final Key<Boolean> SUPER_REF = Key.create("SUPER_REF");
|
||||
private static final Key<Boolean> THIS_REF = Key.create("THIS_REF");
|
||||
private static final Key<Boolean> PRESERVE_QUALIFIER = Key.create("PRESERVE_QUALIFIER");
|
||||
|
||||
private PsiClass mySourceClass;
|
||||
private GrTypeDefinition myTargetSuperClass;
|
||||
private GrMemberInfo[] myMembersToMove;
|
||||
private DocCommentPolicy myDocCommentPolicy;
|
||||
private Set<PsiMember> myMembersAfterMove;
|
||||
|
||||
|
||||
public GrPullUpHelper(PsiClass aClass, PsiClass superClass, GrMemberInfo[] infos, DocCommentPolicy policy) {
|
||||
super(aClass.getProject());
|
||||
|
||||
mySourceClass = aClass;
|
||||
myTargetSuperClass = (GrTypeDefinition)superClass;
|
||||
myMembersToMove = infos;
|
||||
myDocCommentPolicy = policy;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
|
||||
return new UsageViewDescriptor() {
|
||||
public String getProcessedElementsHeader() {
|
||||
return "Pull up members from";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement[] getElements() {
|
||||
return new PsiClass[]{mySourceClass};
|
||||
}
|
||||
|
||||
public String getCodeReferencesText(int usagesCount, int filesCount) {
|
||||
return "Class to pull up members to \"" + RefactoringUIUtil.getDescription(myTargetSuperClass, true) + "\"";
|
||||
}
|
||||
|
||||
public String getCommentReferencesText(int usagesCount, int filesCount) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performRefactoring(UsageInfo[] usages) {
|
||||
moveMembersToBase();
|
||||
//moveFieldInitializations(); todo
|
||||
for (UsageInfo usage : usages) {
|
||||
PsiElement element = usage.getElement();
|
||||
if (element instanceof GrReferenceExpression) {
|
||||
GrExpression qualifier = ((GrReferenceExpression)element).getQualifier();
|
||||
if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve().equals(mySourceClass)) {
|
||||
((GrReferenceExpression)qualifier).bindToElement(myTargetSuperClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
todo
|
||||
ApplicationManager.application.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
processMethodsDuplicates();
|
||||
}
|
||||
}, ModalityState.NON_MODAL, myProject.getDisposed());*/
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCommandName() {
|
||||
return RefactoringBundle.message("pullUp.command", DescriptiveNameUtil.getDescriptiveName(mySourceClass));
|
||||
}
|
||||
|
||||
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(movedMembers, substitutor, info);
|
||||
}
|
||||
else if (info.getMember() instanceof GrField) {
|
||||
doMoveField(movedMembers, substitutor, info);
|
||||
}
|
||||
else if (info.getMember() instanceof PsiClass) {
|
||||
doMoveClass(movedMembers, 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);
|
||||
}
|
||||
}
|
||||
|
||||
private PsiSubstitutor upDownSuperClassSubstitutor() {
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(mySourceClass)) {
|
||||
substitutor = substitutor.put(parameter, null);
|
||||
}
|
||||
|
||||
final Map<PsiTypeParameter, PsiType> substitutionMap =
|
||||
TypeConversionUtil.getSuperClassSubstitutor(myTargetSuperClass, mySourceClass, PsiSubstitutor.EMPTY).getSubstitutionMap();
|
||||
for (PsiTypeParameter parameter : substitutionMap.keySet()) {
|
||||
final PsiType type = substitutionMap.get(parameter);
|
||||
final PsiClass resolvedClass = PsiUtil.resolveClassInType(type);
|
||||
if (resolvedClass instanceof PsiTypeParameter) {
|
||||
substitutor = substitutor.put((PsiTypeParameter)resolvedClass, JavaPsiFacade.getElementFactory(myProject).createType(parameter));
|
||||
}
|
||||
}
|
||||
|
||||
return substitutor;
|
||||
}
|
||||
|
||||
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 static boolean willBeUsedInSubclass(PsiElement member, Set<PsiMember> movedMembers, PsiClass superclass, PsiClass subclass) {
|
||||
for (PsiReference ref : ReferencesSearch.search(member, new LocalSearchScope(subclass), false)) {
|
||||
PsiElement element = ref.getElement();
|
||||
if (!RefactoringHierarchyUtil.willBeInTargetClass(element, movedMembers, superclass, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void doMoveMethod(Set<PsiMember> movedMembers, 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);
|
||||
replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
|
||||
|
||||
myDocCommentPolicy.processCopiedJavaDoc(methodCopy.getDocComment(), method.getDocComment(), isOriginalMethodAbstract);
|
||||
|
||||
final PsiMember movedElement =
|
||||
anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)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());
|
||||
}
|
||||
}
|
||||
|
||||
if (!PsiUtil.isLanguageLevel6OrHigher(mySourceClass) && myTargetSuperClass.isInterface()) {
|
||||
if (isOriginalMethodAbstract) {
|
||||
for (PsiMethod oMethod : OverridingMethodsSearch.search(method)) {
|
||||
deleteOverrideAnnotationIfFound(oMethod);
|
||||
}
|
||||
}
|
||||
|
||||
deleteOverrideAnnotationIfFound(method);
|
||||
}
|
||||
|
||||
myMembersAfterMove.add(movedElement);
|
||||
if (isOriginalMethodAbstract) {
|
||||
method.delete();
|
||||
}
|
||||
}
|
||||
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);
|
||||
if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
superClassMethod.replace(methodCopy);
|
||||
}
|
||||
else {
|
||||
final PsiMember movedElement =
|
||||
anchor != null ? (PsiMember)myTargetSuperClass.addBefore(methodCopy, anchor) : (PsiMember)myTargetSuperClass.add(methodCopy);
|
||||
myMembersAfterMove.add(movedElement);
|
||||
}
|
||||
|
||||
method.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private static void deleteOverrideAnnotationIfFound(PsiMethod oMethod) {
|
||||
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(oMethod, CommonClassNames.JAVA_LANG_OVERRIDE);
|
||||
if (annotation != null) {
|
||||
annotation.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static void replaceMovedMemberTypeParameters(final PsiElement member,
|
||||
final Iterable<PsiTypeParameter> parametersIterable,
|
||||
final PsiSubstitutor substitutor,
|
||||
final GroovyPsiElementFactory factory) {
|
||||
final Map<PsiElement, PsiElement> replacement = new LinkedHashMap<PsiElement, PsiElement>();
|
||||
for (PsiTypeParameter parameter : parametersIterable) {
|
||||
PsiType substitutedType = substitutor.substitute(parameter);
|
||||
if (substitutedType == null) {
|
||||
substitutedType = TypeConversionUtil.erasure(factory.createType(parameter));
|
||||
}
|
||||
|
||||
PsiElement scopeElement = member instanceof GrField ? member.getParent() : member;
|
||||
for (PsiReference reference : ReferencesSearch.search(parameter, new LocalSearchScope(scopeElement))) {
|
||||
final PsiElement element = reference.getElement();
|
||||
final PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiTypeElement) {
|
||||
replacement.put(parent, factory.createTypeElement(substitutedType));
|
||||
}
|
||||
else if (element instanceof GrCodeReferenceElement && substitutedType instanceof PsiClassType) {
|
||||
replacement.put(element, factory.createReferenceElementByType((PsiClassType)substitutedType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (PsiElement element : replacement.keySet()) {
|
||||
if (element.isValid()) {
|
||||
element.replace(replacement.get(element));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fixReferencesToStatic(GroovyPsiElement classMember, Set<PsiMember> movedMembers) throws IncorrectOperationException {
|
||||
final StaticReferencesCollector collector = new StaticReferencesCollector(movedMembers);
|
||||
classMember.accept(collector);
|
||||
ArrayList<GrReferenceElement> refs = collector.getReferences();
|
||||
ArrayList<PsiElement> members = collector.getReferees();
|
||||
ArrayList<PsiClass> classes = collector.getRefereeClasses();
|
||||
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
|
||||
|
||||
for (int i = 0; i < refs.size(); i++) {
|
||||
GrReferenceElement ref = refs.get(i);
|
||||
PsiElement namedElement = members.get(i);
|
||||
PsiClass aClass = classes.get(i);
|
||||
|
||||
if (namedElement instanceof PsiNamedElement) {
|
||||
GrReferenceExpression newRef = (GrReferenceExpression)factory.createExpressionFromText("a." + ((PsiNamedElement)namedElement).getName(), null);
|
||||
GrExpression qualifier = newRef.getQualifierExpression();
|
||||
assert qualifier != null;
|
||||
qualifier = (GrExpression)qualifier.replace(factory.createReferenceExpressionFromText(aClass.getQualifiedName()));
|
||||
qualifier.putCopyableUserData(PRESERVE_QUALIFIER, ref.isQualified());
|
||||
PsiElement replaced = ref.replace(newRef);
|
||||
JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(replaced);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class StaticReferencesCollector extends GrClassMemberReferenceVisitor {
|
||||
private final ArrayList<GrReferenceElement> myReferences = new ArrayList<GrReferenceElement>();
|
||||
private final ArrayList<PsiElement> myReferees = new ArrayList<PsiElement>();
|
||||
private final ArrayList<PsiClass> myRefereeClasses = new ArrayList<PsiClass>();
|
||||
private final Set<PsiMember> myMovedMembers;
|
||||
|
||||
private StaticReferencesCollector(Set<PsiMember> movedMembers) {
|
||||
super(mySourceClass);
|
||||
myMovedMembers = movedMembers;
|
||||
}
|
||||
|
||||
public ArrayList<PsiElement> getReferees() {
|
||||
return myReferees;
|
||||
}
|
||||
|
||||
public ArrayList<PsiClass> getRefereeClasses() {
|
||||
return myRefereeClasses;
|
||||
}
|
||||
|
||||
public ArrayList<GrReferenceElement> getReferences() {
|
||||
return myReferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void visitClassMemberReferenceElement(GrMember classMember, GrReferenceElement classMemberReference) {
|
||||
if (classMember.hasModifierProperty(PsiModifier.STATIC) /*&& classMemberReference.isQualified()*/) {
|
||||
if (!myMovedMembers.contains(classMember) &&
|
||||
RefactoringHierarchyUtil.isMemberBetween(myTargetSuperClass, mySourceClass, classMember)) {
|
||||
myReferences.add(classMemberReference);
|
||||
myReferees.add(classMember);
|
||||
myRefereeClasses.add(classMember.getContainingClass());
|
||||
}
|
||||
else if (myMovedMembers.contains(classMember) || myMembersAfterMove.contains(classMember)) {
|
||||
myReferences.add(classMemberReference);
|
||||
myReferees.add(classMember);
|
||||
myRefereeClasses.add(myTargetSuperClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ExplicitSuperDeleter extends GroovyRecursiveElementVisitor {
|
||||
private final ArrayList<GrExpression> mySupersToDelete = ContainerUtil.newArrayList();
|
||||
private final ArrayList<GrReferenceExpression> mySupersToChangeToThis = ContainerUtil.newArrayList();
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(GrReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
if(org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression.getQualifierExpression())) {
|
||||
PsiElement resolved = expression.resolve();
|
||||
if (resolved == null || resolved instanceof PsiMethod && shouldFixSuper((PsiMethod) resolved)) {
|
||||
mySupersToDelete.add(expression.getQualifierExpression());
|
||||
}
|
||||
}
|
||||
else if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression)) {
|
||||
mySupersToChangeToThis.add(expression);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeDefinition(GrTypeDefinition typeDefinition) {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public void fixSupers() throws IncorrectOperationException {
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
|
||||
GrReferenceExpression thisExpression = (GrReferenceExpression) factory.createExpressionFromText("this", null);
|
||||
for (GrExpression expression : mySupersToDelete) {
|
||||
expression.delete();
|
||||
}
|
||||
|
||||
for (GrReferenceExpression superExpression : mySupersToChangeToThis) {
|
||||
superExpression.replace(thisExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class QualifiedThisSuperAdjuster extends GroovyRecursiveElementVisitor {
|
||||
@Override
|
||||
public void visitReferenceExpression(GrReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
if (expression.getCopyableUserData(SUPER_REF) != null) {
|
||||
expression.putCopyableUserData(SUPER_REF, null);
|
||||
final GrExpression qualifier = expression.getQualifier();
|
||||
if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
|
||||
try {
|
||||
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
|
||||
GrExpression newExpr = factory.createExpressionFromText(myTargetSuperClass.getName() + ".this", null);
|
||||
expression.replace(newExpr);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (expression.getCopyableUserData(THIS_REF) != null) {
|
||||
expression.putCopyableUserData(THIS_REF, null);
|
||||
final GrExpression qualifier = expression.getQualifier();
|
||||
if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
|
||||
try {
|
||||
((GrReferenceExpression)qualifier).bindToElement(myTargetSuperClass);
|
||||
GroovyChangeContextUtil.clearContextInfo(qualifier);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doMoveField(Set<PsiMember> movedMembers, 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);
|
||||
field.delete();
|
||||
}
|
||||
|
||||
private void doMoveClass(Set<PsiMember> movedMembers, 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);
|
||||
//CodeStyleManager.getInstance(myProject).reformat(referenceList);
|
||||
//myTargetSuperClass.getNode().addLeaf(TokenType.WHITE_SPACE, " ", referenceList.getNode());
|
||||
}
|
||||
}
|
||||
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);
|
||||
//CodeStyleManager.getInstance(myProject).reformat(referenceList);
|
||||
//myTargetSuperClass.getNode().addLeaf(TokenType.WHITE_SPACE, " ", referenceList.getNode());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
aClass.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static GrCodeReferenceElement findReferenceToClass(GrReferenceList refList, PsiClass aClass) {
|
||||
GrCodeReferenceElement[] refs = refList.getReferenceElements();
|
||||
for (GrCodeReferenceElement ref : refs) {
|
||||
if (ref.isReferenceTo(aClass)) {
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* removes a reference to the specified class from the reference list given
|
||||
*
|
||||
* @return if removed - a reference to the class or null if there were no references to this class in the reference list
|
||||
*/
|
||||
public static GrCodeReferenceElement removeFromReferenceList(GrReferenceList refList, PsiClass aClass)
|
||||
throws IncorrectOperationException {
|
||||
GrCodeReferenceElement[] refs = refList.getReferenceElements();
|
||||
for (GrCodeReferenceElement ref : refs) {
|
||||
if (ref.isReferenceTo(aClass)) {
|
||||
GrCodeReferenceElement refCopy = (GrCodeReferenceElement)ref.copy();
|
||||
ref.delete();
|
||||
return refCopy;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class QualifiedThisSuperSearcher extends GroovyRecursiveElementVisitor {
|
||||
@Override
|
||||
public void visitReferenceExpression(GrReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression)) {
|
||||
final GrExpression qualifier = expression.getQualifier();
|
||||
if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
|
||||
try {
|
||||
expression.putCopyableUserData(SUPER_REF, Boolean.TRUE);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isThisReference(expression)) {
|
||||
final GrExpression qualifier = expression.getQualifier();
|
||||
if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).isReferenceTo(mySourceClass)) {
|
||||
try {
|
||||
expression.putCopyableUserData(THIS_REF, Boolean.TRUE);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+243
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.memberPullUp
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.refactoring.listeners.JavaRefactoringListenerManager
|
||||
import com.intellij.refactoring.listeners.MoveMemberListener
|
||||
import com.intellij.refactoring.util.DocCommentPolicy
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import junit.framework.Assert
|
||||
import org.jetbrains.plugins.groovy.LightGroovyTestCase
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember
|
||||
import org.jetbrains.plugins.groovy.refactoring.classMembers.GrMemberInfo
|
||||
import org.jetbrains.plugins.groovy.util.TestUtils
|
||||
/**
|
||||
* Created by Max Medvedev on 8/17/13
|
||||
*/
|
||||
class GrPullUpTest extends LightGroovyTestCase {
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
TestUtils.testDataPath + 'refactoring/pullUp'
|
||||
}
|
||||
|
||||
public void testQualifiedThis() {
|
||||
doTest(new MemberDescriptor("Inner", PsiClass));
|
||||
}
|
||||
|
||||
public void testQualifiedSuper() {
|
||||
doTest(new MemberDescriptor("Inner", PsiClass));
|
||||
}
|
||||
|
||||
public void testQualifiedReference() { // IDEADEV-25008
|
||||
doTest(new MemberDescriptor("x", PsiField),
|
||||
new MemberDescriptor("getX", PsiMethod),
|
||||
new MemberDescriptor("setX", PsiMethod));
|
||||
}
|
||||
|
||||
public void testPullUpInheritedStaticClasses() {
|
||||
doTest(new MemberDescriptor("C", PsiClass),
|
||||
new MemberDescriptor("D", PsiClass));
|
||||
}
|
||||
|
||||
public void testPullUpPrivateInnerClassWithPrivateConstructor() {
|
||||
doTest(new MemberDescriptor("C", PsiClass));
|
||||
}
|
||||
|
||||
public void testPullUpAndMakeAbstract() {
|
||||
doTest(new MemberDescriptor("a", PsiMethod),
|
||||
new MemberDescriptor("b", PsiMethod, true));
|
||||
}
|
||||
|
||||
public void _testTryCatchFieldInitializer() {
|
||||
doTest(new MemberDescriptor("field", PsiField));
|
||||
}
|
||||
|
||||
public void testIfFieldInitializationWithNonMovedField() {
|
||||
doTest(new MemberDescriptor("f", PsiField));
|
||||
}
|
||||
|
||||
public void _testIfFieldMovedInitialization() {
|
||||
doTest(new MemberDescriptor("f", PsiField));
|
||||
}
|
||||
|
||||
public void _testMultipleConstructorsFieldInitialization() {
|
||||
doTest(new MemberDescriptor("f", PsiField));
|
||||
}
|
||||
|
||||
public void _testMultipleConstructorsFieldInitializationNoGood() {
|
||||
doTest(new MemberDescriptor("f", PsiField));
|
||||
}
|
||||
|
||||
public void _testRemoveOverride() {
|
||||
doTest(new MemberDescriptor("get", PsiMethod));
|
||||
}
|
||||
|
||||
public void testTypeParamErasure() {
|
||||
doTest(new MemberDescriptor("f", PsiField));
|
||||
}
|
||||
|
||||
public void testTypeParamSubst() {
|
||||
doTest(new MemberDescriptor("f", PsiField));
|
||||
}
|
||||
|
||||
public void testTypeArgument() {
|
||||
doTest(new MemberDescriptor("f", PsiField));
|
||||
}
|
||||
|
||||
public void testGenericsInAbstractMethod() {
|
||||
doTest(new MemberDescriptor("method", PsiMethod, true));
|
||||
}
|
||||
|
||||
public void _testReplaceDuplicatesInInheritors() {
|
||||
doTest(new MemberDescriptor("foo", PsiMethod, false));
|
||||
}
|
||||
|
||||
public void testGenericsInImplements() {
|
||||
doTest(false, new MemberDescriptor("I", PsiClass));
|
||||
}
|
||||
|
||||
public void testUpdateStaticRefs() {
|
||||
doTest(false, new MemberDescriptor("foo", PsiMethod));
|
||||
}
|
||||
|
||||
public void testRemoveOverrideFromPulledMethod() {
|
||||
doTest(false, new MemberDescriptor("foo", PsiMethod));
|
||||
}
|
||||
|
||||
public void testPreserveOverrideInPulledMethod() {
|
||||
doTest(false, new MemberDescriptor("foo", PsiMethod));
|
||||
}
|
||||
|
||||
public void testMergeInterfaces() {
|
||||
doTest(false, new MemberDescriptor("I", PsiClass));
|
||||
}
|
||||
|
||||
public void testTypeParamsConflictingNames() {
|
||||
doTest(false, new MemberDescriptor("foo", PsiMethod));
|
||||
}
|
||||
|
||||
public void testEscalateVisibility() {
|
||||
doTest(false, new MemberDescriptor("foo", PsiMethod));
|
||||
}
|
||||
|
||||
public void testExtensionMethod() {
|
||||
doTest(false, new MemberDescriptor("foo", PsiMethod));
|
||||
}
|
||||
|
||||
public void testPreserveOverride() {
|
||||
doTest(false, new MemberDescriptor("foo", PsiMethod));
|
||||
}
|
||||
|
||||
private void doTest(MemberDescriptor... membersToFind) {
|
||||
doTest(true, membersToFind);
|
||||
}
|
||||
|
||||
private void doTest(final boolean checkMembersMovedCount, MemberDescriptor... membersToFind) {
|
||||
myFixture.configureByFile(getTestName(false) + ".groovy");
|
||||
PsiElement elementAt = myFixture.getFile().findElementAt(myFixture.getEditor().getCaretModel().getOffset());
|
||||
final PsiClass sourceClass = PsiTreeUtil.getParentOfType(elementAt, PsiClass);
|
||||
assertNotNull(sourceClass);
|
||||
|
||||
PsiClass targetClass = sourceClass.getSuperClass();
|
||||
assertNotNull(targetClass);
|
||||
if (!targetClass.isWritable()) {
|
||||
final PsiClass[] interfaces = sourceClass.getInterfaces();
|
||||
assertEquals(1, interfaces.length);
|
||||
assertTrue(interfaces[0].isWritable());
|
||||
targetClass = interfaces[0];
|
||||
}
|
||||
GrMemberInfo[] infos = findMembers(sourceClass, membersToFind);
|
||||
|
||||
final int[] countMoved = [0];
|
||||
final MoveMemberListener listener = new MoveMemberListener() {
|
||||
@Override
|
||||
public void memberMoved(PsiClass aClass, PsiMember member) {
|
||||
assertEquals(sourceClass, aClass);
|
||||
countMoved[0]++;
|
||||
}
|
||||
};
|
||||
JavaRefactoringListenerManager.getInstance(getProject()).addMoveMembersListener(listener);
|
||||
final GrPullUpHelper helper = new GrPullUpHelper(sourceClass, targetClass, infos, new DocCommentPolicy(DocCommentPolicy.ASIS));
|
||||
helper.run();
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
JavaRefactoringListenerManager.getInstance(getProject()).removeMoveMembersListener(listener);
|
||||
if (checkMembersMovedCount) {
|
||||
assertEquals(countMoved[0], membersToFind.length);
|
||||
}
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.groovy");
|
||||
}
|
||||
|
||||
public static class MemberDescriptor {
|
||||
private String myName;
|
||||
private Class<? extends PsiMember> myClass;
|
||||
private boolean myAbstract;
|
||||
|
||||
public MemberDescriptor(String name, Class<? extends PsiMember> aClass, boolean isAbstract) {
|
||||
myName = name;
|
||||
myClass = aClass;
|
||||
myAbstract = isAbstract;
|
||||
}
|
||||
|
||||
|
||||
public MemberDescriptor(String name, Class<? extends PsiMember> aClass) {
|
||||
this(name, aClass, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static GrMemberInfo[] findMembers(final PsiClass sourceClass, final MemberDescriptor... membersToFind) {
|
||||
GrMemberInfo[] infos = new GrMemberInfo[membersToFind.length]
|
||||
for (int i = 0; i < membersToFind.length; i++) {
|
||||
final Class<? extends PsiMember> clazz = membersToFind[i].myClass
|
||||
final String name = membersToFind[i].myName
|
||||
PsiMember member = null
|
||||
boolean overrides = false
|
||||
GrReferenceList refList = null
|
||||
if (PsiClass.isAssignableFrom(clazz)) {
|
||||
member = sourceClass.findInnerClassByName(name, false)
|
||||
if (member == null) {
|
||||
final PsiClass[] supers = sourceClass.getSupers()
|
||||
for (PsiClass superTypeClass : supers) {
|
||||
if (superTypeClass.getName().equals(name)) {
|
||||
member = superTypeClass
|
||||
overrides = true
|
||||
refList = superTypeClass.isInterface() ?
|
||||
(sourceClass as GrTypeDefinition).getImplementsClause() :
|
||||
(sourceClass as GrTypeDefinition).getExtendsClause()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (PsiMethod.class.isAssignableFrom(clazz)) {
|
||||
final PsiMethod[] methods = sourceClass.findMethodsByName(name, false)
|
||||
Assert.assertEquals(1, methods.length)
|
||||
member = methods[0]
|
||||
} else if (PsiField.class.isAssignableFrom(clazz)) {
|
||||
member = sourceClass.findFieldByName(name, false)
|
||||
}
|
||||
|
||||
assertNotNull(member)
|
||||
assertInstanceOf(member, GrMember)
|
||||
infos[i] = new GrMemberInfo(member as GrMember, overrides, refList)
|
||||
infos[i].setToAbstract(membersToFind[i].myAbstract)
|
||||
}
|
||||
return infos
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class Foo {
|
||||
|
||||
}
|
||||
|
||||
class FooImpl extends Foo {
|
||||
private void fo<caret>o(){}
|
||||
void bar() {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class Foo {
|
||||
|
||||
protected void foo(){}
|
||||
}
|
||||
|
||||
class FooImpl extends Foo {
|
||||
void bar() {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
interface Base {
|
||||
}
|
||||
|
||||
interface I2 extends Base {
|
||||
default void foo<caret>() {
|
||||
System.out.println("Hi there.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
interface Base {
|
||||
default void foo() {
|
||||
System.out.println("Hi there.");
|
||||
}
|
||||
}
|
||||
|
||||
interface I2 extends Base {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public abstract class Parent<S> {}
|
||||
|
||||
class Child<T> extends Parent<T> {
|
||||
void <caret>method(T t){}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public abstract class Parent<S> {
|
||||
abstract void method(S t)
|
||||
}
|
||||
|
||||
class Child<T> extends Parent<T> {
|
||||
@Override
|
||||
void method(T t){}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
public class Parent<S> {}
|
||||
|
||||
interface I<IT> {
|
||||
void method(IT t);
|
||||
}
|
||||
|
||||
class Child<T> extends Parent<T> implements I<T>{
|
||||
<caret>
|
||||
public void method(T t){}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
public class Parent<S> implements I<S> {}
|
||||
|
||||
interface I<IT> {
|
||||
void method(IT t);
|
||||
}
|
||||
|
||||
class Child<T> extends Parent<T> {
|
||||
|
||||
public void method(T t){}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
public class A {
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
final String <caret>f;
|
||||
final String foo;
|
||||
|
||||
B(String fi, String foo) {
|
||||
this.foo = foo;
|
||||
if (fi == this.foo) {
|
||||
f = foo;
|
||||
} else {
|
||||
f = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
public class A {
|
||||
protected final String f
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
final String foo;
|
||||
|
||||
B(String fi, String foo) {
|
||||
this.foo = foo;
|
||||
if (fi == this.foo) {
|
||||
f = foo;
|
||||
} else {
|
||||
f = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
public class A {
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
final String <caret>f;
|
||||
final String foo;
|
||||
|
||||
B(String fi, String foo) {
|
||||
this.foo = foo;
|
||||
if (fi == foo) {
|
||||
f = foo;
|
||||
} else {
|
||||
f = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
public class A {
|
||||
final String f;
|
||||
|
||||
public A(String fi, String foo) {
|
||||
if (fi == foo) {
|
||||
f = foo;
|
||||
} else {
|
||||
f = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
final String foo;
|
||||
|
||||
B(String fi, String foo) {
|
||||
super(fi, foo);
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class Base implements I<String> {}
|
||||
class Te<caret>st extends Base implements I<String> {}
|
||||
interface I<T>{}
|
||||
@@ -0,0 +1,3 @@
|
||||
class Base implements I<String> {}
|
||||
class Test extends Base {}
|
||||
interface I<T>{}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
public class A {
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
final String <caret>f;
|
||||
final String foo;
|
||||
|
||||
B(String fi, String foo) {
|
||||
this.foo = foo;
|
||||
f = "";
|
||||
}
|
||||
|
||||
B(String foo) {
|
||||
this.foo = foo;
|
||||
f = "";
|
||||
}
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
public class A {
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
final String <caret>f;
|
||||
final String foo;
|
||||
|
||||
B(String fi, String foo) {
|
||||
this.foo = foo;
|
||||
if (fi == this.foo) {
|
||||
f = foo;
|
||||
} else {
|
||||
f = "";
|
||||
}
|
||||
}
|
||||
|
||||
B(String f) {
|
||||
this.f = f;
|
||||
foo = "";
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
public class A {
|
||||
final String f;
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
final String foo;
|
||||
|
||||
B(String fi, String foo) {
|
||||
this.foo = foo;
|
||||
if (fi == this.foo) {
|
||||
f = foo;
|
||||
} else {
|
||||
f = "";
|
||||
}
|
||||
}
|
||||
|
||||
B(String f) {
|
||||
this.f = f;
|
||||
foo = "";
|
||||
}
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
public class A {
|
||||
final String f;
|
||||
|
||||
public A() {
|
||||
f = "";
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
final String foo;
|
||||
|
||||
B(String fi, String foo) {
|
||||
super();
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
B(String foo) {
|
||||
super();
|
||||
this.foo = foo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
abstract class Bazz {
|
||||
public abstract void foo();
|
||||
}
|
||||
|
||||
abstract class Foo extends Bazz {}
|
||||
|
||||
class Bar extends Foo {
|
||||
@Override
|
||||
public void f<caret>oo() {
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
public class Test {
|
||||
abstract class Base extends IntImpl {
|
||||
@Override
|
||||
public abstract String<caret> foo();
|
||||
}
|
||||
|
||||
class IntImpl extends Int {}
|
||||
|
||||
class Int {
|
||||
public abstract String foo();
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
public class Test {
|
||||
abstract class Base extends IntImpl {
|
||||
}
|
||||
|
||||
abstract class IntImpl extends Int {
|
||||
@Override
|
||||
public abstract String foo();
|
||||
}
|
||||
|
||||
class Int {
|
||||
public abstract String foo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
abstract class Bazz {
|
||||
public abstract void foo();
|
||||
}
|
||||
|
||||
abstract class Foo extends Bazz {
|
||||
@Override
|
||||
public void foo() {
|
||||
}
|
||||
}
|
||||
|
||||
class Bar extends Foo {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
public class A2 {
|
||||
}
|
||||
|
||||
class B2 extends A2 {
|
||||
public void <caret>a() {
|
||||
b();
|
||||
}
|
||||
|
||||
private void b() {
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
public abstract class A2 {
|
||||
public void a() {
|
||||
b();
|
||||
}
|
||||
|
||||
protected abstract void b()
|
||||
}
|
||||
|
||||
class B2 extends A2 {
|
||||
|
||||
@Override
|
||||
protected void b() {
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public class A extends AA {
|
||||
<caret>
|
||||
static class C extends D {}
|
||||
static class D extends B {}
|
||||
static class B {}
|
||||
}
|
||||
|
||||
class AA {}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
public class A extends AA {
|
||||
|
||||
static class B {}
|
||||
}
|
||||
|
||||
class AA {
|
||||
static class C extends D {}
|
||||
|
||||
static class D extends A.B {}
|
||||
}
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
public class B extends A {
|
||||
private void f(){
|
||||
new C();
|
||||
}
|
||||
<caret>
|
||||
private static class C{
|
||||
private C(){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//A.java
|
||||
class A {
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
public class B extends A {
|
||||
private void f(){
|
||||
new C();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//A.java
|
||||
class A {
|
||||
protected static class C{
|
||||
protected C(){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class X {}
|
||||
|
||||
class <caret>Y extends X {
|
||||
private static int x = 0;
|
||||
|
||||
public static int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public static void setX(int x) {
|
||||
Y.x = x;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
class X {
|
||||
private static int x = 0
|
||||
|
||||
public static int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public static void setX(int x) {
|
||||
X.x = x;
|
||||
}
|
||||
}
|
||||
|
||||
class Y extends X {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class <caret>QualifiedSuper extends Base {
|
||||
class Inner {
|
||||
void goo() {
|
||||
QualifiedSuper.super.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Base {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class QualifiedSuper extends Base {
|
||||
}
|
||||
|
||||
class Base {
|
||||
|
||||
|
||||
class Inner {
|
||||
void goo() {
|
||||
Base.this.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
class Base {
|
||||
void foo() {
|
||||
}
|
||||
}
|
||||
|
||||
public class <caret>QualifiedThis extends Base {
|
||||
void foo() {
|
||||
}
|
||||
|
||||
class Inner {
|
||||
void bar() {
|
||||
QualifiedThis.this.foo();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
class Base {
|
||||
void foo() {
|
||||
}
|
||||
|
||||
class Inner {
|
||||
void bar() {
|
||||
Base.this.foo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class QualifiedThis extends Base {
|
||||
void foo() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
public class Test {
|
||||
class Impl extends Base {
|
||||
@Override
|
||||
public String get() {
|
||||
return "239";
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Base implements Int {
|
||||
public abstract String <caret>get();
|
||||
|
||||
}
|
||||
|
||||
interface Int {
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public class Test {
|
||||
abstract class Base extends Int {
|
||||
@Override
|
||||
public abstract String<caret> foo();
|
||||
}
|
||||
|
||||
class Int {
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public class Test {
|
||||
abstract class Base extends Int {
|
||||
}
|
||||
|
||||
abstract class Int {
|
||||
public abstract String foo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
public class Test {
|
||||
class Impl extends Base {
|
||||
public String get() {
|
||||
return "239";
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Base implements Int {
|
||||
|
||||
}
|
||||
|
||||
interface Int {
|
||||
String get();
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
class A {}
|
||||
class AImpl1 extends A{
|
||||
void f<caret>oo() {
|
||||
System.out.println("hello");
|
||||
System.out.println("hello");
|
||||
System.out.println("hello");
|
||||
System.out.println("hello");
|
||||
}
|
||||
}
|
||||
|
||||
class AImpl2 extends A {
|
||||
void bar() {
|
||||
System.out.println("hello");
|
||||
System.out.println("hello");
|
||||
System.out.println("hello");
|
||||
System.out.println("hello");
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
class A {
|
||||
void foo() {
|
||||
System.out.println("hello");
|
||||
System.out.println("hello");
|
||||
System.out.println("hello");
|
||||
System.out.println("hello");
|
||||
}
|
||||
}
|
||||
class AImpl1 extends A{
|
||||
}
|
||||
|
||||
class AImpl2 extends A {
|
||||
void bar() {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
public class Sup {
|
||||
|
||||
}
|
||||
|
||||
class ExtractSuperClass extends Sup {
|
||||
|
||||
private final String <caret>field;
|
||||
|
||||
public ExtractSuperClass() {
|
||||
|
||||
|
||||
try {
|
||||
field = (String)"text";
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
public class Sup {
|
||||
|
||||
protected final String field
|
||||
|
||||
public Sup() {
|
||||
try {
|
||||
field = (String)"text";
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ExtractSuperClass extends Sup {
|
||||
|
||||
public ExtractSuperClass() {
|
||||
super();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public class Parent<S> {}
|
||||
|
||||
class Child extends Parent<String> {
|
||||
String <caret>f;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
public class Parent<S> {
|
||||
String f
|
||||
}
|
||||
|
||||
class Child extends Parent<String> {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public class Parent {}
|
||||
|
||||
class Child<T> extends Parent {
|
||||
T <caret>f;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
public class Parent {
|
||||
Object f
|
||||
}
|
||||
|
||||
class Child<T> extends Parent {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public class Parent<S> {}
|
||||
|
||||
class Child<T> extends Parent<T> {
|
||||
T <caret>f;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
public class Parent<S> {
|
||||
S f
|
||||
}
|
||||
|
||||
class Child<T> extends Parent<T> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
interface Bar<T> { }
|
||||
|
||||
interface Base<T> { }
|
||||
|
||||
class Foo<T,U> implements Base<U> {
|
||||
void fo<caret>o(Bar<U> bar) { }
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
interface Bar<T> { }
|
||||
|
||||
interface Base<T> {
|
||||
void foo(Bar<T> bar);
|
||||
}
|
||||
|
||||
class Foo<T,U> implements Base<U> {
|
||||
@Override
|
||||
public void foo(Bar<U> bar) { }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class Foo {}
|
||||
class FooImpl extends Foo {
|
||||
public static void foo(){}
|
||||
<caret>
|
||||
}
|
||||
class U {
|
||||
public static void main(String[] args) {
|
||||
FooImpl.foo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class Foo {
|
||||
public static void foo(){}
|
||||
}
|
||||
class FooImpl extends Foo {
|
||||
|
||||
}
|
||||
class U {
|
||||
public static void main(String[] args) {
|
||||
Foo.foo();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user