From 3e2801ad504e8f6b3fa7b50a42bf2706994e1727 Mon Sep 17 00:00:00 2001 From: jhugunin Date: Thu, 13 Feb 2003 21:00:35 +0000 Subject: [PATCH] fixed Bug 29959: super call in intertype method declaration body causes VerifyError --- .../ast/InterTypeConstructorDeclaration.java | 4 +- .../compiler/ast/SuperFixerVisitor.java | 12 ++++++ .../lookup/InterTypeMethodBinding.java | 39 ++++--------------- .../compiler/ast/AllocationExpression.java | 2 +- .../compiler/ast/ExplicitConstructorCall.java | 2 +- .../internal/compiler/ast/MessageSend.java | 2 +- .../compiler/lookup/MethodBinding.java | 2 +- tests/ajcTests.xml | 6 +++ tests/ajcTestsFailing.xml | 7 ++++ tests/bugs/SuperToIntro.java | 27 +++++++++++++ tests/jimTests.xml | 15 ++----- 11 files changed, 69 insertions(+), 49 deletions(-) create mode 100644 tests/bugs/SuperToIntro.java diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java index 55ddb12f6..5abe2ce07 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java @@ -110,7 +110,7 @@ public class InterTypeConstructorDeclaration extends InterTypeDeclaration { if (explicitConstructorCall != null) { explicitConstructor = explicitConstructorCall.binding; if (explicitConstructor.alwaysNeedsAccessMethod()) { - explicitConstructor = explicitConstructor.getAccessMethod(); + explicitConstructor = explicitConstructor.getAccessMethod(true); } } @@ -226,7 +226,7 @@ public class InterTypeConstructorDeclaration extends InterTypeDeclaration { if (explicitConstructorCall != null && !(explicitConstructorCall.binding instanceof ProblemMethodBinding)) { MethodBinding explicitConstructor = explicitConstructorCall.binding; if (explicitConstructor.alwaysNeedsAccessMethod()) { - explicitConstructor = explicitConstructor.getAccessMethod(); + explicitConstructor = explicitConstructor.getAccessMethod(true); } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/SuperFixerVisitor.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/SuperFixerVisitor.java index 00732e4eb..74d071b6c 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/SuperFixerVisitor.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/SuperFixerVisitor.java @@ -16,6 +16,7 @@ package org.aspectj.ajdt.internal.compiler.ast; import java.util.*; import java.util.Arrays; +import org.aspectj.ajdt.internal.compiler.lookup.*; import org.aspectj.ajdt.internal.compiler.lookup.EclipseWorld; import org.aspectj.weaver.*; import org.aspectj.weaver.ShadowMunger; @@ -49,6 +50,17 @@ public class SuperFixerVisitor extends AbstractSyntaxTreeVisitorAdapter { if (superBinding instanceof ProblemMethodBinding) { return; } + // InterTypeMethodBindings are always statically bound, so there's no + // need to treat super calls specially here + if (superBinding instanceof InterTypeMethodBinding) { + return; +// InterTypeMethodBinding m = (InterTypeMethodBinding)superBinding; +// if (m.postDispatchMethod != null) { +// call.binding = m.postDispatchMethod; +// } +// return; + } + char[] accessName; if (call.isSuperAccess() && !call.binding.isStatic()) { call.receiver = new ThisReference(); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMethodBinding.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMethodBinding.java index 18aea28e4..fac054a2d 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMethodBinding.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMethodBinding.java @@ -18,11 +18,10 @@ import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.lookup.*; public class InterTypeMethodBinding extends MethodBinding { - //private ReferenceBinding withinType; private ReferenceBinding targetType; private MethodBinding syntheticMethod; - //public MethodBinding introducedMethod; + public MethodBinding postDispatchMethod; public AbstractMethodDeclaration sourceMethod; @@ -38,42 +37,17 @@ public class InterTypeMethodBinding extends MethodBinding { if (signature.getKind() == Member.METHOD) { syntheticMethod = world.makeMethodBinding(AjcMemberMaker.interMethodDispatcher(signature, withinType)); + postDispatchMethod = + world.makeMethodBinding(AjcMemberMaker.interMethodBody(signature, withinType)); } else { syntheticMethod = world.makeMethodBinding( AjcMemberMaker.interConstructor(world.resolve(signature.getDeclaringType()), signature, withinType)); + postDispatchMethod = syntheticMethod; } } - -// -// this.declaringClass = -// -// -// -// char[] dispatch2Name; -// if (Modifier.isPublic(modifiers)) { -// dispatch2Name = name; -// } else if (Modifier.isPrivate(modifiers)) { -// dispatch2Name = -// AstUtil.makeAjcMangledName("dispatch2".toCharArray(), withinType, selector); -// } else { -// // package visible -// //??? optimize both in same package -// dispatch2Name = -// AstUtil.makeAjcMangledName("dispatch2".toCharArray(), -// withinType.qualifiedPackageName(), selector); -// } -// -// introducedMethod = -// new MethodBinding(AstUtil.makePublic(modifiers), dispatch2Name, -// type, args, exceptions, declaringClass); -// -// this.dispatchMethod = -// new DispatchMethodBinding(introducedMethod, withinType, mangledParams); -// } - //XXX this is identical to InterTypeFieldBinding public boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) { @@ -127,8 +101,9 @@ public class InterTypeMethodBinding extends MethodBinding { } - public MethodBinding getAccessMethod() { - return syntheticMethod; + public MethodBinding getAccessMethod(boolean staticReference) { + if (staticReference) return postDispatchMethod; + else return syntheticMethod; } public boolean alwaysNeedsAccessMethod() { return true; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java index 57bf85572..c8ccc2864 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java @@ -155,7 +155,7 @@ public class AllocationExpression public void manageSyntheticAccessIfNecessary(BlockScope currentScope) { if (binding.alwaysNeedsAccessMethod()) { - syntheticAccessor = binding.getAccessMethod(); + syntheticAccessor = binding.getAccessMethod(true); return; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java index 6a871d7ff..ddfb729a4 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java @@ -181,7 +181,7 @@ public class ExplicitConstructorCall public void manageSyntheticAccessIfNecessary(BlockScope currentScope) { if (binding.alwaysNeedsAccessMethod()) { - syntheticAccessor = binding.getAccessMethod(); + syntheticAccessor = binding.getAccessMethod(true); return; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java index a05394370..cd68794eb 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java @@ -142,7 +142,7 @@ public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) { } public void manageSyntheticAccessIfNecessary(BlockScope currentScope){ if (binding.alwaysNeedsAccessMethod()) { - syntheticAccessor = binding.getAccessMethod(); + syntheticAccessor = binding.getAccessMethod(isSuperAccess()); return; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java index c8e5d9979..49982a359 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java @@ -421,7 +421,7 @@ public final int sourceStart() { * This will only be called if alwaysNeedsAccessMethod() returns true. * In that case it should return the access method to be used. */ - public MethodBinding getAccessMethod() { + public MethodBinding getAccessMethod(boolean staticReference) { throw new RuntimeException("unimplemented"); } diff --git a/tests/ajcTests.xml b/tests/ajcTests.xml index 58ac77e35..1d0501dd6 100644 --- a/tests/ajcTests.xml +++ b/tests/ajcTests.xml @@ -5560,4 +5560,10 @@ + + + + + diff --git a/tests/ajcTestsFailing.xml b/tests/ajcTestsFailing.xml index dd0d78673..4bdd8def6 100644 --- a/tests/ajcTestsFailing.xml +++ b/tests/ajcTestsFailing.xml @@ -51,4 +51,11 @@ + + + + + + diff --git a/tests/bugs/SuperToIntro.java b/tests/bugs/SuperToIntro.java new file mode 100644 index 000000000..81c25bfdf --- /dev/null +++ b/tests/bugs/SuperToIntro.java @@ -0,0 +1,27 @@ +// from Bug#: 29959 +import org.aspectj.testing.Tester; + +aspect Foo { + String A.onlyA() { return "onlyA"; } + String A.foo() { return "Afoo"; } + String B.foo() { return super.foo() + ":" + onlyA() + ":" + super.getName(); } +} + +class A { + String getName() { return "A"; } +} +class B extends A { + String getName() { return "B"; } + + String onB1() { return foo() + ":" + onlyA() + ":" + getName(); } + String onB2() { return super.foo() + ":" + super.onlyA() + ":" + super.getName(); } +} + +public class SuperToIntro { + public static void main(String[] args) { + B b = new B(); + Tester.checkEqual(b.foo(), "Afoo:onlyA:A"); + Tester.checkEqual(b.onB1(), "Afoo:onlyA:A:onlyA:B"); + Tester.checkEqual(b.onB2(), "Afoo:onlyA:A"); + } +} diff --git a/tests/jimTests.xml b/tests/jimTests.xml index 23f82d378..0a867d719 100644 --- a/tests/jimTests.xml +++ b/tests/jimTests.xml @@ -1,18 +1,11 @@ - - - - + + + \ No newline at end of file -- 2.39.5