--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * initial implementation Alexandre Vasseur
+ * generic signature update Adrian Colyer
+ *******************************************************************************/
+package org.aspectj.lang;
+
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Handles generic aspectOf method when those are not available in the aspects but added later on
+ * thru load time weaving.
+ * <p/>
+ * Aspects.aspectOf(..) is doing reflective calls to the aspect aspectOf, so for better performance
+ * consider using ajc compilation of the aspects and using them as a binary dependancies in your project.
+ *
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class Aspects {
+
+ private final static Class[] EMPTY_CLASS_ARRAY = new Class[0];
+ private final static Class[] PEROBJECT_CLASS_ARRAY = new Class[]{Object.class};
+ private final static Class[] PERTYPEWITHIN_CLASS_ARRAY = new Class[]{Class.class};
+ private final static Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+ private final static String ASPECTOF = "aspectOf";
+ private final static String HASASPECT = "hasAspect";
+
+ /**
+ * Returns the singleton aspect or the percflow / percflowbelow associated with the current thread
+ *
+ * @param aspectClass
+ * @return
+ * @throws NoAspectBoundException if no such aspect
+ */
+ public static <T> T aspectOf(Class<T> aspectClass) throws NoAspectBoundException {
+ try {
+ return (T) getSingletonOrThreadAspectOf(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY);
+ } catch (InvocationTargetException e) {
+ //FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs
+ throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause());
+ } catch (Exception e) {
+ throw new NoAspectBoundException(aspectClass.getName(), e);
+ }
+ }
+
+ /**
+ * Returns the perthis / pertarget aspect
+ * @param aspectClass
+ * @param perObject
+ * @return
+ * @throws NoAspectBoundException if no such aspect, or no aspect bound
+ */
+ public static <T> T aspectOf(Class<T> aspectClass, Object perObject) throws NoAspectBoundException {
+ try {
+ return (T) getPerObjectAspectOf(aspectClass).invoke(null, new Object[]{perObject});
+ } catch (InvocationTargetException e) {
+ //FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs
+ throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause());
+ } catch (Exception e) {
+ throw new NoAspectBoundException(aspectClass.getName(), e);
+ }
+ }
+
+ /**
+ * Returns the pertypewithin aspect
+ * @param aspectClass
+ * @param perTypeWithin class
+ * @return
+ * @throws NoAspectBoundException if no such aspect, or no aspect bound
+ */
+ public static <T> T aspectOf(Class<T> aspectClass, Class<?> perTypeWithin) throws NoAspectBoundException {
+ try {
+ return (T) getPerTypeWithinAspectOf(aspectClass).invoke(null, new Object[]{perTypeWithin});
+ } catch (InvocationTargetException e) {
+// FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs
+ throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause());
+ } catch (Exception e) {
+ throw new NoAspectBoundException(aspectClass.getName(), e);
+ }
+ }
+
+ /**
+ * Returns true if singleton aspect or percflow / percflowbelow aspect is bound
+ *
+ * @param aspectClass
+ * @return
+ * @throws NoAspectBoundException if not bound
+ */
+ public static boolean hasAspect(Class<?> aspectClass) throws NoAspectBoundException {
+ try {
+ return ((Boolean)getSingletonOrThreadHasAspect(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY)).booleanValue();
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if the perthis / pertarget aspect is bound
+ * @param aspectClass
+ * @param perObject
+ * @return
+ * @throws NoAspectBoundException if not bound
+ */
+ public static boolean hasAspect(Class<?> aspectClass, Object perObject) throws NoAspectBoundException {
+ try {
+ return ((Boolean)getPerObjectHasAspect(aspectClass).invoke(null, new Object[]{perObject})).booleanValue();
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if the pertypewithin aspect is bound
+ * @param aspectClass
+ * @param perTypeWithin class
+ * @return
+ * @throws NoAspectBoundException if not bound
+ */
+ public static boolean hasAspect(Class<?> aspectClass, Class<?> perTypeWithin) throws NoAspectBoundException {
+ try {
+ return ((Boolean)getPerTypeWithinHasAspect(aspectClass).invoke(null, new Object[]{perTypeWithin})).booleanValue();
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ // -- aspectOf
+
+ private static Method getSingletonOrThreadAspectOf(Class<?> aspectClass) throws NoSuchMethodException {
+ Method method = aspectClass.getDeclaredMethod(ASPECTOF, EMPTY_CLASS_ARRAY);
+ return checkAspectOf(method, aspectClass);
+ }
+
+ private static Method getPerObjectAspectOf(Class<?> aspectClass) throws NoSuchMethodException {
+ Method method = aspectClass.getDeclaredMethod(ASPECTOF, PEROBJECT_CLASS_ARRAY);
+ return checkAspectOf(method, aspectClass);
+ }
+
+ private static Method getPerTypeWithinAspectOf(Class<?> aspectClass) throws NoSuchMethodException {
+ Method method = aspectClass.getDeclaredMethod(ASPECTOF, PERTYPEWITHIN_CLASS_ARRAY);
+ return checkAspectOf(method, aspectClass);
+ }
+
+ private static Method checkAspectOf(Method method, Class<?> aspectClass) throws NoSuchMethodException {
+ method.setAccessible(true);
+ if (!method.isAccessible()
+ || !Modifier.isPublic(method.getModifiers())
+ || !Modifier.isStatic(method.getModifiers())) {
+ throw new NoSuchMethodException(aspectClass.getName() + ".aspectOf(..) is not accessible public static");
+ }
+ return method;
+ }
+
+ // -- hasAspect
+
+ private static Method getSingletonOrThreadHasAspect(Class aspectClass) throws NoSuchMethodException {
+ Method method = aspectClass.getDeclaredMethod(HASASPECT, EMPTY_CLASS_ARRAY);
+ return checkHasAspect(method, aspectClass);
+ }
+
+ private static Method getPerObjectHasAspect(Class aspectClass) throws NoSuchMethodException {
+ Method method = aspectClass.getDeclaredMethod(HASASPECT, PEROBJECT_CLASS_ARRAY);
+ return checkHasAspect(method, aspectClass);
+ }
+
+ private static Method getPerTypeWithinHasAspect(Class aspectClass) throws NoSuchMethodException {
+ Method method = aspectClass.getDeclaredMethod(HASASPECT, PERTYPEWITHIN_CLASS_ARRAY);
+ return checkHasAspect(method, aspectClass);
+ }
+
+ private static Method checkHasAspect(Method method, Class aspectClass) throws NoSuchMethodException {
+ method.setAccessible(true);
+ if (!method.isAccessible()
+ || !Modifier.isPublic(method.getModifiers())
+ || !Modifier.isStatic(method.getModifiers())) {
+ throw new NoSuchMethodException(aspectClass.getName() + ".hasAspect(..) is not accessible public static");
+ }
+ return method;
+ }
+}
static interface I1 { int do1(); }
- static class Imp1 implements I1 {
+ public static class Imp1 implements I1 {
public int do1() {return 1;}
}
}
static class Implementation implements Introduced {
+ public Implementation(int i) {}
+ public Implementation() {}
+
public void intro() {
log("intro-"+field1);
// we cannot copy the raw bytecode as there might be super.* calls, and other OO stuff
import junit.framework.TestCase;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
-import org.aspectj.lang.annotation.DeclareImplements;
import org.aspectj.lang.annotation.DeclareParents;
import java.util.Arrays;
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Vasseur initial implementation
+ *******************************************************************************/
+package ataspectj.bugs;
+
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Around;
+
+/**
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+//@Aspect
+public abstract aspect AbstractInherited {
+
+ //@Around("execution(* foo(..))")
+ //public Object around() {
+ // return null;
+ //}
+
+ void around(): execution(* foo(..)) {
+ }
+
+}
+
+@Aspect
+class Sub extends AbstractInherited {
+}
+
+class C {
+ void foo() {
+ }
+}
+
+
import junit.framework.Test;
import junit.framework.TestSuite;
import ataspectj.TestHelper;
+import org.aspectj.lang.annotation.DeclareParents;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.DeclareImplements;
import org.aspectj.lang.Aspects;
import java.io.Serializable;
@Aspect
static class TestAspectForAspect {
- @DeclareImplements("ataspectj.bugs.AspectOfWhenAspectNotInIncludeTest.TestAspect")
+ @DeclareParents("ataspectj.bugs.AspectOfWhenAspectNotInIncludeTest.TestAspect")
Serializable shouldNotHappenDueToInclude;
}
interface I {
}
- static class IImpl implements I {
+ public static class IIimpl implements I {
public void m2() { }
}
- @DeclareParents(value="Basic2b",defaultImpl=X.IImpl.class)
- private I simplefield;;
+ @DeclareParents(value="Basic2b",defaultImpl=X.IIimpl.class)
+ private I simplefield;
@Before("execution(* *(..))")
@Aspect class X {
interface I {
- public void m2();
- public void m3();
- public void m4();
+ public void m2();
+ public void m3();
+ public void m4();
}
- static class IImpl implements I {
+ public static class IIimpl implements I {
public void m2() { }
public void m3() { }
public void m4() { }
}
- @DeclareParents(value="Basic3b",defaultImpl=IImpl.class)
+ @DeclareParents(value="Basic3b",defaultImpl=X.IIimpl.class)
private I simplefield;
-
@Before("call(* *(..))")
public void advice1() {}
--- /dev/null
+package moodytest;
+
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.DeclareParents;
+
+@Aspect
+public class AnnotationMoodIndicator {
+ public interface Moody {
+ Mood getMood();
+ void setMood(Mood mood);
+ }
+
+ public static class MoodyImpl implements Moody {
+ Mood mood = Mood.HAPPY;
+
+ public Mood getMood() { return mood; }
+ public void setMood(Mood mood) { this.mood = mood; }
+ }
+
+ @DeclareParents(value="moodytest.AnnotationMoodyImplementor",defaultImpl=MoodyImpl.class)
+ private Moody introduced;
+}
--- /dev/null
+package moodytest;
+
+public class AnnotationMoodyImplementor {
+
+}
--- /dev/null
+package moodytest;
+
+public enum Mood {
+ HAPPY, SAD, CONFUSED
+}
--- /dev/null
+package moodytest;
+
+import moodytest.AnnotationMoodyImplementor;
+import moodytest.Mood;
+import junit.framework.TestCase;
+
+public class AnnotationMoodTester extends TestCase {
+ AnnotationMoodyImplementor ami0 = null;
+ AnnotationMoodyImplementor ami1 = null;
+
+ public AnnotationMoodTester(String name) { super(name); }
+
+ protected void setUp() throws Exception {
+ ami0 = new AnnotationMoodyImplementor();
+ ami1 = new AnnotationMoodyImplementor();
+ }
+
+ public void testHappyDefault() {
+ assertEquals("ami0 should be happy!", Mood.HAPPY, ami0.getMood());
+ }
+
+ public void testOneConfused() {
+ ami0.setMood(Mood.CONFUSED);
+ assertEquals("ami0 should now be confused", Mood.CONFUSED,
+ ami0.getMood());
+ assertEquals("ami1 should still be happy", Mood.HAPPY,
+ ami1.getMood());
+ }
+}
protected File getSpecFile() {
return new File("../tests/src/org/aspectj/systemtest/ajc150/ajc150.xml");
}
- public void testDecps1() { runTest("decps - 1");}
- public void testDecps1b() { runTest("decps - 1b");}
- public void testDecps2() { runTest("decps - 2");}
- public void testDecps2b() { runTest("decps - 2b");}
- public void testDecps3() { runTest("decps - 3");}
- public void testDecps3b() { runTest("decps - 3b");}
- public void testDecps3c() { runTest("decps - 3c");}
+
+ public void testDecps1() { runTest("decps - 1"); }
+ public void testDecps1b() { runTest("decps - 1b"); }
+ public void testDecps2() { runTest("decps - 2"); }
+ public void testDecps2b() { runTest("decps - 2b"); }
+ public void testDecps3() { runTest("decps - 3"); }
+ public void testDecps3b() { runTest("decps - 3b"); }
+ public void testDecps3c() { runTest("decps - 3c"); }
public void testVarargsNPE_pr120826() { runTest("varargs NPE");}
public void testNamedPointcutPertarget_pr120521() { runTest("named pointcut not resolved in pertarget pointcut");}
<run class="Pr114054"/>
</ajc-test>
-
+ <ajc-test dir="bugs150" pr="121385" title="mixing styles">
+ <compile files="pr121385.aj" options="-1.5"/>
+ </ajc-test>
+
<ajc-test dir="java5/decps" title="decps - 1">
<compile files="Basic1.java" options="-1.5"/>
<run class="Basic1"/>
<ajc-test dir="java5/decps" title="decps - 2b">
<compile files="Basic2b.java" options="-1.5 -showWeaveInfo">
- <message kind="weave" text="Join point 'method-execution(void X$IImpl.m2())' in Type 'X$IImpl' (Basic2b.java:18) advised by before advice from 'X' (Basic2b.java:27)"/>
+ <message kind="weave" text="Join point 'method-execution(void X$IIimpl.m2())' in Type 'X$IIimpl' (Basic2b.java:18) advised by before advice from 'X' (Basic2b.java:27)"/>
<message kind="weave" text="Extending interface set for type 'Basic2b' (Basic2b.java) to include 'X$I' (Basic2b.java)"/>
<message kind="weave" text="Join point 'method-execution(void Basic2b.main(java.lang.String[]))' in Type 'Basic2b' (Basic2b.java:4) advised by before advice from 'X' (Basic2b.java:27)"/>
</compile>
<message kind="weave" text="Type 'Basic3b' (Basic3b.java) has intertyped method from 'X' (Basic3b.java:'void X$I.m2()')"/>
<message kind="weave" text="Type 'Basic3b' (Basic3b.java) has intertyped method from 'X' (Basic3b.java:'void X$I.m3()')"/>
<message kind="weave" text="Type 'Basic3b' (Basic3b.java) has intertyped method from 'X' (Basic3b.java:'void X$I.m4()')"/>
- <message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3b' (Basic3b.java:7) advised by before advice from 'X' (Basic3b.java:36)"/>
- <message kind="weave" text="Join point 'method-call(void X$I.m3())' in Type 'Basic3b' (Basic3b.java:8) advised by before advice from 'X' (Basic3b.java:36)"/>
- <message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3b' (Basic3b.java:9) advised by before advice from 'X' (Basic3b.java:36)"/>
- <message kind="weave" text="Join point 'method-call(void X$I.m4())' in Type 'Basic3b' (Basic3b.java:10) advised by before advice from 'X' (Basic3b.java:36)"/>
+ <message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3b' (Basic3b.java:7) advised by before advice from 'X' (Basic3b.java:35)"/>
+ <message kind="weave" text="Join point 'method-call(void X$I.m3())' in Type 'Basic3b' (Basic3b.java:8) advised by before advice from 'X' (Basic3b.java:35)"/>
+ <message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3b' (Basic3b.java:9) advised by before advice from 'X' (Basic3b.java:35)"/>
+ <message kind="weave" text="Join point 'method-call(void X$I.m4())' in Type 'Basic3b' (Basic3b.java:10) advised by before advice from 'X' (Basic3b.java:35)"/>
</compile>
<run class="Basic3b"/>
</ajc-test>
<ajc-test dir="java5/decps" title="decps - 3c">
<compile files="Basic3c.java" options="-1.5">
+ <message kind="error" text="@DeclareParents: defaultImpl="X$IImpl" has no public no-arg constructor"/>
</compile>
- <run class="Basic3c"/>
</ajc-test>
runTest("AbstractAspectNPE");
}
+ public void testAbstractInherited() {
+ runTest("AbstractInherited");
+ }
+
}
</compile>
</ajc-test>
+
+ <ajc-test dir="java5/ataspectj" title="AbstractInherited">
+ <compile files="ataspectj/bugs/AbstractInherited.java"
+ options="-1.5 -showWeaveInfo">
+ <message kind="weave" text="Join point "/>
+ </compile>
+ </ajc-test>
+
</suite>
\ No newline at end of file
System.getProperty("sun.boot.class.path") +
File.pathSeparator + "../runtime/bin" +
File.pathSeparator + System.getProperty("aspectjrt.path") +
+ File.pathSeparator + "../lib/junit/junit.jar" +
File.pathSeparator+".."+File.separator+"lib" + File.separator+"test"+File.separator+"aspectjrt.jar";
// look at dependant projects
build("PR115251");
checkWasntFullBuild();
}
+
+ public void testPr121384() {
+// AjdeInteractionTestbed.VERBOSE=true;
+// AsmManager.setReporting("c:/foo.txt",true,true,true,false);
+ MyBuildOptionsAdapter.setNonStandardOptions("-showWeaveInfo");
+ configureBuildStructureModel(true);
+ initialiseProject("pr121384");
+ build("pr121384");
+ checkWasFullBuild();
+ alter("pr121384","inc1");
+ build("pr121384");
+ checkWasntFullBuild();
+ }
/* public void testPr111779() {
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
-import java.lang.reflect.Modifier;
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.LocalVariableTable;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
+import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnotations;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations;
-import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.WeaverMessages;
-import org.aspectj.weaver.NewFieldTypeMunger;
-import org.aspectj.weaver.ResolvedMemberImpl;
-import org.aspectj.weaver.Member;
import org.aspectj.weaver.patterns.AndPointcut;
import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
import org.aspectj.weaver.patterns.DeclareParents;
if (fieldType.isInterface()) {
TypePattern parent = new ExactTypePattern(UnresolvedType.forSignature(struct.field.getSignature()), false, false);
parent.resolve(struct.enclosingType.getWorld());
- //TODO kick ISourceLocation sl = struct.bField.getSourceLocation(); ??
// first add the declare implements like
List parents = new ArrayList(1); parents.add(parent);
+ DeclareParents dp = new DeclareParents(
+ typePattern,
+ parents,
+ false
+ );
+ //TODO kick ISourceLocation sl = struct.bField.getSourceLocation(); ??
+ dp.setLocation(struct.context,0,0); // not ideal...
struct.ajAttributes.add(
new AjAttribute.DeclareAttribute(
- new DeclareParents(
- typePattern,
- parents,
- false
- )
+ dp
)
);
defaultImplClassName = UnresolvedType.forSignature(defaultImpl.getClassString()).getName();
if (defaultImplClassName.equals("org.aspectj.lang.annotation.DeclareParents")) {
defaultImplClassName = null;
+ } else {
+ // check public no arg ctor
+ ResolvedType impl = struct.enclosingType.getWorld().resolve(
+ defaultImplClassName,
+ false
+ );
+ ResolvedMember[] mm = impl.getDeclaredMethods();
+ boolean hasNoCtorOrANoArgOne = true;
+ for (int i = 0; i < mm.length; i++) {
+ ResolvedMember resolvedMember = mm[i];
+ if (resolvedMember.getName().equals("<init>")) {
+ hasNoCtorOrANoArgOne = false;
+ if (resolvedMember.getParameterTypes().length == 0
+ && resolvedMember.isPublic()) {
+ hasNoCtorOrANoArgOne = true;
+ }
+ }
+ if (hasNoCtorOrANoArgOne) {
+ break;
+ }
+ }
+ if (!hasNoCtorOrANoArgOne) {
+ reportError("@DeclareParents: defaultImpl=\""
+ + defaultImplClassName
+ + "\" has no public no-arg constructor", struct);
+ }
}
- //TODO check public no arg ctor
+
}
// then iterate on field interface hierarchy (not object)
return false;
}
hasAtLeastOneMethod = true;
-
+
struct.ajAttributes.add(
new AjAttribute.TypeMunger(
new MethodDelegateTypeMunger(
}
} else if (hasExtraParameter()) {
previousIsClosure = false;
- extraVar.appendLoadAndConvert(
- il,
- fact,
- getExtraParameterType().resolve(world));
- } else {
+ //extra var can be null here (@Aj aspect extends abstract code style, advice in code style)
+ if (extraVar != null) {
+ extraVar.appendLoadAndConvert(
+ il,
+ fact,
+ getExtraParameterType().resolve(world));
+ }
+ } else {
previousIsClosure = false;
getConcreteAspect().getWorld().getMessageHandler().handleMessage(
new Message(
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
+import org.aspectj.apache.bcel.generic.BranchInstruction;
import org.aspectj.apache.bcel.generic.ConstantPoolGen;
import org.aspectj.apache.bcel.generic.FieldGen;
import org.aspectj.apache.bcel.generic.INVOKESPECIAL;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.Type;
-import org.aspectj.apache.bcel.generic.BranchInstruction;
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.World;
import org.aspectj.weaver.patterns.DeclareAnnotation;
import org.aspectj.weaver.patterns.Pointcut;
-import org.aspectj.lang.Signature;
//XXX addLazyMethodGen is probably bad everywhere
public class BcelTypeMunger extends ConcreteTypeMunger {