diff options
author | Andy Clement <aclement@pivotal.io> | 2019-01-30 16:55:38 -0800 |
---|---|---|
committer | Andy Clement <aclement@pivotal.io> | 2019-01-30 16:55:38 -0800 |
commit | 2b24e7377da7c849fe7f9f4fa06a701664f9d27d (patch) | |
tree | 64c36c8fcf29633af7a5e2f7405b94cbec629ca8 /tests/src/test/java/org/aspectj/systemtest/ajc169/TransparentWeavingTests.java | |
parent | d60de8d0b3e62eb36b612a824bb9345d865c0155 (diff) | |
download | aspectj-2b24e7377da7c849fe7f9f4fa06a701664f9d27d.tar.gz aspectj-2b24e7377da7c849fe7f9f4fa06a701664f9d27d.zip |
mavenizing tests - wip
Diffstat (limited to 'tests/src/test/java/org/aspectj/systemtest/ajc169/TransparentWeavingTests.java')
-rw-r--r-- | tests/src/test/java/org/aspectj/systemtest/ajc169/TransparentWeavingTests.java | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/tests/src/test/java/org/aspectj/systemtest/ajc169/TransparentWeavingTests.java b/tests/src/test/java/org/aspectj/systemtest/ajc169/TransparentWeavingTests.java new file mode 100644 index 000000000..a32f4f15e --- /dev/null +++ b/tests/src/test/java/org/aspectj/systemtest/ajc169/TransparentWeavingTests.java @@ -0,0 +1,244 @@ +/******************************************************************************* + * Copyright (c) 2008 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial API and implementation + *******************************************************************************/ +package org.aspectj.systemtest.ajc169; + +import java.io.File; +import java.lang.reflect.Modifier; + +import junit.framework.Test; + +import org.aspectj.apache.bcel.classfile.Field; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.testing.XMLBasedAjcTestCase; + +/** + * What would a completely transparent weave be? Is there a minimal subset that makes sense? What is the roadmap to get there? What + * needs testing + * + * --- 'Transparent' here is meaning that the resultant bytecode is more representative of the original declarations, so that it + * looks like the intertype declaration and associated constructs have been seamless added to the affected targets. + * + * + * Fully transparent weaving, what would we like to have: - ITDs appear exactly as declared: 'private int A.i' will create 'private + * int i' in A + * + * - What is the benefit? - although this isn't really in keeping with the AspectJ definition of what an ITD represents, having the + * end result look like the declaration does make it easier for users simply looking at the resultant class file or attempting + * reflection to access what they just ITD'd in place + * + * + * testing For transparent weaving of ITD fields - annotations on new fields - AJDT model - AjType support - what happens to it? - + * advice on within() how does that get affected? - visibility - accessors created when required? - handling clashes with existing + * fields - handling clashes with other aspects - generic declarations - interface declarations - initializers - static and + * non-static - accessibility from advice, for read and write + * + * Design<br> + * The intention will be 'new code' uses the new style whilst old code continues to cause the old code to be built. Whether the code + * wants to use the old or new naming should be apparent from the + * + * @author Andy Clement + */ +public class TransparentWeavingTests extends org.aspectj.testing.XMLBasedAjcTestCase { + + // Simple private ITD onto a target + public void testSimplePrivate() throws Exception { + runTest("one - private"); + checkForField("OnePrivate", Modifier.PRIVATE, "x"); + } + + // Default visibility ITD field + public void testSimpleDefault() throws Exception { + runTest("one - default"); + checkForField("OneDefault", 0, "x"); + } + + // annotated private ITD + public void testSimplePrivateAnnotated() throws Exception { + runTest("one - private - annotated"); + Field f = checkForField("OnePrivateAnnotated", Modifier.PRIVATE, "x"); + AnnotationGen[] annos = f.getAnnotations(); + assertTrue(annos.length > 0); // 0==Anno 1==ajcITD + assertEquals("LAnno;", annos[0].getTypeSignature()); + } + + // annotated default ITD + public void testSimpleDefaultAnnotated() throws Exception { + runTest("one - default - annotated"); + Field f = checkForField("OneDefaultAnnotated", 0, "x"); + AnnotationGen[] annos = f.getAnnotations(); + assertTrue(annos.length > 0); // 0==Anno 1==ajcITD + assertEquals("LAnno;", annos[0].getTypeSignature()); + } + + // Simple private ITD with getter/setter usage + public void testSimplePrivateWithAccessors() throws Exception { + runTest("one - private - accessors"); + } + + // check initializer runs OK + public void testSimplePrivateInitializer() throws Exception { + runTest("one - private - initializer"); + } + + public void testDeclareAtOnPrivateItd() throws Exception { + runTest("declare at on private itd"); + Field f = checkForField("OneDeclareAt", Modifier.PRIVATE, "x"); + AnnotationGen[] annos = f.getAnnotations(); + assertTrue(annos.length > 0); // 1==Anno 0==ajcITD + assertEquals("LAnno;", annos[1].getTypeSignature()); + } + + // declare @field on a field that already has one + public void testDeclareAtTwo() throws Exception { + runTest("declare at two"); + Field f = checkForField("DeclareAtTwo", Modifier.PRIVATE, "x"); + AnnotationGen[] annos = f.getAnnotations(); + assertTrue(annos.length > 2); // 1==Anno 0==ajcITD + assertEquals("LAnno;", annos[0].getTypeSignature()); + assertEquals("LAnno2;", annos[2].getTypeSignature()); + } + + public void testTwoItdsOnTarget() throws Exception { + runTest("two itds on target"); + // Aspect X gets the field, aspect Y gets a mangled one + if (hasField("TwoItdsOnTarget", "ajc$interField$Y$x")) { + checkForField("TwoItdsOnTarget", Modifier.PRIVATE, "x"); + checkForField("TwoItdsOnTarget", Modifier.PUBLIC, "ajc$interField$Y$x"); + } else { + checkForField("TwoItdsOnTarget", Modifier.PRIVATE, "x"); + checkForField("TwoItdsOnTarget", Modifier.PUBLIC, "ajc$interField$X$x"); + } + } + + public void testTwoItdsOnTargetThatAlreadyHasIt() throws Exception { + runTest("two itds on target that already has it"); + // Aspect X gets the field, aspect Y gets a mangled one + checkForField("TwoItdsOnTargetHasAlready", Modifier.PUBLIC, "ajc$interField$X$x"); + checkForField("TwoItdsOnTargetHasAlready", Modifier.PUBLIC, "ajc$interField$Y$x"); + } + + public void testInteractingOldAndNew() throws Exception { + runTest("interacting old and new"); + int SYNTHETIC = 0x00001000; // 4096 + if (hasField("InteractingOldAndNew", "ajc$interField$Y$i")) { + checkForField("InteractingOldAndNew", Modifier.PRIVATE, "i"); + checkForField("InteractingOldAndNew", Modifier.PUBLIC, "ajc$interField$Y$i"); + } else { + checkForField("InteractingOldAndNew", Modifier.PRIVATE, "i"); + checkForField("InteractingOldAndNew", Modifier.PUBLIC, "ajc$interField$X$i"); + } + checkForMethod("InteractingOldAndNew", Modifier.PUBLIC | Modifier.STATIC, "main"); + checkForMethod("InteractingOldAndNew", Modifier.PUBLIC | Modifier.STATIC | SYNTHETIC, "ajc$get$i"); + checkForMethod("InteractingOldAndNew", Modifier.PUBLIC | Modifier.STATIC | SYNTHETIC, "ajc$set$i"); + checkForMethod("InteractingOldAndNew", Modifier.PUBLIC, "getI1"); + checkForMethod("InteractingOldAndNew", Modifier.PUBLIC, "getI2"); + checkForMethod("InteractingOldAndNew", Modifier.PUBLIC, "setI1"); + checkForMethod("InteractingOldAndNew", Modifier.PUBLIC, "setI2"); + } + + public void testPrivateGenerics() throws Exception { + runTest("generics - private"); + Field f = checkForField("Generics", Modifier.PRIVATE, "listOfString"); + assertEquals("Ljava/util/List<Ljava/lang/String;>;", f.getGenericSignature()); + f = checkForField("Generics", Modifier.PRIVATE, "thing"); + assertEquals("TX;", f.getGenericSignature()); + } + + // --- + + private boolean hasField(String clazzname, String name) { + try { + JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), clazzname); + Field[] fs = jc.getFields(); + StringBuffer fields = new StringBuffer(); + for (Field f : fs) { + fields.append(f.getName()).append(" "); + if (f.getName().equals(name)) { + return true; + } + } + } catch (Exception e) { + return false; + } + return false; + } + + private Field checkForField(String clazzname, int modifiers, String name) throws Exception { + JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), clazzname); + Field[] fs = jc.getFields(); + StringBuffer fields = new StringBuffer(); + for (Field f : fs) { + fields.append(f.getName()).append(" "); + if (f.getName().equals(name)) { + if (f.getModifiers() != modifiers) { + fail("Found field " + name + " in " + clazzname + " but modifiers were wrong, they were " + f.getModifiers()); + } + return f; + } + } + fail("Did not find field " + name + " in class " + clazzname + ". Found fields: " + fields.toString()); + return null; + } + + private Method checkForMethod(String clazzname, int modifiers, String name) throws Exception { + JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), clazzname); + Method[] fs = jc.getMethods(); + StringBuffer methods = new StringBuffer(); + methods.append("\n"); + for (Method f : fs) { + methods.append(f.getName()).append("\n"); + if (f.getName().equals(name)) { + if (f.getModifiers() != modifiers) { + fail("Found method " + name + " in " + clazzname + " but modifiers were wrong, they were " + f.getModifiers()); + } + return f; + } + System.out.println(f.getGenericSignature()); + } + fail("Did not find method " + name + " in class " + clazzname + ". Found methods: " + methods.toString()); + return null; + } + + // public itd onto a target that already has a field of that name + // just to check what goes wrong and who checks it + public void testPublicClash() throws Exception { + runTest("two"); + } + + public void testPrivateClash() throws Exception { + runTest("three"); + + JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), "Three"); + Field[] fs = jc.getFields(); + for (Field f : fs) { + System.out.println(f); + } + + // public int ajc$interField$X$xPrivate [RuntimeVisibleAnnotations] + // public Integer ajc$interField$$yDefault [RuntimeVisibleAnnotations] + // public String zPublic [RuntimeVisibleAnnotations] + + } + + // -- + + public static Test suite() { + return XMLBasedAjcTestCase.loadSuite(TransparentWeavingTests.class); + } + + @Override + protected File getSpecFile() { + return getClassResource("transparentweaving.xml"); + } + +}
\ No newline at end of file |