public final Kind unresolvableMember = | public final Kind unresolvableMember = | ||||
new Kind("unresolvableMember", "can not resolve this member: {0}"); | new Kind("unresolvableMember", "can not resolve this member: {0}"); | ||||
public final Kind typeNotExposedToWeaver = | |||||
new Kind("typeNotExposedToWeaver", "this affected type is not exposed to the weaver: {0}"); | |||||
public Lint(World world) { | public Lint(World world) { | ||||
this.world = world; | this.world = world; |
public boolean matches(ResolvedTypeX matchType) { | public boolean matches(ResolvedTypeX matchType) { | ||||
ResolvedTypeX onType = matchType.getWorld().resolve(signature.getDeclaringType()); | ResolvedTypeX onType = matchType.getWorld().resolve(signature.getDeclaringType()); | ||||
//System.err.println("matching: " + this + " to " + matchType + " onType = " + onType); | //System.err.println("matching: " + this + " to " + matchType + " onType = " + onType); | ||||
if (matchType.equals(onType)) return true; | |||||
if (matchType.equals(onType)) { | |||||
if (!onType.isExposedToWeaver() && | |||||
matchType.getWorld().getLint().typeNotExposedToWeaver.isEnabled()) | |||||
{ | |||||
matchType.getWorld().getLint().typeNotExposedToWeaver.signal(matchType.getName(), signature.getSourceLocation()); | |||||
} | |||||
return true; | |||||
} | |||||
//System.err.println("NO MATCH DIRECT"); | //System.err.println("NO MATCH DIRECT"); | ||||
if (onType.isInterface()) { | if (onType.isInterface()) { |
public abstract class ResolvedTypeX extends TypeX { | public abstract class ResolvedTypeX extends TypeX { | ||||
protected World world; | protected World world; | ||||
ResolvedTypeX(String signature, World world) { | ResolvedTypeX(String signature, World world) { | ||||
super(signature); | super(signature); | ||||
public static abstract class Name extends ResolvedTypeX { | public static abstract class Name extends ResolvedTypeX { | ||||
protected ISourceContext sourceContext; | protected ISourceContext sourceContext; | ||||
protected boolean exposedToWeaver; | |||||
public Name(String signature, World world) { | |||||
public Name(String signature, World world, boolean exposedToWeaver) { | |||||
super(signature, world); | super(signature, world); | ||||
this.exposedToWeaver = exposedToWeaver; | |||||
} | } | ||||
public final boolean isClass() { | public final boolean isClass() { | ||||
return sourceContext; | return sourceContext; | ||||
} | } | ||||
public boolean isExposedToWeaver() { | |||||
return exposedToWeaver; | |||||
} | |||||
} | } | ||||
static class Array extends ResolvedTypeX { | static class Array extends ResolvedTypeX { | ||||
} | } | ||||
public ISourceLocation getSourceLocation() { return null; } | public ISourceLocation getSourceLocation() { return null; } | ||||
public boolean isExposedToWeaver() { return false; } | |||||
} | } |
invalidAbsoluteTypeName = warning | invalidAbsoluteTypeName = warning | ||||
invalidWildcardTypeName = ignore | invalidWildcardTypeName = ignore | ||||
unresolvableMember = warning | |||||
unresolvableMember = warning | |||||
typeNotExposedToWeaver = warning |
// IMPORTANT! THIS DOESN'T do real work on the java class, just stores it away. | // IMPORTANT! THIS DOESN'T do real work on the java class, just stores it away. | ||||
BcelObjectType(String signature, World world, JavaClass javaClass) { | |||||
super(signature, world); | |||||
BcelObjectType(String signature, World world, JavaClass javaClass, boolean exposedToWeaver) { | |||||
super(signature, world, exposedToWeaver); | |||||
this.javaClass = javaClass; | this.javaClass = javaClass; | ||||
sourceContext = new BcelSourceContext(this); | sourceContext = new BcelSourceContext(this); | ||||
List l = BcelAttributes.readAjAttributes(javaClass.getAttributes(), getSourceContext()); | List l = BcelAttributes.readAjAttributes(javaClass.getAttributes(), getSourceContext()); | ||||
for (Iterator iter = l.iterator(); iter.hasNext();) { | for (Iterator iter = l.iterator(); iter.hasNext();) { | ||||
AjAttribute a = (AjAttribute) iter.next(); | AjAttribute a = (AjAttribute) iter.next(); | ||||
//System.err.println("unpacking: " + this + " and " + a); | |||||
if (a instanceof AjAttribute.Aspect) { | if (a instanceof AjAttribute.Aspect) { | ||||
perClause = ((AjAttribute.Aspect)a).reify(this); | perClause = ((AjAttribute.Aspect)a).reify(this); | ||||
} else if (a instanceof AjAttribute.PointcutDeclarationAttribute) { | } else if (a instanceof AjAttribute.PointcutDeclarationAttribute) { | ||||
return javaClass; | return javaClass; | ||||
} | } | ||||
/** | |||||
* Switch to a new JavaClass and clear all caches | |||||
*/ | |||||
void replaceJavaClass(JavaClass jc) { | |||||
if (this.javaClass == jc) return; | |||||
this.javaClass = jc; | |||||
void resetState() { | |||||
this.interfaces = null; | this.interfaces = null; | ||||
this.superClass = null; | this.superClass = null; | ||||
this.fields = null; | this.fields = null; | ||||
isObject = (javaClass.getSuperclassNameIndex() == 0); | isObject = (javaClass.getSuperclassNameIndex() == 0); | ||||
unpackAspectAttributes(); | unpackAspectAttributes(); | ||||
//XXX is clearing these caches sufficient | |||||
} | |||||
/** | |||||
* Switch to a new JavaClass and clear all caches | |||||
*/ | |||||
void replaceJavaClass(JavaClass jc) { | |||||
if (this.javaClass == jc) return; | |||||
this.javaClass = jc; | |||||
resetState(); | |||||
} | } | ||||
public WeaverStateKind getWeaverState() { | public WeaverStateKind getWeaverState() { | ||||
public LazyClassGen getLazyClassGen() { | public LazyClassGen getLazyClassGen() { | ||||
LazyClassGen ret = lazyClassGen; | LazyClassGen ret = lazyClassGen; | ||||
if (ret == null) { | if (ret == null) { | ||||
//System.err.println("creating lazy class gen for: " + this); | |||||
ret = new LazyClassGen(this); | ret = new LazyClassGen(this); | ||||
if (isAspect()) { | if (isAspect()) { | ||||
lazyClassGen = ret; | lazyClassGen = ret; |
"(world=" + needToReweaveWorld + ")", null, null); | "(world=" + needToReweaveWorld + ")", null, null); | ||||
//System.err.println("typeMungers: " + typeMungerList); | |||||
// clear all state from files we'll be reweaving | |||||
for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) { | |||||
UnwovenClassFile classFile = (UnwovenClassFile)i.next(); | |||||
String className = classFile.getClassName(); | |||||
BcelObjectType classType = (BcelObjectType) world.resolve(className); | |||||
classType.resetState(); | |||||
} | |||||
//XXX this isn't quite the right place for this... | //XXX this isn't quite the right place for this... | ||||
for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) { | for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) { | ||||
UnwovenClassFile classFile = (UnwovenClassFile)i.next(); | UnwovenClassFile classFile = (UnwovenClassFile)i.next(); | ||||
if (shadowMungers.size() > 0 || typeMungers.size() > 0 || classType.isAspect()) { | if (shadowMungers.size() > 0 || typeMungers.size() > 0 || classType.isAspect()) { | ||||
clazz = classType.getLazyClassGen(); | clazz = classType.getLazyClassGen(); | ||||
//System.err.println("got lazy gen: " + clazz + ", " + clazz.getWeaverState()); | |||||
try { | try { | ||||
boolean isChanged = BcelClassWeaver.weave(world, clazz, shadowMungers, typeMungers); | boolean isChanged = BcelClassWeaver.weave(world, clazz, shadowMungers, typeMungers); | ||||
if (isChanged) { | if (isChanged) { |
if (jc == null) { | if (jc == null) { | ||||
return ResolvedTypeX.MISSING; | return ResolvedTypeX.MISSING; | ||||
} else { | } else { | ||||
return new BcelObjectType(ty.getSignature(), this, jc); | |||||
return new BcelObjectType(ty.getSignature(), this, jc, false); | |||||
} | } | ||||
} | } | ||||
String signature = TypeX.forName(jc.getClassName()).getSignature(); | String signature = TypeX.forName(jc.getClassName()).getSignature(); | ||||
BcelObjectType ret = (BcelObjectType)typeMap.get(signature); | BcelObjectType ret = (BcelObjectType)typeMap.get(signature); | ||||
if (ret == null) { | if (ret == null) { | ||||
ret = new BcelObjectType(signature, this, jc); | |||||
ret = new BcelObjectType(signature, this, jc, true); | |||||
typeMap.put(signature, ret); | typeMap.put(signature, ret); | ||||
} else { | } else { | ||||
ret.replaceJavaClass(jc); | ret.replaceJavaClass(jc); |
/* ******************************************************************* | |||||
* 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: | |||||
* Xerox/PARC initial implementation | |||||
* ******************************************************************/ | |||||
package org.aspectj.weaver.bcel; | |||||
import java.io.IOException; | |||||
import java.util.List; | |||||
import java.util.zip.*; | |||||
//XXX we believe this is now unneeded | |||||
public class UnwovenZipClassFile extends UnwovenClassFile { | |||||
private ZipOutputStream zipOutputStream; | |||||
public UnwovenZipClassFile(ZipOutputStream zipOutputStream, String filename, byte[] bytes) { | |||||
super(filename, bytes); | |||||
this.zipOutputStream = zipOutputStream; | |||||
} | |||||
public void writeWovenBytes(byte[] bytes, List childClasses) throws IOException { | |||||
//??? we rewrite this every time | |||||
if (!childClasses.isEmpty()) { | |||||
throw new RuntimeException("unimplemented"); | |||||
} | |||||
ZipEntry newEntry = new ZipEntry(filename); //??? get compression scheme right | |||||
zipOutputStream.putNextEntry(newEntry); | |||||
zipOutputStream.write(bytes); | |||||
zipOutputStream.closeEntry(); | |||||
writtenBytes = bytes; | |||||
} | |||||
} |
} | } | ||||
public boolean match(ResolvedTypeX typeX) { | public boolean match(ResolvedTypeX typeX) { | ||||
return child.matchesStatically(typeX); | |||||
if (!child.matchesStatically(typeX)) return false; | |||||
if (typeX.getWorld().getLint().typeNotExposedToWeaver.isEnabled() && | |||||
!typeX.isExposedToWeaver()) | |||||
{ | |||||
typeX.getWorld().getLint().typeNotExposedToWeaver.signal(typeX.getName(), getSourceLocation()); | |||||
} | |||||
return true; | |||||
} | } | ||||
public String toString() { | public String toString() { | ||||
StringBuffer buf = new StringBuffer(); | StringBuffer buf = new StringBuffer(); |