* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.weaver.bcel;
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.generic.FieldGen;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionList;
-import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.NameMangler;
public class BcelCflowStackFieldAdder extends BcelTypeMunger {
private ResolvedMember cflowStackField;
+
public BcelCflowStackFieldAdder(ResolvedMember cflowStackField) {
- super(null,(ResolvedType)cflowStackField.getDeclaringType());
+ super(null, (ResolvedType) cflowStackField.getDeclaringType());
this.cflowStackField = cflowStackField;
}
+ @Override
public boolean munge(BcelClassWeaver weaver) {
LazyClassGen gen = weaver.getLazyClassGen();
- if (!gen.getType().equals(cflowStackField.getDeclaringType())) return false;
-
- FieldGen f = new FieldGen(cflowStackField.getModifiers(),
- BcelWorld.makeBcelType(cflowStackField.getReturnType()),
- cflowStackField.getName(),
- gen.getConstantPool());
- gen.addField(f,getSourceLocation());
-
- LazyMethodGen clinit = gen.getAjcPreClinit(); //StaticInitializer();
+ if (!gen.getType().equals(cflowStackField.getDeclaringType())) {
+ return false;
+ }
+ FieldGen f = new FieldGen(cflowStackField.getModifiers(), BcelWorld.makeBcelType(cflowStackField.getReturnType()),
+ cflowStackField.getName(), gen.getConstantPool());
+ gen.addField(f, getSourceLocation());
+
+ LazyMethodGen clinit = gen.getAjcPreClinit(); // StaticInitializer();
InstructionList setup = new InstructionList();
InstructionFactory fact = gen.getFactory();
- setup.append(fact.createNew(new ObjectType(NameMangler.CFLOW_STACK_TYPE)));
+ setup.append(fact.createNew(NameMangler.CFLOW_STACK_TYPE));
setup.append(InstructionFactory.createDup(1));
- setup.append(fact.createInvoke(
- NameMangler.CFLOW_STACK_TYPE,
- "<init>",
- Type.VOID,
- new Type[0],
- Constants.INVOKESPECIAL));
-
+ setup.append(fact.createInvoke(NameMangler.CFLOW_STACK_TYPE, "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
setup.append(Utility.createSet(fact, cflowStackField));
clinit.getBody().insert(setup);
return true;
}
-
+ @Override
public ResolvedMember getMatchingSyntheticMember(Member member) {
return null;
}
+ @Override
public ResolvedMember getSignature() {
return cflowStackField;
}
+ @Override
public boolean matches(ResolvedType onType) {
return onType.equals(cflowStackField.getDeclaringType());
}
+
+ @Override
public boolean existsToSupportShadowMunging() {
return true;
}
}
private LazyClassGen weave(UnwovenClassFile classFile, BcelObjectType classType, boolean dump) throws IOException {
+
if (classType.isSynthetic()) { // Don't touch synthetic classes
if (dump) {
dumpUnchanged(classFile);
}
return null;
}
+ ReferenceType resolvedClassType = classType.getResolvedTypeX();
+
+ if (world.isXmlConfigured() && world.getXmlConfiguration().excludesType(resolvedClassType)) {
+ if (dump) {
+ dumpUnchanged(classFile);
+ }
+ return null;
+ }
- List<ShadowMunger> shadowMungers = fastMatch(shadowMungerList, classType.getResolvedTypeX());
+ List<ShadowMunger> shadowMungers = fastMatch(shadowMungerList, resolvedClassType);
List<ConcreteTypeMunger> typeMungers = classType.getResolvedTypeX().getInterTypeMungers();
- classType.getResolvedTypeX().checkInterTypeMungers();
+ resolvedClassType.checkInterTypeMungers();
// Decide if we need to do actual weaving for this class
boolean mightNeedToWeave = shadowMungers.size() > 0 || typeMungers.size() > 0 || classType.isAspect()
// May need bridge methods if on 1.5 and something in our hierarchy is
// affected by ITDs
boolean mightNeedBridgeMethods = world.isInJava5Mode() && !classType.isInterface()
- && classType.getResolvedTypeX().getInterTypeMungersIncludingSupers().size() > 0;
+ && resolvedClassType.getInterTypeMungersIncludingSupers().size() > 0;
LazyClassGen clazz = null;
if (mightNeedToWeave || mightNeedBridgeMethods) {
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.aspectj.weaver.model.AsmRelationshipProvider;
import org.aspectj.weaver.patterns.DeclareAnnotation;
import org.aspectj.weaver.patterns.DeclareParents;
+import org.aspectj.weaver.patterns.ParserException;
import org.aspectj.weaver.patterns.PatternParser;
import org.aspectj.weaver.patterns.TypePattern;
import org.aspectj.weaver.tools.Trace;
// weaving.
protected void weaveInterTypeDeclarations(ResolvedType onType) {
- List declareParentsList = getCrosscuttingMembersSet().getDeclareParents();
+ List<DeclareParents> declareParentsList = getCrosscuttingMembersSet().getDeclareParents();
if (onType.isRawType()) {
onType = onType.getGenericType();
}
onType.clearInterTypeMungers();
- List decpToRepeat = new ArrayList();
+ List<DeclareParents> decpToRepeat = new ArrayList<DeclareParents>();
boolean aParentChangeOccurred = false;
boolean anAnnotationChangeOccurred = false;
// First pass - apply all decp mungers
- for (Iterator i = declareParentsList.iterator(); i.hasNext();) {
- DeclareParents decp = (DeclareParents) i.next();
+ for (Iterator<DeclareParents> i = declareParentsList.iterator(); i.hasNext();) {
+ DeclareParents decp = i.next();
boolean typeChanged = applyDeclareParents(decp, onType);
if (typeChanged) {
aParentChangeOccurred = true;
while ((aParentChangeOccurred || anAnnotationChangeOccurred) && !decpToRepeat.isEmpty()) {
anAnnotationChangeOccurred = aParentChangeOccurred = false;
- List decpToRepeatNextTime = new ArrayList();
- for (Iterator iter = decpToRepeat.iterator(); iter.hasNext();) {
- DeclareParents decp = (DeclareParents) iter.next();
+ List<DeclareParents> decpToRepeatNextTime = new ArrayList<DeclareParents>();
+ for (Iterator<DeclareParents> iter = decpToRepeat.iterator(); iter.hasNext();) {
+ DeclareParents decp = iter.next();
boolean typeChanged = applyDeclareParents(decp, onType);
if (typeChanged) {
aParentChangeOccurred = true;
return (AsmManager) getModel(); // For now... always an AsmManager in a bcel environment
}
+ void raiseError(String message) {
+ getMessageHandler().handleMessage(MessageUtil.error(message));
+ }
+
/**
* These are aop.xml files that can be used to alter the aspects that actually apply from those passed in - and also their scope
* of application to other files in the system.
*
* @param xmlFiles list of File objects representing any aop.xml files passed in to configure the build process
*/
- public void setXmlFiles(List xmlFiles) {
+ public void setXmlFiles(List<File> xmlFiles) {
if (!isXmlConfiguredWorld && !xmlFiles.isEmpty()) {
- getMessageHandler().handleMessage(
- MessageUtil
- .error("xml configuration files only supported by the compiler when -xmlConfigured option specified"));
+ raiseError("xml configuration files only supported by the compiler when -xmlConfigured option specified");
return;
}
if (!xmlFiles.isEmpty()) {
xmlConfiguration = new WeavingXmlConfig(this);
}
- for (Iterator iterator = xmlFiles.iterator(); iterator.hasNext();) {
- File xmlfile = (File) iterator.next();
+ for (File xmlfile : xmlFiles) {
try {
Definition d = DocumentParser.parse(xmlfile.toURI().toURL());
xmlConfiguration.add(d);
} catch (MalformedURLException e) {
- getMessageHandler().handleMessage(
- MessageUtil.error("Unexpected problem processing XML config file '" + xmlfile.getName() + "' :"
- + e.getMessage()));
+ raiseError("Unexpected problem processing XML config file '" + xmlfile.getName() + "' :" + e.getMessage());
} catch (Exception e) {
- getMessageHandler().handleMessage(
- MessageUtil.error("Unexpected problem processing XML config file '" + xmlfile.getName() + "' :"
- + e.getMessage()));
+ raiseError("Unexpected problem processing XML config file '" + xmlfile.getName() + "' :" + e.getMessage());
}
}
}
return isXmlConfiguredWorld && xmlConfiguration != null;
}
+ public WeavingXmlConfig getXmlConfiguration() {
+ return xmlConfiguration;
+ }
+
@Override
public boolean isAspectIncluded(ResolvedType aspectType) {
if (!isXmlConfigured()) {
static class WeavingXmlConfig {
private boolean initialized = false; // Lazily done
- private List/* Definition */definitions = new ArrayList();
+ private List<Definition> definitions = new ArrayList<Definition>();
- private List/* <String> */resolvedIncludedAspects = new ArrayList();
- private Map/* <String,TypePattern> */scopes = new HashMap();
+ private List<String> resolvedIncludedAspects = new ArrayList<String>();
+ private Map<String, TypePattern> scopes = new HashMap<String, TypePattern>();
+ private List<String> includedFastMatchPatterns = Collections.emptyList();
+ private List<TypePattern> includedPatterns = Collections.emptyList();
+ private List<String> excludedFastMatchPatterns = Collections.emptyList();
+ private List<TypePattern> excludedPatterns = Collections.emptyList();
private BcelWorld world;
public void ensureInitialized() {
if (!initialized) {
try {
- resolvedIncludedAspects = new ArrayList();
+ resolvedIncludedAspects = new ArrayList<String>();
// Process the definitions into something more optimal
- for (Iterator iterator = definitions.iterator(); iterator.hasNext();) {
- Definition definition = (Definition) iterator.next();
- List/* String */aspectNames = definition.getAspectClassNames();
- for (Iterator iterator2 = aspectNames.iterator(); iterator2.hasNext();) {
- String name = (String) iterator2.next();
+ for (Definition definition : definitions) {
+ List<String> aspectNames = definition.getAspectClassNames();
+ for (String name : aspectNames) {
resolvedIncludedAspects.add(name);
// TODO check for existence?
// ResolvedType resolvedAspect = resolve(UnresolvedType.forName(name));
}
}
}
+ try {
+ List<String> includePatterns = definition.getIncludePatterns();
+ if (includePatterns.size() > 0) {
+ includedPatterns = new ArrayList<TypePattern>();
+ includedFastMatchPatterns = new ArrayList<String>();
+ }
+ for (String includePattern : includePatterns) {
+ if (includePattern.endsWith("..*")) {
+ // from 'blah.blah.blah..*' leave the 'blah.blah.blah.'
+ includedFastMatchPatterns.add(includePattern
+ .substring(0, includePattern.length() - 2));
+ } else {
+ TypePattern includedPattern = new PatternParser(includePattern).parseTypePattern();
+ includedPatterns.add(includedPattern);
+ }
+ }
+ List<String> excludePatterns = definition.getExcludePatterns();
+ if (excludePatterns.size() > 0) {
+ excludedPatterns = new ArrayList<TypePattern>();
+ excludedFastMatchPatterns = new ArrayList<String>();
+ }
+ for (String excludePattern : excludePatterns) {
+ if (excludePattern.endsWith("..*")) {
+ // from 'blah.blah.blah..*' leave the 'blah.blah.blah.'
+ excludedFastMatchPatterns.add(excludePattern
+ .substring(0, excludePattern.length() - 2));
+ } else {
+ TypePattern excludedPattern = new PatternParser(excludePattern).parseTypePattern();
+ excludedPatterns.add(excludedPattern);
+ }
+ }
+ } catch (ParserException pe) {
+ // TODO definitions should remember which file they came from, for inclusion in this message
+ world.getMessageHandler().handleMessage(
+ MessageUtil.error("Unable to parse type pattern: " + pe.getMessage()));
+
+ }
}
} finally {
initialized = true;
}
public TypePattern getScopeFor(String name) {
- return (TypePattern) scopes.get(name);
+ return scopes.get(name);
+ }
+
+ // Can't quite follow the same rules for exclusion as used for loadtime weaving:
+ // "The set of types to be woven are those types matched by at least one weaver include element and not matched by any
+ // weaver
+ // exclude element. If there are no weaver include statements then all non-excluded types are included."
+ // Since if the weaver is seeing it during this kind of build, the type is implicitly included. So all we should check
+ // for is exclusion
+ public boolean excludesType(ResolvedType type) {
+ String typename = type.getName();
+ boolean excluded = false;
+ for (String excludedPattern : excludedFastMatchPatterns) {
+ if (typename.startsWith(excludedPattern)) {
+ excluded = true;
+ break;
+ }
+ }
+ if (!excluded) {
+ for (TypePattern excludedPattern : excludedPatterns) {
+ if (excludedPattern.matchesStatically(type)) {
+ excluded = true;
+ break;
+ }
+ }
+ }
+ if (excluded && !world.getMessageHandler().isIgnoring(IMessage.INFO)) {
+ world.getMessageHandler().handleMessage(
+ MessageUtil.info("Type '" + typename + "' excluded from weaving due to xml configuration"));
+
+ }
+ return excluded;
}
}
*/
public class Definition {
- private final StringBuffer m_weaverOptions;
-
- private final List m_dumpPatterns;
-
- private boolean m_dumpBefore;
-
+ private final StringBuffer weaverOptions;
+ private final List<String> dumpPatterns;
+ private boolean dumpBefore;
private boolean perClassloaderDumpDir;
-
- private final List m_includePatterns;
-
- private final List m_excludePatterns;
-
- private final List m_aspectClassNames;
-
- private final List m_aspectExcludePatterns;
-
- private final List m_aspectIncludePatterns;
-
- private final List m_concreteAspects;
+ private final List<String> includePatterns;
+ private final List<String> excludePatterns;
+ private final List<String> aspectClassNames;
+ private final List<String> aspectExcludePatterns;
+ private final List<String> aspectIncludePatterns;
+ private final List<Definition.ConcreteAspect> concreteAspects;
/**
* When aspects are defined, they can specify a scope type pattern and then will only apply to types matching that pattern.
*/
- private final Map scopedAspects;
+ private final Map<String, String> scopedAspects;
public Definition() {
- m_weaverOptions = new StringBuffer();
- m_dumpBefore = false;
+ weaverOptions = new StringBuffer();
+ dumpBefore = false;
perClassloaderDumpDir = false;
- m_dumpPatterns = new ArrayList(0);
- m_includePatterns = new ArrayList(0);
- m_excludePatterns = new ArrayList(0);
- m_aspectClassNames = new ArrayList();
- m_aspectExcludePatterns = new ArrayList(0);
- m_aspectIncludePatterns = new ArrayList(0);
- m_concreteAspects = new ArrayList(0);
- scopedAspects = new HashMap();
+ dumpPatterns = new ArrayList<String>();
+ includePatterns = new ArrayList<String>();
+ excludePatterns = new ArrayList<String>();
+ aspectClassNames = new ArrayList<String>();
+ aspectExcludePatterns = new ArrayList<String>();
+ aspectIncludePatterns = new ArrayList<String>();
+ concreteAspects = new ArrayList<Definition.ConcreteAspect>();
+ scopedAspects = new HashMap<String, String>();
}
public String getWeaverOptions() {
- return m_weaverOptions.toString();
+ return weaverOptions.toString();
}
- public List getDumpPatterns() {
- return m_dumpPatterns;
+ public List<String> getDumpPatterns() {
+ return dumpPatterns;
}
public void setDumpBefore(boolean b) {
- m_dumpBefore = b;
+ dumpBefore = b;
}
public boolean shouldDumpBefore() {
- return m_dumpBefore;
+ return dumpBefore;
}
public void setCreateDumpDirPerClassloader(boolean b) {
return perClassloaderDumpDir;
}
- public List getIncludePatterns() {
- return m_includePatterns;
+ public List<String> getIncludePatterns() {
+ return includePatterns;
}
- public List getExcludePatterns() {
- return m_excludePatterns;
+ public List<String> getExcludePatterns() {
+ return excludePatterns;
}
- public List getAspectClassNames() {
- return m_aspectClassNames;
+ public List<String> getAspectClassNames() {
+ return aspectClassNames;
}
- public List getAspectExcludePatterns() {
- return m_aspectExcludePatterns;
+ public List<String> getAspectExcludePatterns() {
+ return aspectExcludePatterns;
}
- public List getAspectIncludePatterns() {
- return m_aspectIncludePatterns;
+ public List<String> getAspectIncludePatterns() {
+ return aspectIncludePatterns;
}
- public List getConcreteAspects() {
- return m_concreteAspects;
+ public List<Definition.ConcreteAspect> getConcreteAspects() {
+ return concreteAspects;
}
public static class ConcreteAspect {
public final String name;
public final String extend;
public final String precedence;
- public final List pointcuts;
+ public final List<Definition.Pointcut> pointcuts;
public final String perclause;
public ConcreteAspect(String name, String extend) {
this.extend = extend;
}
this.precedence = precedence;
- this.pointcuts = new ArrayList();
+ this.pointcuts = new ArrayList<Definition.Pointcut>();
this.perclause = perclause;
}
}
}
public void appendWeaverOptions(String option) {
- m_weaverOptions.append(option.trim()).append(' ');
+ weaverOptions.append(option.trim()).append(' ');
}
public void addScopedAspect(String name, String scopePattern) {
}
public String getScopeForAspect(String name) {
- return (String) scopedAspects.get(name);
+ return scopedAspects.get(name);
}
}