From ebd2c14134d346b39e2c1d581627132f8b4337c6 Mon Sep 17 00:00:00 2001 From: aclement Date: Tue, 15 Sep 2009 16:39:33 +0000 Subject: [PATCH] more aop.xml compile time config stuff --- .../weaver/bcel/BcelCflowStackFieldAdder.java | 39 +++--- .../org/aspectj/weaver/bcel/BcelWeaver.java | 15 +- .../org/aspectj/weaver/bcel/BcelWorld.java | 131 ++++++++++++++---- .../loadtime/definition/Definition.java | 91 ++++++------ 4 files changed, 173 insertions(+), 103 deletions(-) diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelCflowStackFieldAdder.java b/weaver/src/org/aspectj/weaver/bcel/BcelCflowStackFieldAdder.java index 5c5e2a86b..455edd174 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelCflowStackFieldAdder.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelCflowStackFieldAdder.java @@ -10,14 +10,12 @@ * 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; @@ -26,34 +24,29 @@ import org.aspectj.weaver.ResolvedType; 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, - "", - Type.VOID, - new Type[0], - Constants.INVOKESPECIAL)); - + setup.append(fact.createInvoke(NameMangler.CFLOW_STACK_TYPE, "", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); setup.append(Utility.createSet(fact, cflowStackField)); clinit.getBody().insert(setup); @@ -61,18 +54,22 @@ public class BcelCflowStackFieldAdder extends BcelTypeMunger { 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; } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index a43cf6a1c..db05b5a31 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -1762,17 +1762,26 @@ public class BcelWeaver { } 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 shadowMungers = fastMatch(shadowMungerList, classType.getResolvedTypeX()); + List shadowMungers = fastMatch(shadowMungerList, resolvedClassType); List 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() @@ -1781,7 +1790,7 @@ public class BcelWeaver { // 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) { diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java index 1e48e20ae..f9482e16a 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java @@ -18,6 +18,7 @@ import java.io.IOException; 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; @@ -76,6 +77,7 @@ import org.aspectj.weaver.loadtime.definition.DocumentParser; 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; @@ -719,19 +721,19 @@ public class BcelWorld extends World implements Repository { // weaving. protected void weaveInterTypeDeclarations(ResolvedType onType) { - List declareParentsList = getCrosscuttingMembersSet().getDeclareParents(); + List declareParentsList = getCrosscuttingMembersSet().getDeclareParents(); if (onType.isRawType()) { onType = onType.getGenericType(); } onType.clearInterTypeMungers(); - List decpToRepeat = new ArrayList(); + List decpToRepeat = new ArrayList(); 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 i = declareParentsList.iterator(); i.hasNext();) { + DeclareParents decp = i.next(); boolean typeChanged = applyDeclareParents(decp, onType); if (typeChanged) { aParentChangeOccurred = true; @@ -753,9 +755,9 @@ public class BcelWorld extends World implements Repository { 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 decpToRepeatNextTime = new ArrayList(); + for (Iterator iter = decpToRepeat.iterator(); iter.hasNext();) { + DeclareParents decp = iter.next(); boolean typeChanged = applyDeclareParents(decp, onType); if (typeChanged) { aParentChangeOccurred = true; @@ -808,35 +810,32 @@ public class BcelWorld extends World implements Repository { 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 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()); } } } @@ -850,6 +849,10 @@ public class BcelWorld extends World implements Repository { return isXmlConfiguredWorld && xmlConfiguration != null; } + public WeavingXmlConfig getXmlConfiguration() { + return xmlConfiguration; + } + @Override public boolean isAspectIncluded(ResolvedType aspectType) { if (!isXmlConfigured()) { @@ -873,10 +876,14 @@ public class BcelWorld extends World implements Repository { static class WeavingXmlConfig { private boolean initialized = false; // Lazily done - private List/* Definition */definitions = new ArrayList(); + private List definitions = new ArrayList(); - private List/* */resolvedIncludedAspects = new ArrayList(); - private Map/* */scopes = new HashMap(); + private List resolvedIncludedAspects = new ArrayList(); + private Map scopes = new HashMap(); + private List includedFastMatchPatterns = Collections.emptyList(); + private List includedPatterns = Collections.emptyList(); + private List excludedFastMatchPatterns = Collections.emptyList(); + private List excludedPatterns = Collections.emptyList(); private BcelWorld world; @@ -891,13 +898,11 @@ public class BcelWorld extends World implements Repository { public void ensureInitialized() { if (!initialized) { try { - resolvedIncludedAspects = new ArrayList(); + resolvedIncludedAspects = new ArrayList(); // 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 aspectNames = definition.getAspectClassNames(); + for (String name : aspectNames) { resolvedIncludedAspects.add(name); // TODO check for existence? // ResolvedType resolvedAspect = resolve(UnresolvedType.forName(name)); @@ -927,6 +932,43 @@ public class BcelWorld extends World implements Repository { } } } + try { + List includePatterns = definition.getIncludePatterns(); + if (includePatterns.size() > 0) { + includedPatterns = new ArrayList(); + includedFastMatchPatterns = new ArrayList(); + } + 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 excludePatterns = definition.getExcludePatterns(); + if (excludePatterns.size() > 0) { + excludedPatterns = new ArrayList(); + excludedFastMatchPatterns = new ArrayList(); + } + 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; @@ -940,7 +982,38 @@ public class BcelWorld extends World implements Repository { } 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; } } diff --git a/weaver/src/org/aspectj/weaver/loadtime/definition/Definition.java b/weaver/src/org/aspectj/weaver/loadtime/definition/Definition.java index 6328aefd8..55ba1aea8 100644 --- a/weaver/src/org/aspectj/weaver/loadtime/definition/Definition.java +++ b/weaver/src/org/aspectj/weaver/loadtime/definition/Definition.java @@ -23,59 +23,50 @@ import java.util.Map; */ public class Definition { - private final StringBuffer m_weaverOptions; - - private final List m_dumpPatterns; - - private boolean m_dumpBefore; - + private final StringBuffer weaverOptions; + private final List 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 includePatterns; + private final List excludePatterns; + private final List aspectClassNames; + private final List aspectExcludePatterns; + private final List aspectIncludePatterns; + private final List 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 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(); + includePatterns = new ArrayList(); + excludePatterns = new ArrayList(); + aspectClassNames = new ArrayList(); + aspectExcludePatterns = new ArrayList(); + aspectIncludePatterns = new ArrayList(); + concreteAspects = new ArrayList(); + scopedAspects = new HashMap(); } public String getWeaverOptions() { - return m_weaverOptions.toString(); + return weaverOptions.toString(); } - public List getDumpPatterns() { - return m_dumpPatterns; + public List 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) { @@ -86,35 +77,35 @@ public class Definition { return perClassloaderDumpDir; } - public List getIncludePatterns() { - return m_includePatterns; + public List getIncludePatterns() { + return includePatterns; } - public List getExcludePatterns() { - return m_excludePatterns; + public List getExcludePatterns() { + return excludePatterns; } - public List getAspectClassNames() { - return m_aspectClassNames; + public List getAspectClassNames() { + return aspectClassNames; } - public List getAspectExcludePatterns() { - return m_aspectExcludePatterns; + public List getAspectExcludePatterns() { + return aspectExcludePatterns; } - public List getAspectIncludePatterns() { - return m_aspectIncludePatterns; + public List getAspectIncludePatterns() { + return aspectIncludePatterns; } - public List getConcreteAspects() { - return m_concreteAspects; + public List 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 pointcuts; public final String perclause; public ConcreteAspect(String name, String extend) { @@ -133,7 +124,7 @@ public class Definition { this.extend = extend; } this.precedence = precedence; - this.pointcuts = new ArrayList(); + this.pointcuts = new ArrayList(); this.perclause = perclause; } } @@ -149,7 +140,7 @@ public class Definition { } public void appendWeaverOptions(String option) { - m_weaverOptions.append(option.trim()).append(' '); + weaverOptions.append(option.trim()).append(' '); } public void addScopedAspect(String name, String scopePattern) { @@ -157,7 +148,7 @@ public class Definition { } public String getScopeForAspect(String name) { - return (String) scopedAspects.get(name); + return scopedAspects.get(name); } } -- 2.39.5