aboutsummaryrefslogtreecommitdiffstats
path: root/org.aspectj.ajdt.core
diff options
context:
space:
mode:
authoraclement <aclement>2005-08-23 14:02:30 +0000
committeraclement <aclement>2005-08-23 14:02:30 +0000
commit284c4eed6b80ac368ca60c2f9eb7aff1234bf2a8 (patch)
tree0953fe63aa97f0b16f8358ed0f3eee18bfb5db13 /org.aspectj.ajdt.core
parent4aacf20ad0fd3f3782fe1ff936aa13f666431beb (diff)
downloadaspectj-284c4eed6b80ac368ca60c2f9eb7aff1234bf2a8.tar.gz
aspectj-284c4eed6b80ac368ca60c2f9eb7aff1234bf2a8.zip
@override support for ITDs. Plus some binary weaving generic ITD tests.
Diffstat (limited to 'org.aspectj.ajdt.core')
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java44
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java59
2 files changed, 103 insertions, 0 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java
index cac14243d..80271fbdf 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java
@@ -17,6 +17,7 @@ import java.lang.reflect.Modifier;
import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
import org.aspectj.ajdt.internal.compiler.lookup.EclipseTypeMunger;
+import org.aspectj.ajdt.internal.compiler.problem.AjProblemReporter;
import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
@@ -26,6 +27,8 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.aspectj.org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
import org.aspectj.org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
@@ -83,6 +86,8 @@ public class InterTypeMethodDeclaration extends InterTypeDeclaration {
super.resolve(upperScope);
}
+
+
public void resolveStatements() {
if ((modifiers & AccSemicolonBody) != 0) {
if ((declaredModifiers & AccAbstract) == 0)
@@ -93,6 +98,45 @@ public class InterTypeMethodDeclaration extends InterTypeDeclaration {
scope.problemReporter().methodNeedingNoBody(this);
}
+ // check @Override annotation - based on MethodDeclaration.resolveStatements() @Override processing
+ checkOverride: {
+ if (this.binding == null) break checkOverride;
+ if (this.scope.compilerOptions().sourceLevel < JDK1_5) break checkOverride;
+ int bindingModifiers = this.binding.modifiers;
+ boolean hasOverrideAnnotation = (this.binding.tagBits & TagBits.AnnotationOverride) != 0;
+
+ // Need to verify
+ if (hasOverrideAnnotation) {
+
+ // Work out the real method binding that we can use for comparison
+ EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(scope);
+ MethodBinding realthing = world.makeMethodBinding(munger.getSignature());
+
+ boolean reportError = true;
+ // Go up the hierarchy, looking for something we override
+ ReferenceBinding supertype = onTypeBinding.superclass();
+ while (supertype!=null && reportError) {
+ MethodBinding[] possibles = supertype.getMethods(declaredSelector);
+ for (int i = 0; i < possibles.length; i++) {
+ MethodBinding mb = possibles[i];
+
+ boolean couldBeMatch = true;
+ if (mb.parameters.length!=realthing.parameters.length) couldBeMatch=false;
+ else {
+ for (int j = 0; j < mb.parameters.length && couldBeMatch; j++) {
+ if (!mb.parameters[j].equals(realthing.parameters[j])) couldBeMatch=false;
+ }
+ }
+ // return types compatible? (allow for covariance)
+ if (couldBeMatch && !returnType.resolvedType.isCompatibleWith(mb.returnType)) couldBeMatch=false;
+ if (couldBeMatch) reportError = false;
+ }
+ supertype = supertype.superclass(); // superclass of object is null
+ }
+ // If we couldn't find something we override, report the error
+ if (reportError) ((AjProblemReporter)this.scope.problemReporter()).itdMethodMustOverride(this,realthing);
+ }
+ }
if (!Modifier.isAbstract(declaredModifiers)) super.resolveStatements();
if (Modifier.isStatic(declaredModifiers)) {
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java
index bd3783b0a..7a7f54318 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java
@@ -31,6 +31,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.aspectj.org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
@@ -313,5 +314,63 @@ public class AjProblemReporter extends ProblemReporter {
methodDecl.sourceEnd,this.referenceContext,
this.referenceContext == null ? null : this.referenceContext.compilationResult());
}
+
+
+ /**
+ * Called when there is an ITD marked @override that doesn't override a supertypes method.
+ * The method and the binding are passed - some information is useful from each. The 'method'
+ * knows about source offsets for the message, the 'binding' has the signature of what the
+ * ITD is trying to be in the target class.
+ */
+ public void itdMethodMustOverride(AbstractMethodDeclaration method,MethodBinding binding) {
+ this.handle(
+ IProblem.MethodMustOverride,
+ new String[] {new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, false), new String(binding.declaringClass.readableName()), },
+ new String[] {new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, true), new String(binding.declaringClass.shortReadableName()),},
+ method.sourceStart,
+ method.sourceEnd,
+ this.referenceContext,
+ this.referenceContext == null ? null : this.referenceContext.compilationResult());
+ }
+
+ /**
+ * Overrides the implementation in ProblemReporter and is ITD aware.
+ * To report a *real* problem with an ITD marked @override, the other methodMustOverride() method is used.
+ */
+ public void methodMustOverride(AbstractMethodDeclaration method) {
+ MethodBinding binding = method.binding;
+
+ // ignore ajc$ methods
+ if (new String(method.selector).startsWith("ajc$")) return;
+
+ ResolvedType onTypeX = factory.fromEclipse(method.binding.declaringClass);
+ for (Iterator i = onTypeX.getInterTypeMungersIncludingSupers().iterator(); i.hasNext(); ) {
+ ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
+ ResolvedMember sig = m.getSignature();
+ if (ResolvedType.matches(AjcMemberMaker.interMethod(sig,m.getAspectType(),
+ sig.getDeclaringType().resolve(factory.getWorld()).isInterface()),
+ factory.makeResolvedMember(method.binding))) {
+ // match, so dont need to report a problem!
+ return;
+ }
+ }
+ // report the error...
+ super.methodMustOverride(method);
+ }
+
+
+ private String typesAsString(boolean isVarargs, TypeBinding[] types, boolean makeShort) {
+ StringBuffer buffer = new StringBuffer(10);
+ for (int i = 0, length = types.length; i < length; i++) {
+ if (i != 0)
+ buffer.append(", "); //$NON-NLS-1$
+ TypeBinding type = types[i];
+ boolean isVarargType = isVarargs && i == length-1;
+ if (isVarargType) type = ((ArrayBinding)type).elementsType();
+ buffer.append(new String(makeShort ? type.shortReadableName() : type.readableName()));
+ if (isVarargType) buffer.append("..."); //$NON-NLS-1$
+ }
+ return buffer.toString();
+ }
}