Ver código fonte

fixing declare parents problems

tags/V1_1_0_RC2
jhugunin 21 anos atrás
pai
commit
039d04d39d

+ 11
- 39
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java Ver arquivo

@@ -191,58 +191,30 @@ public class AjLookupEnvironment extends LookupEnvironment {
}

private void doDeclareParents(DeclareParents declareParents, SourceTypeBinding sourceType) {
if (declareParents.match(factory.fromEclipse(sourceType))) {
TypePatternList l = declareParents.getParents();
for (int i=0, len=l.size(); i < len; i++) {
addParent(declareParents, sourceType, l.get(i));
List newParents = declareParents.findMatchingNewParents(factory.fromEclipse(sourceType));
if (!newParents.isEmpty()) {
for (Iterator i = newParents.iterator(); i.hasNext(); ) {
ResolvedTypeX parent = (ResolvedTypeX)i.next();
addParent(sourceType, parent);
}
}
}

private void addParent(DeclareParents declareParents, SourceTypeBinding sourceType, TypePattern typePattern) {
if (typePattern == TypePattern.NO) return; // already had an error here
TypeX iType = typePattern.getExactType();
ReferenceBinding b = (ReferenceBinding)factory.makeTypeBinding(iType); //"
if (b.isClass()) {
if (sourceType.isInterface()) {
factory.showMessage(IMessage.ERROR,
"interface can not extend a class",
declareParents.getSourceLocation(), null
);
// how to handle xcutting errors???
}
if (sourceType == b || sourceType.isSuperclassOf(b)) {
factory.showMessage(IMessage.ERROR,
"class can not extend itself", declareParents.getSourceLocation(), null
);
return;
}
sourceType.superclass = b;
private void addParent(SourceTypeBinding sourceType, ResolvedTypeX parent) {
ReferenceBinding parentBinding = (ReferenceBinding)factory.makeTypeBinding(parent);
if (parentBinding.isClass()) {
sourceType.superclass = parentBinding;
} else {
//??? it's not considered an error to extend yourself, nothing happens
if (sourceType.equals(b)) {
return;
}
if (sourceType.isInterface() && b.implementsInterface(sourceType, true)) {
factory.showMessage(IMessage.ERROR,
"interface can not extend itself", declareParents.getSourceLocation(), null
);
return;
}
if (sourceType == b || b.isSuperclassOf(sourceType)) return;
ReferenceBinding[] oldI = sourceType.superInterfaces;
ReferenceBinding[] newI;
if (oldI == null) {
newI = new ReferenceBinding[1];
newI[0] = b;
newI[0] = parentBinding;
} else {
int n = oldI.length;
newI = new ReferenceBinding[n+1];
System.arraycopy(oldI, 0, newI, 0, n);
newI[n] = b;
newI[n] = parentBinding;
}
sourceType.superInterfaces = newI;
}

+ 1
- 1
org.aspectj.ajdt.core/testdata/src1/ParentsFail.java Ver arquivo

@@ -18,5 +18,5 @@ aspect A {
declare parents: C2 implements I; // CE can't implement
declare parents: C2 extends C3; // CE circular
declare parents: C1 extends C1; // CE self
declare parents: C1 extends C1; // not considered a CE, just does nothing
}

+ 1
- 1
org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CompileAndRunTestCase.java Ver arquivo

@@ -44,7 +44,7 @@ public class CompileAndRunTestCase extends CommandTestCase {
}
public void testDeclareParentsFail() throws IOException {
CommandTestCase.checkCompile("src1/ParentsFail.java", new int[] {3, 11, 19, 21});
CommandTestCase.checkCompile("src1/ParentsFail.java", new int[] {3, 11, 19});
}
public void testDeclareParents() throws IOException {

+ 22
- 0
tests/ajcTests.xml Ver arquivo

@@ -5781,5 +5781,27 @@
<run class="b_impl.BImpl"/>
</ajc-test>

<ajc-test dir="new/declareParents"
title="Declare parents with intermediate ancestor"
keywords="from-new">
<compile files="Driver.java"/>
<run class="Driver"/>
</ajc-test>
<ajc-test dir="new/declareParents"
title="Declare parents removing ancestor"
keywords="from-new">
<compile files="IllegalAdoption.java">
<message kind="error" line="13"/>
</compile>
</ajc-test>

<ajc-test dir="options/injars/simple" pr="35865"
title="options -injars checking declare parents interactions">
<compile files="DecParents.java,main.jar"
options="!eclipse"/>
<run class="DecParents"/>
</ajc-test>
</suite>

+ 1
- 14
tests/ajcTestsFailing.xml Ver arquivo

@@ -4,19 +4,6 @@
<!-- contains valid tests that the compiler has never passed -->
<suite>

<ajc-test dir="new/declareParents"
title="Declare parents with intermediate ancestor"
keywords="from-new">
<compile files="Driver.java"/>
<run class="Driver"/>
</ajc-test>
<ajc-test dir="new/declareParents"
title="Declare parents removing ancestor"
keywords="from-new">
<compile files="IllegalAdoption.java">
<message kind="error" line="13"/>
</compile>
</ajc-test>


</suite>

+ 0
- 1
tests/jimTests.xml Ver arquivo

@@ -1,7 +1,6 @@
<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd">
<suite>


<!--
<ajc-test dir="new" pr="885"

+ 23
- 0
tests/options/injars/simple/DecParents.java Ver arquivo

@@ -0,0 +1,23 @@


import org.aspectj.testing.Tester;

public aspect DecParents {
private interface I {
public abstract String doit();
}
public String I.doit() {
return "foo";
}
declare parents: Main implements I;
before(): execution(void Main.main(..)) {
}
public static void main(String[] args) {
I i = new Main();
System.out.println("Main: " + i.doit());
}
}

+ 39
- 0
weaver/src/org/aspectj/weaver/NewParentTypeMunger.java Ver arquivo

@@ -0,0 +1,39 @@
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Common Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* PARC initial implementation
* ******************************************************************/


package org.aspectj.weaver;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Set;

public class NewParentTypeMunger extends ResolvedTypeMunger {
ResolvedTypeX newParent;
public NewParentTypeMunger(ResolvedTypeX newParent) {
super(Parent, null);
this.newParent = newParent;
}

public void write(DataOutputStream s) throws IOException {
throw new RuntimeException("unimplemented");
}


public ResolvedTypeX getNewParent() {
return newParent;
}


}

+ 2
- 0
weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java Ver arquivo

@@ -154,6 +154,8 @@ public abstract class ResolvedTypeMunger {
// not serialized, only created during concretization of aspects
public static final Kind PerObjectInterface = new Kind("PerObjectInterface", 3);
public static final Kind PrivilegedAccess = new Kind("PrivilegedAccess", 4);
public static final Kind Parent = new Kind("Parent", 6);

public static final String SUPER_DISPATCH_NAME = "superDispatch";


+ 18
- 0
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java Ver arquivo

@@ -246,6 +246,8 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
if (ret == null) {
//System.err.println("creating lazy class gen for: " + this);
ret = new LazyClassGen(this);
//ret.print(System.err);
//System.err.println("made LCG from : " + this.getJavaClass().getSuperclassName() );
if (isAspect()) {
lazyClassGen = ret;
}
@@ -264,6 +266,22 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
public ISourceLocation getSourceLocation() {
return getResolvedTypeX().getSourceContext().makeSourceLocation(0); //FIXME, we can do better than this
}

public void addParent(ResolvedTypeX newParent) {
if (newParent.isClass()) {
superClass = newParent;
} else {
ResolvedTypeX[] oldInterfaceNames = getDeclaredInterfaces();
int len = oldInterfaceNames.length;
ResolvedTypeX[] newInterfaceNames = new ResolvedTypeX[len+1];
System.arraycopy(oldInterfaceNames, 0, newInterfaceNames, 0, len);
newInterfaceNames[len] = newParent;
interfaces = newInterfaceNames;
}
//System.err.println("javaClass: " + Arrays.asList(javaClass.getInterfaceNames()) + " super " + javaClass.getSuperclassName());
//if (lazyClassGen != null) lazyClassGen.print();
}
}

+ 14
- 1
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java Ver arquivo

@@ -29,6 +29,7 @@ import org.aspectj.weaver.NameMangler;
import org.aspectj.weaver.NewConstructorTypeMunger;
import org.aspectj.weaver.NewFieldTypeMunger;
import org.aspectj.weaver.NewMethodTypeMunger;
import org.aspectj.weaver.NewParentTypeMunger;
import org.aspectj.weaver.PerObjectInterfaceTypeMunger;
import org.aspectj.weaver.PrivilegedAccessMunger;
import org.aspectj.weaver.ResolvedMember;
@@ -60,13 +61,25 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
return mungePrivilegedAccess(weaver, (PrivilegedAccessMunger)munger);
} else if (munger.getKind() == ResolvedTypeMunger.Constructor) {
return mungeNewConstructor(weaver, (NewConstructorTypeMunger)munger);
} else if (munger.getKind() == ResolvedTypeMunger.Parent) {
return mungeNewParent(weaver, (NewParentTypeMunger)munger);
} else {
throw new RuntimeException("unimplemented");
}
}


private boolean mungeNewParent(BcelClassWeaver weaver, NewParentTypeMunger munger) {
LazyClassGen gen = weaver.getLazyClassGen();
ResolvedTypeX newParent = munger.getNewParent();
if (newParent.isClass()) {
//gen.setSuperClass(newParent);
} else {
gen.addInterface(newParent);
}
return true;
}

private boolean mungePrivilegedAccess(
BcelClassWeaver weaver,
PrivilegedAccessMunger munger)

+ 31
- 1
weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java Ver arquivo

@@ -22,6 +22,7 @@ import org.apache.bcel.classfile.JavaClass;
import org.aspectj.bridge.IMessage;
import org.aspectj.util.FileUtil;
import org.aspectj.weaver.*;
import org.aspectj.weaver.patterns.DeclareParents;
import org.aspectj.weaver.patterns.Pointcut;

public class BcelWeaver implements IWeaver {
@@ -45,7 +46,8 @@ public class BcelWeaver implements IWeaver {
private boolean needToReweaveWorld = false;

private List shadowMungerList = null; // setup by prepareForWeave
private List typeMungerList = null; // setup by prepareForWeave
private List typeMungerList = null; // setup by prepareForWeave
private List declareParentsList = null; // setup by prepareForWeave

private ZipOutputStream zipOutputStream;

@@ -172,6 +174,7 @@ public class BcelWeaver implements IWeaver {

shadowMungerList = xcutSet.getShadowMungers();
typeMungerList = xcutSet.getTypeMungers();
declareParentsList = xcutSet.getDeclareParents();
//XXX this gets us a stable (but completely meaningless) order
Collections.sort(
@@ -284,6 +287,32 @@ public class BcelWeaver implements IWeaver {

public void weave(ResolvedTypeX onType) {
onType.clearInterTypeMungers();
// need to do any declare parents before the matching below
for (Iterator i = declareParentsList.iterator(); i.hasNext(); ) {
DeclareParents p = (DeclareParents)i.next();
List newParents = p.findMatchingNewParents(onType);
if (!newParents.isEmpty()) {
//???
BcelObjectType classType = BcelWorld.getBcelObjectType(world.resolve(onType.getClassName()));
//System.err.println("need to do declare parents for: " + onType);
for (Iterator j = newParents.iterator(); j.hasNext(); ) {
ResolvedTypeX newParent = (ResolvedTypeX)j.next();
if (newParent.isClass()) {
world.showMessage(IMessage.ERROR,
"can't use declare parents to change superclass of binary form \'" +
onType.getClassName() + "\' (implementation limitation)",
p.getSourceLocation(), null);
continue;
}
classType.addParent(newParent);
ResolvedTypeMunger newParentMunger = new NewParentTypeMunger(newParent);
onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, null));
}
}
}
for (Iterator i = typeMungerList.iterator(); i.hasNext(); ) {
ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
if (m.matches(onType)) {
@@ -292,6 +321,7 @@ public class BcelWeaver implements IWeaver {
}
}


// exposed for ClassLoader dynamic weaving
public LazyClassGen weaveWithoutDump(UnwovenClassFile classFile, BcelObjectType classType) throws IOException {
return weave(classFile, classType, false);

+ 5
- 0
weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java Ver arquivo

@@ -177,6 +177,11 @@ public final class LazyClassGen {
public void addInterface(TypeX typeX) {
myGen.addInterface(typeX.getName());
}
public void setSuperClass(TypeX typeX) {
myGen.setSuperclassName(typeX.getName());
}


// non-recursive, may be a bug, ha ha.
private List getClassGens() {

+ 58
- 0
weaver/src/org/aspectj/weaver/patterns/DeclareParents.java Ver arquivo

@@ -16,10 +16,15 @@ package org.aspectj.weaver.patterns;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.aspectj.bridge.IMessage;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedTypeX;
import org.aspectj.weaver.TypeX;
import org.aspectj.weaver.World;

public class DeclareParents extends Declare {
private TypePattern child;
@@ -103,5 +108,58 @@ public class DeclareParents extends Declare {
public boolean isAdviceLike() {
return false;
}
private ResolvedTypeX maybeGetNewParent(ResolvedTypeX targetType, TypePattern typePattern, World world) {
if (typePattern == TypePattern.NO) return null; // already had an error here
TypeX iType = typePattern.getExactType();
ResolvedTypeX parentType = iType.resolve(world);
if (parentType.isAssignableFrom(targetType)) return null; // already a parent
if (targetType.isAssignableFrom(parentType)) {
world.showMessage(IMessage.ERROR,
"type can not extend itself", this.getSourceLocation(), null
);
return null;
}
if (parentType.isClass()) {
if (targetType.isInterface()) {
world.showMessage(IMessage.ERROR,
"interface can not extend a class",
this.getSourceLocation(), null
);
return null;
// how to handle xcutting errors???
}
if (!targetType.getSuperclass().isAssignableFrom(parentType)) {
world.showMessage(IMessage.ERROR,
"can only insert a class into hierarchy, but "
+ iType.getName() + " is not a subtype of " +
targetType.getSuperclass().getName(),
this.getSourceLocation(), null
);
return null;
} else {
return parentType;
}
} else {
return parentType;
}
}

public List/*<ResolvedTypeX>*/ findMatchingNewParents(ResolvedTypeX onType) {
if (!match(onType)) return Collections.EMPTY_LIST;
List ret = new ArrayList();
for (int i=0; i < parents.size(); i++) {
ResolvedTypeX t = maybeGetNewParent(onType, parents.get(i), onType.getWorld());
if (t != null) ret.add(t);
}
return ret;
}

}

Carregando…
Cancelar
Salvar