diff options
author | Stephan Herrmann | 2012-08-11 13:26:09 +0000 |
---|---|---|
committer | Stephan Herrmann | 2012-08-11 13:26:09 +0000 |
commit | bbd06a961329133604a68cfd41d482a8c7aafd26 (patch) | |
tree | bc09c50ceaaad285f5bdc7fea400c1273a75e529 /plugins | |
parent | c189f3f52c86ddf49b4243581f06f25cd5524919 (diff) | |
download | org.eclipse.objectteams-bbd06a961329133604a68cfd41d482a8c7aafd26.tar.gz org.eclipse.objectteams-bbd06a961329133604a68cfd41d482a8c7aafd26.tar.xz org.eclipse.objectteams-bbd06a961329133604a68cfd41d482a8c7aafd26.zip |
Bug 386814 - [refactoring] pull-up should distinguish callouts that can
be pull-up vs. abstract decl.
- when pullup of callout is requested, check:
- is destination type a bound role?
- is the base member accessible via the destination's base?
- also report when a base member of a referenced callout cannot be
resolved (rather than throwing NPE).
Diffstat (limited to 'plugins')
3 files changed, 70 insertions, 4 deletions
diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/RefactoringMessages.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/RefactoringMessages.java index b11b503af..4c7e00b22 100644 --- a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/RefactoringMessages.java +++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/RefactoringMessages.java @@ -19,6 +19,9 @@ public class RefactoringMessages extends NLS { public static String MoveInstanceMethodAdaptor_overloading_error; public static String PullUpAdaptor_ambiguousMethodSpec_error; public static String PullUpAdaptor_callinMethodToNonRole_error; + public static String PullUpAdaptor_calloutToNonRole_error; + public static String PullUpAdaptor_calloutToUnboundRole_error; + public static String PullUpAdaptor_calloutBaseNotBoundInDest_error; public static String PullUpAdaptor_checkOverloading_progress; public static String PullUpAdaptor_checkOverriding_progress; public static String PullUpAdaptor_checkShadowing_progress; @@ -26,6 +29,7 @@ public class RefactoringMessages extends NLS { public static String PullUpAdaptor_overloading_error; public static String PullUpAdaptor_overriding_error; public static String PullUpAdaptor_referencedByMethodBinding_error; + public static String PullUpAdaptor_referencedCalloutUnresolvedBaseMember_error; public static String PushDownAdaptor_ambiguousMethodSpec_error; public static String PushDownAdaptor_boundAsCallout_error; public static String PushDownAdaptor_boundAsCTF_error; diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/RefactoringMessages.properties b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/RefactoringMessages.properties index 8aa36611a..783f59329 100644 --- a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/RefactoringMessages.properties +++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/RefactoringMessages.properties @@ -13,6 +13,9 @@ MoveInstanceMethodAdaptor_moveInstanceMethod_name=Move Instance Method MoveInstanceMethodAdaptor_overloading_error=Moved method will be overloaded after refactoring\! PullUpAdaptor_ambiguousMethodSpec_error=Refactoring cannot be performed\! There would be an ambiguous method specifier in a method binding after moving\! PullUpAdaptor_callinMethodToNonRole_error=The callin method ''{0}'' can only be moved to a role (OTJLD \uFFFD4.2.(d)). +PullUpAdaptor_calloutToNonRole_error=The callout binding ''{0}'' can only be moved to a role (OTJLD \uFFFD3.1.(a)). +PullUpAdaptor_calloutToUnboundRole_error=The callout binding ''{0}'' can only be moved to a bound role (OTJLD \uFFFD3.1.(a)). +PullUpAdaptor_calloutBaseNotBoundInDest_error=The callout binding ''{0}'' cannot be moved to class ''{1}'', because the the bound base member ''{2}'' will not be accessible after refactoring (OTJLD \uFFFD3.1.(a)). PullUpAdaptor_checkOverloading_progress=Checking Overloading PullUpAdaptor_checkOverriding_progress=Checking Overriding PullUpAdaptor_checkShadowing_progress=Checking Shadowing @@ -20,6 +23,7 @@ PullUpAdaptor_fieldShadowing_error=The pulled up field ''{0}'' would be shadowed PullUpAdaptor_overloading_error=The pulled up method ''{0}'' would be overloaded after refactoring. PullUpAdaptor_overriding_error=The pulled up method ''{0}'' would be overridden in ''{1}''. PullUpAdaptor_referencedByMethodBinding_error=Pulled up member ''{0}'' is referenced in an aspect binding by ''{1}'' +PullUpAdaptor_referencedCalloutUnresolvedBaseMember_error=Refactoring cannot be performed\! The base member of callout binding ''{0}'', which is referenced from ''{1}'', cannot be resolved. PushDownAdaptor_ambiguousMethodSpec_error=Refactoring cannot be performed\! There would be an ambiguous method specifier in a method binding after moving\! PushDownAdaptor_boundAsCallout_error=The pushed down method ''{0}'' is bound in a callout method binding in ''{1}''. PushDownAdaptor_boundAsCTF_error=The pushed down method ''{0}'' is bound in a callout to field binding in ''{1}''. diff --git a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/PullUpAdaptor.java b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/PullUpAdaptor.java index 06abc6b78..a12cff268 100644 --- a/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/PullUpAdaptor.java +++ b/plugins/org.eclipse.objectteams.otdt.refactoring/src/org/eclipse/objectteams/otdt/internal/refactoring/adaptor/pullup/PullUpAdaptor.java @@ -40,9 +40,12 @@ import org.eclipse.jdt.core.ITypeHierarchy; import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.CalloutMappingDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodSpec;
@@ -76,6 +79,7 @@ import org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdj import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.JdtFlags;
import org.eclipse.jdt.internal.corext.util.SearchUtils;
+import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
@@ -90,6 +94,8 @@ import org.eclipse.objectteams.otdt.core.OTModelManager; import org.eclipse.objectteams.otdt.core.TypeHelper;
import org.eclipse.objectteams.otdt.core.hierarchy.OTTypeHierarchies;
import org.eclipse.objectteams.otdt.internal.core.AbstractCalloutMapping;
+import org.eclipse.objectteams.otdt.internal.core.CalloutMapping;
+import org.eclipse.objectteams.otdt.internal.core.CalloutToFieldMapping;
import org.eclipse.objectteams.otdt.internal.core.RoleType;
import org.eclipse.objectteams.otdt.internal.refactoring.RefactoringMessages;
import org.eclipse.objectteams.otdt.internal.refactoring.util.IAmbuguityMessageCreator;
@@ -132,7 +138,7 @@ public team class PullUpAdaptor { status.merge(checkOverloadingAndAmbiguity(pm));
status.merge(checkOverriding(pm));
if(TypeHelper.isRole(getDeclaringType().getFlags())){
- status.merge(checkDestinationForOTElements());
+ status.merge(checkDestinationForOTElements(pm));
status.merge(checkShadowingFieldInImplicitHierarchy(pm));
}
}
@@ -193,7 +199,7 @@ public team class PullUpAdaptor { }
- private RefactoringStatus checkDestinationForOTElements() throws JavaModelException {
+ private RefactoringStatus checkDestinationForOTElements(IProgressMonitor pm) throws JavaModelException {
RefactoringStatus status = new RefactoringStatus();
for (int i = 0; i < getFMembersToMove().length; i++) {
IMember element = getFMembersToMove()[i];
@@ -203,6 +209,44 @@ public team class PullUpAdaptor { if(Flags.isCallin(method.getFlags()) && !TypeHelper.isRole(getDestinationType().getFlags())){
String msg = NLS.bind(RefactoringMessages.PullUpAdaptor_callinMethodToNonRole_error, method.getElementName());
status.addFatalError(msg, JavaStatusContext.create(method));
+ } else {
+ // for callout bindings check if the base member will be accessible after refactoring:
+ IMember baseMember = null;
+ switch (element.getElementType()) {
+ case IOTJavaElement.CALLOUT_MAPPING:
+ baseMember = ((CalloutMapping)element).getBoundBaseMethod();
+ break;
+ case IOTJavaElement.CALLOUT_TO_FIELD_MAPPING:
+ baseMember = ((CalloutToFieldMapping)element).getBoundBaseField();
+ break;
+ }
+ if (baseMember != null) {
+ IType requiredBaseType = baseMember.getDeclaringType();
+ IType destinationType = getDestinationType();
+ if (!TypeHelper.isRole(destinationType.getFlags())) {
+ String msg = NLS.bind(RefactoringMessages.PullUpAdaptor_calloutToNonRole_error, method.getElementName());
+ status.addFatalError(msg, JavaStatusContext.create(method));
+ } else {
+ IRoleType roleType = (IRoleType) OTModelManager.getOTElement(destinationType);
+ IType baseClass = roleType.getBaseClass();
+ if (baseClass == null) {
+ String msg = NLS.bind(RefactoringMessages.PullUpAdaptor_calloutToUnboundRole_error, method.getElementName());
+ status.addFatalError(msg, JavaStatusContext.create(method));
+ } else {
+ IJavaElement[] elements = new IJavaElement[]{requiredBaseType, baseClass};
+ ASTParser astParser = ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
+ astParser.setProject(getDeclaringType().getJavaProject());
+ IBinding[] bindings = astParser.createBindings(elements, pm);
+ ITypeBinding requiredBaseBinding = (ITypeBinding)bindings[0];
+ ITypeBinding baseOfDestination = (ITypeBinding)bindings[1];
+ if (!baseOfDestination.isAssignmentCompatible(requiredBaseBinding)) {
+ String msg = NLS.bind(RefactoringMessages.PullUpAdaptor_calloutBaseNotBoundInDest_error,
+ new Object[]{method.getElementName(), destinationType.getElementName(), baseMember.getElementName()});
+ status.addFatalError(msg, JavaStatusContext.create(method));
+ }
+ }
+ }
+ }
}
}
}
@@ -375,13 +419,19 @@ public team class PullUpAdaptor { Object element= match.getElement();
if (element instanceof ICalloutMapping) {
ICalloutMapping mapping = (ICalloutMapping) element;
- if(mapping.getBoundBaseMethod().equals(member)){
+ IMethod boundBaseMethod = mapping.getBoundBaseMethod();
+ if (boundBaseMethod == null) {
+ addUnresolvedBaseMemberError(mapping, status, member);
+ } else if(boundBaseMethod.equals(member)){
addAspectBindingWarning(member, status, mapping);
}
}
if (element instanceof ICalloutToFieldMapping) {
ICalloutToFieldMapping mapping = (ICalloutToFieldMapping) element;
- if(mapping.getBoundBaseField().equals(member)){
+ IField boundBaseField = mapping.getBoundBaseField();
+ if (boundBaseField == null) {
+ addUnresolvedBaseMemberError(mapping, status, member);
+ } else if(boundBaseField.equals(member)){
addAspectBindingWarning(member, status, mapping);
}
}
@@ -399,6 +449,14 @@ public team class PullUpAdaptor { return status;
}
+ private void addUnresolvedBaseMemberError(IMethodMapping referencedMapping, RefactoringStatus status, IMember member)
+ {
+ status.addEntry(new RefactoringStatusEntry(RefactoringStatus.ERROR,
+ NLS.bind(RefactoringMessages.PullUpAdaptor_referencedCalloutUnresolvedBaseMember_error,
+ referencedMapping.getElementName(),
+ member.getElementName())));
+ }
+
/**
* Adds a warning to the given refactoring status that notifies the user about existing aspect bingings.
*
|