Modified test expectation system so it is possible to say the test cares about one particular message and the rest do not matter (prefix message string with '*') - crude but quick. Polished many places to exploit generics Upgraded all the tests to work on Java8 - some serious changes regarding ajdoc on Java8. Hopefully it has stayed backwards compatible with earlier JDK versions (e.g. if using AspectJ 1.8.3+ with a JDK less than 8) but no explicit testing done for this.tags/V1_8_3
@@ -0,0 +1 @@ | |||
@@ -1,12 +0,0 @@ | |||
#Thu Oct 06 08:32:56 PDT 2005 | |||
eclipse.preferences.version=1 | |||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled | |||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.1 | |||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | |||
org.eclipse.jdt.core.compiler.compliance=1.3 | |||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate | |||
org.eclipse.jdt.core.compiler.debug.localVariable=generate | |||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate | |||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=ignore | |||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=ignore | |||
org.eclipse.jdt.core.compiler.source=1.3 |
@@ -224,7 +224,20 @@ class HtmlDecorator { | |||
classStartIndex = fileContents.toString().indexOf("<H2>\nClass "); | |||
br = false; | |||
} | |||
if (classStartIndex != -1) { | |||
if (classStartIndex == -1) { | |||
// Java8 looks more like this: | |||
// <h2 title="Class A" class="title">Class A</h2> | |||
classStartIndex = fileContents.toString().indexOf("<h2 title=\"Class "); | |||
int classEndIndex = fileContents.toString().indexOf("</h2>", classStartIndex); | |||
if (classEndIndex != -1) { | |||
// Convert it to "<h2 title="Aspect A" class="title">Aspect A</h2>" | |||
String classLine = fileContents.toString().substring(classStartIndex, classEndIndex); | |||
String aspectLine = classLine.replaceAll("Class ","Aspect "); | |||
fileContents.delete(classStartIndex, classEndIndex); | |||
fileContents.insert(classStartIndex, aspectLine); | |||
} | |||
} | |||
else if (classStartIndex != -1) { | |||
int classEndIndex = fileContents.toString().indexOf("</H2>", classStartIndex); | |||
if (classStartIndex != -1 && classEndIndex != -1) { | |||
String classLine = fileContents.toString().substring(classStartIndex, classEndIndex); | |||
@@ -249,6 +262,19 @@ class HtmlDecorator { | |||
fileContents.insert(secondClassStartIndex, sb.toString()); | |||
} | |||
} | |||
else { | |||
// Java8: | |||
// <pre>static class <span class="typeNameLabel">ClassA.InnerAspect</span> | |||
classStartIndex = fileContents.toString().indexOf("class <span class=\"typeNameLabel\">"); | |||
int classEndIndex = fileContents.toString().indexOf("</span>", classStartIndex); | |||
if (classEndIndex != -1) { | |||
// Convert it to "aspect <span class="typeNameLabel">ClassA.InnerAspect</span>" | |||
String classLine = fileContents.toString().substring(classStartIndex, classEndIndex); | |||
String aspectLine = "aspect"+fileContents.substring(classStartIndex+5,classEndIndex); | |||
fileContents.delete(classStartIndex, classEndIndex); | |||
fileContents.insert(classStartIndex, aspectLine); | |||
} | |||
} | |||
} | |||
} | |||
file.delete(); |
@@ -50,20 +50,18 @@ public class AjdocOutputChecker { | |||
} | |||
/** | |||
* Returns those strings from the given array which aren't in the | |||
* html file | |||
* Returns those strings from the given array which aren't in the html file. | |||
* | |||
* @param htmlFile | |||
* @param an array of requiredStrings | |||
* @return a List of those strings not found | |||
* @throws Exception | |||
*/ | |||
public static List /*String*/ getMissingStringsInFile(File htmlFile, | |||
String[] requiredStrings) throws Exception { | |||
List missingStrings = new ArrayList(); | |||
public static List<String> getMissingStringsInFile(File htmlFile, String[] requiredStrings) throws Exception { | |||
List<String> missingStrings = new ArrayList<String>(); | |||
for (int i = 0; i < requiredStrings.length; i++) { | |||
String string = requiredStrings[i]; | |||
if (!containsString(htmlFile,string)) { | |||
if (!containsString(htmlFile, string)) { | |||
missingStrings.add(string); | |||
} | |||
} |
@@ -14,8 +14,11 @@ | |||
import java.io.File; | |||
import java.util.List; | |||
import org.aspectj.util.FileUtil; | |||
import org.aspectj.util.LangUtil; | |||
import com.sun.org.apache.xml.internal.serializer.utils.Utils; | |||
/** | |||
* A long way to go until full coverage, but this is the place to add more. | |||
@@ -128,14 +131,39 @@ public class CoverageTestCase extends AjdocTestCase { | |||
// ensure that the file is entitled "Aspect ClassA.InnerAspect" rather | |||
// than "Class ClassA.InnerAspect" | |||
String[] strings = { "Aspect ClassA.InnerAspect", | |||
String[] strings = null; | |||
if (LangUtil.is18VMOrGreater()) { | |||
strings = new String[] { | |||
"Aspect ClassA.InnerAspect", | |||
"<pre>static aspect <span class=\"typeNameLabel\">ClassA.InnerAspect</span>", | |||
"Class ClassA.InnerAspect", | |||
"<pre>static class <span class=\"typeNameLabel\">ClassA.InnerAspect</span>"}; | |||
} | |||
else { | |||
strings = new String[] { | |||
"Aspect ClassA.InnerAspect", | |||
"<PRE>static aspect <B>ClassA.InnerAspect</B><DT>extends java.lang.Object</DL>", | |||
"Class ClassA.InnerAspect", | |||
"<PRE>static class <B>ClassA.InnerAspect</B><DT>extends java.lang.Object</DL>"}; | |||
List missing = AjdocOutputChecker.getMissingStringsInFile(htmlFile,strings); | |||
assertEquals("There should be 2 missing strings",2,missing.size()); | |||
assertTrue(htmlFile.getName() + " should not have Class as it's title",missing.contains("Class ClassA.InnerAspect")); | |||
assertTrue(htmlFile.getName() + " should not have class in its subtitle",missing.contains("<PRE>static class <B>ClassA.InnerAspect</B><DT>extends java.lang.Object</DL>")); | |||
} | |||
List<String> missingStrings = AjdocOutputChecker.getMissingStringsInFile(htmlFile,strings); | |||
StringBuilder buf = new StringBuilder(); | |||
for (String str:missingStrings) { | |||
buf.append(str).append("\n"); | |||
} | |||
buf.append("HTMLFILE=\n").append(htmlFile).append("\n"); | |||
assertEquals("There should be 2 missing strings:\n"+buf.toString(), 2, missingStrings.size()); | |||
assertTrue(htmlFile.getName() + " should not have Class as it's title", | |||
missingStrings.contains("Class ClassA.InnerAspect")); | |||
if (LangUtil.is18VMOrGreater()) { | |||
assertTrue(htmlFile.getName() + " should not have class in its subtitle", | |||
missingStrings.contains("<pre>static class <span class=\"typeNameLabel\">ClassA.InnerAspect</span>")); | |||
} | |||
else { | |||
assertTrue(htmlFile.getName() + " should not have class in its subtitle", | |||
missingStrings.contains("<PRE>static class <B>ClassA.InnerAspect</B><DT>extends java.lang.Object</DL>")); | |||
} | |||
// get the html file for the enclosing class | |||
File htmlFileClass = new File(getAbsolutePathOutdir() + "/foo/ClassA.html"); | |||
@@ -146,14 +174,33 @@ public class CoverageTestCase extends AjdocTestCase { | |||
// ensure that the file is entitled "Class ClassA" and | |||
// has not been changed to "Aspect ClassA" | |||
String[] classStrings = { "Class ClassA</H2>", | |||
"public abstract class <B>ClassA</B><DT>extends java.lang.Object<DT>", | |||
String[] classStrings = null; | |||
if (LangUtil.is18VMOrGreater()) { | |||
classStrings = new String[] { | |||
"Class ClassA</h2>", | |||
"public abstract class <span class=\"typeNameLabel\">ClassA</span>", | |||
"Aspect ClassA</H2>", | |||
"public abstract aspect <B>ClassA</B><DT>extends java.lang.Object<DT>"}; | |||
"public abstract aspect <span class=\"typeNameLabel\">ClassA</span>"}; | |||
} | |||
else { | |||
classStrings = new String[] { | |||
"Class ClassA</H2>", | |||
"public abstract class <B>ClassA</B><DT>extends java.lang.Object<DT>", | |||
"Aspect ClassA</H2>", | |||
"public abstract aspect <B>ClassA</B><DT>extends java.lang.Object<DT>"}; | |||
} | |||
List classMissing = AjdocOutputChecker.getMissingStringsInFile(htmlFileClass,classStrings); | |||
assertEquals("There should be 2 missing strings",2,classMissing.size()); | |||
assertEquals("There should be 2 missing strings:\n"+classMissing,2,classMissing.size()); | |||
assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title",classMissing.contains("Aspect ClassA</H2>")); | |||
assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle",classMissing.contains("public abstract aspect <B>ClassA</B><DT>extends java.lang.Object<DT>")); | |||
if (LangUtil.is18VMOrGreater()) { | |||
assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle", | |||
classMissing.contains("public abstract aspect <span class=\"typeNameLabel\">ClassA</span>")); | |||
} | |||
else { | |||
assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle", | |||
classMissing.contains("public abstract aspect <B>ClassA</B><DT>extends java.lang.Object<DT>")); | |||
} | |||
} | |||
/** | |||
@@ -623,15 +670,32 @@ public class CoverageTestCase extends AjdocTestCase { | |||
// ensure that the file is entitled "Aspect PkgVisibleClass.NestedAspect" rather | |||
// than "Class PkgVisibleClass.NestedAspect" | |||
String[] strings = { "Aspect PkgVisibleClass.NestedAspect", | |||
"<PRE>static aspect <B>PkgVisibleClass.NestedAspect</B><DT>extends java.lang.Object</DL>", | |||
"Class PkgVisibleClass.NestedAspect", | |||
"<PRE>static class <B>PkgVisibleClass.NestedAspect</B><DT>extends java.lang.Object</DL>"}; | |||
List missing = AjdocOutputChecker.getMissingStringsInFile(htmlFile,strings); | |||
String[] strings = null; | |||
if (LangUtil.is18VMOrGreater()) { | |||
strings = new String[] { | |||
"Aspect PkgVisibleClass.NestedAspect", | |||
"<pre>static aspect <span class=\"typeNameLabel\">PkgVisibleClass.NestedAspect</span>", | |||
"Class PkgVisibleClass.NestedAspect", | |||
"<pre>static class <span class=\"typeNameLabel\">PkgVisibleClass.NestedAspect</span>"}; | |||
} | |||
else { | |||
strings = new String[] { | |||
"Aspect PkgVisibleClass.NestedAspect", | |||
"<PRE>static aspect <B>PkgVisibleClass.NestedAspect</B><DT>extends java.lang.Object</DL>", | |||
"Class PkgVisibleClass.NestedAspect", | |||
"<PRE>static class <B>PkgVisibleClass.NestedAspect</B><DT>extends java.lang.Object</DL>"}; | |||
} | |||
List<String> missing = AjdocOutputChecker.getMissingStringsInFile(htmlFile,strings); | |||
assertEquals("There should be 2 missing strings",2,missing.size()); | |||
assertTrue(htmlFile.getName() + " should not have Class as it's title",missing.contains("Class PkgVisibleClass.NestedAspect")); | |||
assertTrue(htmlFile.getName() + " should not have class in its subtitle",missing.contains("<PRE>static class <B>PkgVisibleClass.NestedAspect</B><DT>extends java.lang.Object</DL>")); | |||
if (LangUtil.is18VMOrGreater()) { | |||
assertTrue(htmlFile.getName() + " should not have class in its subtitle", | |||
missing.contains("<pre>static class <span class=\"typeNameLabel\">PkgVisibleClass.NestedAspect</span>")); | |||
} | |||
else { | |||
assertTrue(htmlFile.getName() + " should not have class in its subtitle", | |||
missing.contains("<PRE>static class <B>PkgVisibleClass.NestedAspect</B><DT>extends java.lang.Object</DL>")); | |||
} | |||
// get the html file for the enclosing class | |||
File htmlFileClass = new File(getAbsolutePathOutdir() + "/PkgVisibleClass.html"); | |||
if (!htmlFileClass.exists()) { | |||
@@ -641,14 +705,33 @@ public class CoverageTestCase extends AjdocTestCase { | |||
// ensure that the file is entitled "Class PkgVisibleClass" and | |||
// has not been changed to "Aspect PkgVisibleClass" | |||
String[] classStrings = { "Class PkgVisibleClass</H2>", | |||
"class <B>PkgVisibleClass</B><DT>extends java.lang.Object</DL>", | |||
"Aspect PkgVisibleClass</H2>", | |||
"aspect <B>PkgVisibleClass</B><DT>extends java.lang.Object<DT>"}; | |||
List classMissing = AjdocOutputChecker.getMissingStringsInFile(htmlFileClass,classStrings); | |||
String[] classStrings = null; | |||
if (LangUtil.is18VMOrGreater()) { | |||
classStrings = new String[] { | |||
"Class PkgVisibleClass</h2>", | |||
"<pre>class <span class=\"typeNameLabel\">PkgVisibleClass</span>", | |||
"Aspect PkgVisibleClass</h2>", | |||
"<pre>aspect <span class=\"typeNameLabel\">PkgVisibleClass</span>"}; | |||
} | |||
else { | |||
classStrings = new String[] { | |||
"Class PkgVisibleClass</H2>", | |||
"class <B>PkgVisibleClass</B><DT>extends java.lang.Object</DL>", | |||
"Aspect PkgVisibleClass</H2>", | |||
"aspect <B>PkgVisibleClass</B><DT>extends java.lang.Object<DT>"}; | |||
} | |||
List<String> classMissing = AjdocOutputChecker.getMissingStringsInFile(htmlFileClass,classStrings); | |||
assertEquals("There should be 2 missing strings",2,classMissing.size()); | |||
assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title",classMissing.contains("Aspect PkgVisibleClass</H2>")); | |||
assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle",classMissing.contains("aspect <B>PkgVisibleClass</B><DT>extends java.lang.Object<DT>")); | |||
if (LangUtil.is18VMOrGreater()) { | |||
assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title", | |||
classMissing.contains("Aspect PkgVisibleClass</h2>")); | |||
assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle", | |||
classMissing.contains("<pre>aspect <span class=\"typeNameLabel\">PkgVisibleClass</span>")); | |||
} | |||
else { | |||
assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title",classMissing.contains("Aspect PkgVisibleClass</H2>")); | |||
assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle",classMissing.contains("aspect <B>PkgVisibleClass</B><DT>extends java.lang.Object<DT>")); | |||
} | |||
} | |||
/** | |||
@@ -668,14 +751,31 @@ public class CoverageTestCase extends AjdocTestCase { | |||
} | |||
// ensure that the file is entitled "Aspect ClassWithNestedAspect.NestedAspect" | |||
// rather than "Class ClassWithNestedAspect.NestedAspect" | |||
String[] strings = { "Aspect ClassWithNestedAspect.NestedAspect", | |||
"<PRE>static aspect <B>ClassWithNestedAspect.NestedAspect</B><DT>extends java.lang.Object</DL>", | |||
String[] strings = null; | |||
if (LangUtil.is18VMOrGreater()) { | |||
strings = new String [] { | |||
"Aspect ClassWithNestedAspect.NestedAspect", | |||
"<pre>static aspect <span class=\"typeNameLabel\">ClassWithNestedAspect.NestedAspect</span>", | |||
"Class ClassWithNestedAspect.NestedAspect", | |||
"<PRE>static class <B>ClassWithNestedAspect.NestedAspect</B><DT>extends java.lang.Object</DL>"}; | |||
List missing = AjdocOutputChecker.getMissingStringsInFile(htmlFile,strings); | |||
"<pre>static class <span class=\"typeNameLabel\">ClassWithNestedAspect.NestedAspect</span>"}; | |||
} | |||
else { | |||
strings = new String [] { | |||
"Aspect ClassWithNestedAspect.NestedAspect", | |||
"<PRE>static a;spect <B>ClassWithNestedAspect.NestedAspect</B><DT>extends java.lang.Object</DL>", | |||
"Class ClassWithNestedAspect.NestedAspect", | |||
"<PRE>static class <B>ClassWithNestedAspect.NestedAspect</B><DT>extends java.lang.Object</DL>"}; | |||
} | |||
List<String> missing = AjdocOutputChecker.getMissingStringsInFile(htmlFile,strings); | |||
assertEquals("There should be 2 missing strings",2,missing.size()); | |||
assertTrue(htmlFile.getName() + " should not have Class as it's title",missing.contains("Class ClassWithNestedAspect.NestedAspect")); | |||
assertTrue(htmlFile.getName() + " should not have class in its subtitle",missing.contains("<PRE>static class <B>ClassWithNestedAspect.NestedAspect</B><DT>extends java.lang.Object</DL>")); | |||
if (LangUtil.is18VMOrGreater()) { | |||
assertTrue(htmlFile.getName() + " should not have class in its subtitle", | |||
missing.contains("<pre>static class <span class=\"typeNameLabel\">ClassWithNestedAspect.NestedAspect</span>")); | |||
} | |||
else { | |||
assertTrue(htmlFile.getName() + " should not have class in its subtitle",missing.contains("<PRE>static class <B>ClassWithNestedAspect.NestedAspect</B><DT>extends java.lang.Object</DL>")); | |||
} | |||
// get the html file for the enclosing class | |||
File htmlFileClass = new File(getAbsolutePathOutdir() + "/pkg/ClassWithNestedAspect.html"); | |||
@@ -686,17 +786,35 @@ public class CoverageTestCase extends AjdocTestCase { | |||
// ensure that the file is entitled "Class ClassWithNestedAspect" and | |||
// has not been changed to "Aspect ClassWithNestedAspect" | |||
String[] classStrings = { "Class ClassWithNestedAspect</H2>", | |||
"public class <B>ClassWithNestedAspect</B><DT>extends java.lang.Object</DL>", | |||
"Aspect ClassWithNestedAspect</H2>", | |||
"public aspect <B>ClassWithNestedAspect</B><DT>extends java.lang.Object</DL>"}; | |||
List classMissing = AjdocOutputChecker.getMissingStringsInFile(htmlFileClass,classStrings); | |||
String[] classStrings = null; | |||
if (LangUtil.is18VMOrGreater()) { | |||
classStrings = new String[] { | |||
"Class ClassWithNestedAspect</h2>", | |||
"public class <span class=\"typeNameLabel\">ClassWithNestedAspect</span>", | |||
"Aspect ClassWithNestedAspect</h2>", | |||
"public aspect <span class=\"typeNameLabel\">ClassWithNestedAspect</span>"}; | |||
} | |||
else { | |||
classStrings = new String[] { | |||
"Class ClassWithNestedAspect</H2>", | |||
"public class <B>ClassWithNestedAspect</B><DT>extends java.lang.Object</DL>", | |||
"Aspect ClassWithNestedAspect</H2>", | |||
"public aspect <B>ClassWithNestedAspect</B><DT>extends java.lang.Object</DL>"}; | |||
} | |||
List<String> classMissing = AjdocOutputChecker.getMissingStringsInFile(htmlFileClass,classStrings); | |||
assertEquals("There should be 2 missing strings",2,classMissing.size()); | |||
assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title", | |||
classMissing.contains("Aspect ClassWithNestedAspect</H2>")); | |||
assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle", | |||
classMissing.contains("public aspect <B>ClassWithNestedAspect</B><DT>extends java.lang.Object</DL>")); | |||
if (LangUtil.is18VMOrGreater()) { | |||
assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title", | |||
classMissing.contains("Aspect ClassWithNestedAspect</h2>")); | |||
assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle", | |||
classMissing.contains("public aspect <span class=\"typeNameLabel\">ClassWithNestedAspect</span>")); | |||
} | |||
else { | |||
assertTrue(htmlFileClass.getName() + " should not have Aspect as it's title", | |||
classMissing.contains("Aspect ClassWithNestedAspect</H2>")); | |||
assertTrue(htmlFileClass.getName() + " should not have aspect in its subtitle", | |||
classMissing.contains("public aspect <B>ClassWithNestedAspect</B><DT>extends java.lang.Object</DL>")); | |||
} | |||
} | |||
/** |
@@ -0,0 +1,30 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2014 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 | |||
* ******************************************************************/ | |||
package org.aspectj.lang.annotation; | |||
import java.lang.annotation.ElementType; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
/** | |||
* Can be specified on an aspect to ensure that particular types must be accessible before | |||
* the aspect will be 'activated'. The array value should be a list of fully qualified | |||
* type names as strings, for example "com.foo.Bar". Useful in an aspect library that | |||
* includes a number of aspects, only a few of which should ever be active depending | |||
* upon what is on the classpath. | |||
* | |||
* @author Andy Clement | |||
* @since 1.8.3 | |||
*/ | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Target(ElementType.TYPE) | |||
public @interface RequiredTypes { | |||
String[] value(); | |||
} |
@@ -413,7 +413,7 @@ public class BuildArgParser extends Main { | |||
if (args.size() > nextArgIndex) { | |||
// buildConfig.getAjOptions().put(AjCompilerOptions.OPTION_Inpath, CompilerOptions.PRESERVE); | |||
List inPath = buildConfig.getInpath(); | |||
List<File> inPath = buildConfig.getInpath(); | |||
StringTokenizer st = new StringTokenizer(((ConfigParser.Arg) args.get(nextArgIndex)).getValue(), | |||
File.pathSeparator); | |||
while (st.hasMoreTokens()) { | |||
@@ -475,7 +475,7 @@ public class BuildArgParser extends Main { | |||
buildConfig.setMakeReflectable(true); | |||
} else if (arg.equals("-sourceroots")) { | |||
if (args.size() > nextArgIndex) { | |||
List sourceRoots = new ArrayList(); | |||
List<File> sourceRoots = new ArrayList<File>(); | |||
StringTokenizer st = new StringTokenizer(((ConfigParser.Arg) args.get(nextArgIndex)).getValue(), | |||
File.pathSeparator); | |||
while (st.hasMoreTokens()) { |
@@ -211,6 +211,10 @@ public class AspectDeclaration extends TypeDeclaration { | |||
// For e37 moved the check down to this level | |||
return; | |||
} | |||
if ((binding.tagBits & TagBits.AnnotationResolved) != 0) { | |||
// possibly resolution occurred during hasUnsatisfiedDependency()... | |||
binding.tagBits = (binding.tagBits & ~TagBits.AnnotationResolved); | |||
} | |||
Annotation atAspectAnnotation = AtAspectJAnnotationFactory.createAspectAnnotation(perClause.toDeclarationString(), | |||
declarationSourceStart); | |||
Annotation privilegedAnnotation = null; | |||
@@ -230,6 +234,7 @@ public class AspectDeclaration extends TypeDeclaration { | |||
System.arraycopy(old, 0, annotations, 0, old.length); | |||
System.arraycopy(toAdd, 0, annotations, old.length, toAdd.length); | |||
} | |||
TypeDeclaration.resolveAnnotations(staticInitializerScope, annotations, binding); | |||
} | |||
public void generateCode(ClassFile enclosingClassFile) { |
@@ -682,7 +682,7 @@ public class EclipseSourceType extends AbstractReferenceTypeDelegate { | |||
*/ | |||
public AnnotationAJ[] getAnnotations() { | |||
int declarationAnnoCount = (declaration.annotations == null ? 0 : declaration.annotations.length); | |||
if (annotations != null && annotations.length==declarationAnnoCount) { | |||
if (annotations != null && annotations.length == declarationAnnoCount) { | |||
return annotations; // only do this once | |||
} | |||
if (!annotationsFullyResolved || annotations.length!=declarationAnnoCount) { | |||
@@ -700,6 +700,10 @@ public class EclipseSourceType extends AbstractReferenceTypeDelegate { | |||
} | |||
return annotations; | |||
} | |||
public boolean hasAnnotations() { | |||
return (declaration.annotations != null && declaration.annotations.length != 0); | |||
} | |||
/** | |||
* Convert one eclipse annotation into an AnnotationX object containing an AnnotationAJ object. |
@@ -138,6 +138,7 @@ public class AjcTestCase extends TestCase { | |||
private String text; | |||
private String sourceFileName; | |||
private ISourceLocation[] seeAlsos; | |||
public boolean careAboutOtherMessages = true; | |||
/** | |||
* Create a message that will match any compiler message on the given line. | |||
@@ -153,6 +154,11 @@ public class AjcTestCase extends TestCase { | |||
public Message(int line, String text) { | |||
this.line = line; | |||
this.text = text; | |||
if (this.text != null && text.startsWith("*")) { | |||
// Don't care what other messages are around | |||
this.careAboutOtherMessages = false; | |||
this.text = this.text.substring(1); | |||
} | |||
} | |||
/** | |||
@@ -181,6 +187,11 @@ public class AjcTestCase extends TestCase { | |||
this.sourceFileName = srcFileName.toString(); | |||
} | |||
this.text = text; | |||
if (this.text != null && text.startsWith("*")) { | |||
// Don't care what other messages are around | |||
this.careAboutOtherMessages = false; | |||
this.text = this.text.substring(1); | |||
} | |||
this.seeAlsos = seeAlso; | |||
} | |||
@@ -189,6 +200,11 @@ public class AjcTestCase extends TestCase { | |||
*/ | |||
public Message(String text) { | |||
this.text = text; | |||
if (this.text != null && text.startsWith("*")) { | |||
// Don't care what other messages are around | |||
this.careAboutOtherMessages = false; | |||
this.text = this.text.substring(1); | |||
} | |||
} | |||
/** | |||
@@ -288,11 +304,11 @@ public class AjcTestCase extends TestCase { | |||
Collections.EMPTY_LIST, Collections.EMPTY_LIST); | |||
boolean ignoreInfos = true; | |||
public List fails; | |||
public List infos; | |||
public List warnings; | |||
public List errors; | |||
public List weaves; | |||
public List<AjcTestCase.Message> fails; | |||
public List<AjcTestCase.Message> infos; | |||
public List<AjcTestCase.Message> warnings; | |||
public List<AjcTestCase.Message> errors; | |||
public List<AjcTestCase.Message> weaves; | |||
/** | |||
* Set to true to enable or disable comparison of information messages. | |||
@@ -317,24 +333,25 @@ public class AjcTestCase extends TestCase { | |||
* @param errors The set of error messages to test for - can pass null to indicate empty set. | |||
* @param fails The set of fail or abort messages to test for - can pass null to indicate empty set. | |||
*/ | |||
public MessageSpec(List infos, List warnings, List errors, List fails, List weaves) { | |||
public MessageSpec(List<AjcTestCase.Message> infos, List<AjcTestCase.Message> warnings, | |||
List<AjcTestCase.Message> errors, List<AjcTestCase.Message> fails, List<AjcTestCase.Message> weaves) { | |||
if (infos != null) { | |||
this.infos = infos; | |||
ignoreInfos = false; | |||
} else { | |||
this.infos = Collections.EMPTY_LIST; | |||
this.infos = Collections.emptyList(); | |||
} | |||
this.warnings = ((warnings == null) ? Collections.EMPTY_LIST : warnings); | |||
this.errors = ((errors == null) ? Collections.EMPTY_LIST : errors); | |||
this.fails = ((fails == null) ? Collections.EMPTY_LIST : fails); | |||
this.weaves = ((weaves == null) ? Collections.EMPTY_LIST : weaves); | |||
this.warnings = ((warnings == null) ? Collections.<AjcTestCase.Message>emptyList() : warnings); | |||
this.errors = ((errors == null) ? Collections.<AjcTestCase.Message>emptyList() : errors); | |||
this.fails = ((fails == null) ? Collections.<AjcTestCase.Message>emptyList() : fails); | |||
this.weaves = ((weaves == null) ? Collections.<AjcTestCase.Message>emptyList() : weaves); | |||
} | |||
/** | |||
* Create a message specification to test a CompilationResult for a given set of info, warning, and error messages. The | |||
* presence of any fail or abort messages in a CompilationResult will be a test failure. | |||
*/ | |||
public MessageSpec(List infos, List warnings, List errors) { | |||
public MessageSpec(List<AjcTestCase.Message> infos, List<AjcTestCase.Message> warnings, List<AjcTestCase.Message> errors) { | |||
this(infos, warnings, errors, null, null); | |||
} | |||
@@ -342,7 +359,7 @@ public class AjcTestCase extends TestCase { | |||
* Create a message specification to test a CompilationResult for a given set of warning, and error messages. The presence | |||
* of any fail or abort messages in a CompilationResult will be a test failure. Informational messages will be ignored. | |||
*/ | |||
public MessageSpec(List warnings, List errors) { | |||
public MessageSpec(List<AjcTestCase.Message> warnings, List<AjcTestCase.Message> errors) { | |||
this(null, warnings, errors, null, null); | |||
} | |||
} | |||
@@ -424,11 +441,11 @@ public class AjcTestCase extends TestCase { | |||
public void assertMessages(CompilationResult result, String message, MessageSpec expected) { | |||
if (result == null) | |||
fail("Attempt to compare null compilation results against expected."); | |||
List missingFails = copyAll(expected.fails); | |||
List missingInfos = copyAll(expected.infos); | |||
List missingWarnings = copyAll(expected.warnings); | |||
List missingErrors = copyAll(expected.errors); | |||
List missingWeaves = copyAll(expected.weaves); | |||
List<AjcTestCase.Message> missingFails = copyAll(expected.fails); | |||
List<AjcTestCase.Message> missingInfos = copyAll(expected.infos); | |||
List<AjcTestCase.Message> missingWarnings = copyAll(expected.warnings); | |||
List<AjcTestCase.Message> missingErrors = copyAll(expected.errors); | |||
List<AjcTestCase.Message> missingWeaves = copyAll(expected.weaves); | |||
List<IMessage> extraFails = copyAll(result.getFailMessages()); | |||
List<IMessage> extraInfos = copyAll(result.getInfoMessages()); | |||
List<IMessage> extraWarnings = copyAll(result.getWarningMessages()); | |||
@@ -873,12 +890,12 @@ public class AjcTestCase extends TestCase { | |||
return ret; | |||
} | |||
private List copyAll(List in) { | |||
private <T> List<T> copyAll(List<T> in) { | |||
if (in == Collections.EMPTY_LIST) | |||
return in; | |||
List out = new ArrayList(); | |||
for (Iterator iter = in.iterator(); iter.hasNext();) { | |||
List<T> out = new ArrayList<T>(); | |||
for (Iterator<T> iter = in.iterator(); iter.hasNext();) { | |||
out.add(iter.next()); | |||
} | |||
return out; | |||
@@ -893,25 +910,29 @@ public class AjcTestCase extends TestCase { | |||
* @param missingElements the missing messages, when passed in must contain all of the expected messages | |||
* @param extraElements the additional messages, when passed in must contain all of the actual messages | |||
*/ | |||
private void compare(List expected, List actual, List missingElements, List extraElements) { | |||
for (Iterator expectedIter = expected.iterator(); expectedIter.hasNext();) { | |||
Message expectedMessage = (Message) expectedIter.next(); | |||
for (Iterator actualIter = actual.iterator(); actualIter.hasNext();) { | |||
IMessage actualMessage = (IMessage) actualIter.next(); | |||
private void compare(List<AjcTestCase.Message> expected, List<IMessage> actual, List<AjcTestCase.Message> missingElements, List<IMessage> extraElements) { | |||
for (Message expectedMessage: expected) { | |||
for (IMessage actualMessage: actual) { | |||
if (expectedMessage.matches(actualMessage)) { | |||
missingElements.remove(expectedMessage); | |||
extraElements.remove(actualMessage); | |||
if (expectedMessage.careAboutOtherMessages) { | |||
missingElements.remove(expectedMessage); | |||
extraElements.remove(actualMessage); | |||
} | |||
else { | |||
missingElements.clear(); | |||
extraElements.clear(); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
private void addMissing(StringBuffer buff, String type, List messages) { | |||
private void addMissing(StringBuffer buff, String type, List<AjcTestCase.Message> messages) { | |||
if (!messages.isEmpty()) { | |||
buff.append("Missing expected "); | |||
buff.append(type); | |||
buff.append(" messages:\n"); | |||
for (Iterator iter = messages.iterator(); iter.hasNext();) { | |||
for (Iterator<AjcTestCase.Message> iter = messages.iterator(); iter.hasNext();) { | |||
buff.append("\t"); | |||
buff.append(iter.next().toString()); | |||
buff.append("\n"); |
@@ -20,6 +20,7 @@ import org.aspectj.bridge.context.CompilationAndWeavingContext; | |||
/** | |||
* Exception to use inside the bcweaver. | |||
*/ | |||
@SuppressWarnings("serial") | |||
public class BCException extends RuntimeException { | |||
Throwable thrown; | |||
@@ -78,6 +78,10 @@ class BoundedReferenceTypeDelegate extends AbstractReferenceTypeDelegate { | |||
public AnnotationAJ[] getAnnotations() { | |||
return resolvedTypeX.getAnnotations(); | |||
} | |||
public boolean hasAnnotations() { | |||
return resolvedTypeX.hasAnnotations(); | |||
} | |||
public ResolvedType[] getAnnotationTypes() { | |||
return resolvedTypeX.getAnnotationTypes(); |
@@ -91,6 +91,10 @@ public class GeneratedReferenceTypeDelegate extends AbstractReferenceTypeDelegat | |||
public AnnotationAJ[] getAnnotations() { | |||
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate"); | |||
} | |||
public boolean hasAnnotations() { | |||
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate"); | |||
} | |||
public ResolvedType[] getAnnotationTypes() { | |||
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate"); |
@@ -200,6 +200,11 @@ public class ReferenceType extends ResolvedType { | |||
return getDelegate().getAnnotations(); | |||
} | |||
@Override | |||
public boolean hasAnnotations() { | |||
return getDelegate().hasAnnotations(); | |||
} | |||
@Override | |||
public void addAnnotation(AnnotationAJ annotationX) { | |||
if (annotations == null) { |
@@ -143,4 +143,6 @@ public interface ReferenceTypeDelegate { | |||
public boolean hasBeenWoven(); | |||
public boolean hasAnnotations(); | |||
} |
@@ -925,6 +925,11 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl | |||
public AnnotationAJ[] getAnnotations() { | |||
throw new RuntimeException("ResolvedType.getAnnotations() should never be called"); | |||
} | |||
public boolean hasAnnotations() { | |||
throw new RuntimeException("ResolvedType.getAnnotations() should never be called"); | |||
} | |||
/** | |||
* Note: Only overridden by ReferenceType subtype |
@@ -137,7 +137,7 @@ public class WeaverStateInfo { | |||
case UNTOUCHED: | |||
throw new RuntimeException("unexpected UNWOVEN"); | |||
case WOVEN: | |||
return new WeaverStateInfo(Collections.EMPTY_LIST, true, isReweavable, isReweavableCompressed, isReweavableDiff); | |||
return new WeaverStateInfo(Collections.<Entry>emptyList(), true, isReweavable, isReweavableCompressed, isReweavableDiff); | |||
case EXTENDED: | |||
boolean isCompressed = false; | |||
if (s.isAtLeast169()) { | |||
@@ -145,7 +145,7 @@ public class WeaverStateInfo { | |||
} | |||
int n = s.readShort(); | |||
List l = new ArrayList(); | |||
List<Entry> l = new ArrayList<Entry>(); | |||
for (int i = 0; i < n; i++) { | |||
// conditional on version | |||
UnresolvedType aspectType = null; |
@@ -133,11 +133,11 @@ public class ArgsPointcut extends NameBindingPointcut { | |||
* @see org.aspectj.weaver.patterns.NameBindingPointcut#getBindingTypePatterns() | |||
*/ | |||
public List getBindingTypePatterns() { | |||
List l = new ArrayList(); | |||
List<BindingTypePattern> l = new ArrayList<BindingTypePattern>(); | |||
TypePattern[] pats = arguments.getTypePatterns(); | |||
for (int i = 0; i < pats.length; i++) { | |||
if (pats[i] instanceof BindingTypePattern) { | |||
l.add(pats[i]); | |||
l.add((BindingTypePattern)pats[i]); | |||
} | |||
} | |||
return l; |
@@ -84,7 +84,7 @@ public class BasicTokenSource implements ITokenSource { | |||
char[] chars = input.toCharArray(); | |||
int i = 0; | |||
List tokens = new ArrayList(); | |||
List<BasicToken> tokens = new ArrayList<BasicToken>(); | |||
while (i < chars.length) { | |||
char ch = chars[i++]; |
@@ -194,6 +194,10 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega | |||
// no annotations in Java 1.4 | |||
return AnnotationAJ.EMPTY_ARRAY; | |||
} | |||
public boolean hasAnnotations() { | |||
return false; | |||
} | |||
/* | |||
* (non-Javadoc) |
@@ -664,6 +664,7 @@ public abstract class CommonAdvancedPointcutExpressionTests extends TestCase { | |||
return null; | |||
} | |||
@SuppressWarnings("unused") | |||
private void checkAlwaysMatches(String pointcutExpression, String type, String methodName, String methodSignature) { | |||
StandardPointcutExpression ex = pointcutParser.parsePointcutExpression(pointcutExpression); | |||
assertNotNull(ex); | |||
@@ -674,6 +675,7 @@ public abstract class CommonAdvancedPointcutExpressionTests extends TestCase { | |||
assertTrue(b); | |||
} | |||
@SuppressWarnings("unused") | |||
private void checkNeverMatches(String pointcutExpression, String type, String methodName, String methodSignature) { | |||
StandardPointcutExpression ex = pointcutParser.parsePointcutExpression(pointcutExpression); | |||
assertNotNull(ex); |
@@ -194,7 +194,7 @@ public abstract class CommonWorldTests extends TestCase { | |||
} | |||
protected void mungersTest(ResolvedType ty, ShadowMunger[] x) { | |||
List l = (List) ty.getDeclaredShadowMungers(); | |||
List<ShadowMunger> l = ty.getDeclaredShadowMungers(); | |||
ShadowMunger[] array = (ShadowMunger[]) l.toArray(new ShadowMunger[l.size()]); | |||
TestUtil.assertSetEquals(ty + " mungers:", x, array); | |||
} |
@@ -287,7 +287,7 @@ public class TestUtils { | |||
public static String[] parseIds(String str) { | |||
if (str.length() == 0) | |||
return ZERO_STRINGS; | |||
List l = new ArrayList(); | |||
List<String> l = new ArrayList<String>(); | |||
int start = 0; | |||
while (true) { | |||
int i = str.indexOf(',', start); |
@@ -141,6 +141,7 @@ public class ArgsTestCase extends TestCase { | |||
assertFalse("no match expected", sMatch.matchesJoinPoint(thisOjb, targetObj, args).matches()); | |||
} | |||
@SuppressWarnings("unused") | |||
private static class A { | |||
public void anInt(int i) { | |||
} | |||
@@ -150,6 +151,7 @@ public class ArgsTestCase extends TestCase { | |||
} | |||
@SuppressWarnings("unused") | |||
private static class B extends A { | |||
public void x(A a) { | |||
} | |||
@@ -158,6 +160,7 @@ public class ArgsTestCase extends TestCase { | |||
} | |||
} | |||
@SuppressWarnings("unused") | |||
private static class C { | |||
public void z(A a, C c) { | |||
} |
@@ -16,12 +16,8 @@ import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
import java.lang.reflect.Modifier; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.aspectj.weaver.CompressingDataOutputStream; | |||
import org.aspectj.weaver.ConstantPoolReader; | |||
import org.aspectj.weaver.ConstantPoolWriter; | |||
import org.aspectj.weaver.VersionedDataInputStream; | |||
import org.aspectj.weaver.World; | |||
import org.aspectj.weaver.reflect.ReflectionWorld; |
@@ -293,16 +293,16 @@ public class CompileSpec implements ITestStep { | |||
} | |||
protected AjcTestCase.MessageSpec buildMessageSpec() { | |||
List infos = null; | |||
List warnings = new ArrayList(); | |||
List errors = new ArrayList(); | |||
List fails = new ArrayList(); | |||
List weaveInfos = new ArrayList(); | |||
List<AjcTestCase.Message> infos = null; | |||
List<AjcTestCase.Message> warnings = new ArrayList<AjcTestCase.Message>(); | |||
List<AjcTestCase.Message> errors = new ArrayList<AjcTestCase.Message>(); | |||
List<AjcTestCase.Message> fails = new ArrayList<AjcTestCase.Message>(); | |||
List<AjcTestCase.Message> weaveInfos = new ArrayList<AjcTestCase.Message>(); | |||
for (Iterator iter = expected.iterator(); iter.hasNext();) { | |||
ExpectedMessageSpec exMsg = (ExpectedMessageSpec) iter.next(); | |||
String kind = exMsg.getKind(); | |||
if (kind.equals("info")) { | |||
if (infos == null) infos = new ArrayList(); | |||
if (infos == null) infos = new ArrayList<AjcTestCase.Message>(); | |||
infos.add(exMsg.toMessage()); | |||
} else if (kind.equals("warning")) { | |||
warnings.add(exMsg.toMessage()); |
@@ -0,0 +1 @@ | |||
public class A {} |
@@ -0,0 +1,10 @@ | |||
import org.aspectj.lang.annotation.*; | |||
@RequiredTypes("A") | |||
@Aspect | |||
class X { | |||
@Before("execution(* Code.*(..))") | |||
public void m() { | |||
System.out.println("x"); | |||
} | |||
} |
@@ -0,0 +1 @@ | |||
public class B {} |
@@ -0,0 +1,3 @@ | |||
public class Code { | |||
public void m() {} | |||
} |
@@ -0,0 +1,11 @@ | |||
public class Runner { | |||
public static void main(String []argv) { | |||
new Code().m(); | |||
} | |||
} | |||
class Code { | |||
public void m() { | |||
System.out.println("Code.m() running"); | |||
} | |||
} |
@@ -0,0 +1,6 @@ | |||
import org.aspectj.lang.annotation.*; | |||
@RequiredTypes("A") | |||
aspect X { | |||
before(): execution(* Code.*(..)) {System.out.println("x");} | |||
} |
@@ -0,0 +1,7 @@ | |||
import org.aspectj.lang.annotation.*; | |||
aspect XA { | |||
@SuppressAjWarnings("adviceDidNotMatch") | |||
before(): execution(* A.*(..)) {} | |||
} | |||
@@ -0,0 +1,9 @@ | |||
import org.aspectj.lang.annotation.*; | |||
// Aspect deactivated if A is missing | |||
@RequiredTypes("A") | |||
aspect XA2 { | |||
@SuppressAjWarnings("adviceDidNotMatch") | |||
before(): execution(* A.*(..)) {} | |||
} | |||
@@ -0,0 +1,9 @@ | |||
import org.aspectj.lang.annotation.*; | |||
// Aspect deactivated if A or B is missing (although aspect only really needs A) | |||
@RequiredTypes({"A","B"}) | |||
aspect XA2 { | |||
@SuppressAjWarnings("adviceDidNotMatch") | |||
before(): execution(* A.*(..)) {} | |||
} | |||
@@ -0,0 +1,6 @@ | |||
import org.aspectj.lang.annotation.*; | |||
aspect XB { | |||
before(): execution(* B.*(..)) {} | |||
} | |||
@@ -0,0 +1,7 @@ | |||
import org.aspectj.lang.annotation.*; | |||
aspect XCode { | |||
@SuppressAjWarnings("adviceDidNotMatch") | |||
before(): execution(* Cod*.*(..)) {} | |||
} | |||
@@ -0,0 +1,7 @@ | |||
<aspectj> | |||
<aspects> | |||
<aspect name="X"/> | |||
</aspects> | |||
<weaver options="-verbose"/> | |||
</aspectj> | |||
@@ -0,0 +1,7 @@ | |||
<aspectj> | |||
<aspects> | |||
<aspect name="X"/> | |||
</aspects> | |||
<weaver options="-verbose"/> | |||
</aspectj> | |||
@@ -22,7 +22,8 @@ public class AtItd3 { | |||
Annotation aa = m.getAnnotation(Ann.class); | |||
System.err.println("Ann.class retrieved is: "+aa); | |||
if (!aa.toString().equals("@Ann(id=goodbye, anInt=4)")) | |||
if (!aa.toString().equals("@Ann(id=goodbye, anInt=4)")) // < Java8 order | |||
if (!aa.toString().equals("@Ann(anInt=4, id=goodbye)")) // Java8 order | |||
throw new RuntimeException("Incorrect output, expected:"+ | |||
"@Ann(id=goodbye, anInt=4) but got "+aa.toString()); | |||
@@ -10,7 +10,7 @@ | |||
<target name="compile:javac"> | |||
<!-- compile only javac compilable stuff, exclude the one that needs other dependencies --> | |||
<javac target="1.5" destdir="${aj.sandbox}" classpathref="aj.path" | |||
<javac source="1.5" target="1.5" destdir="${aj.sandbox}" classpathref="aj.path" | |||
srcdir="${basedir}" | |||
includes="ataspectj/*" | |||
excludes="ataspectj/UnweavableTest.java" | |||
@@ -75,7 +75,7 @@ | |||
<target name="ltw.Aspect2MainTest"> | |||
<!-- javac Aspect2 --> | |||
<javac target="1.5" destdir="${aj.sandbox}" classpathref="aj.path" | |||
<javac source="1.5" target="1.5" destdir="${aj.sandbox}" classpathref="aj.path" | |||
srcdir="${basedir}" | |||
includes="ataspectj/ltwreweavable/Aspect2.java" | |||
debug="true"> | |||
@@ -125,7 +125,7 @@ | |||
</target> | |||
<target name="ltw.Unweavable"> | |||
<javac target="1.5" destdir="${aj.sandbox}" | |||
<javac source="1.5" target="1.5" destdir="${aj.sandbox}" | |||
srcdir="${basedir}" | |||
includes="ataspectj/UnweavableTest.java, ataspectj/TestHelper.java" | |||
debug="true"> | |||
@@ -171,7 +171,7 @@ | |||
<target name="ltw.Decp2"> | |||
<!-- javac compile the 2nd aspect --> | |||
<javac target="1.5" destdir="${aj.sandbox}" | |||
<javac source="1.5" target="1.5" destdir="${aj.sandbox}" | |||
srcdir="${basedir}" | |||
includes="ataspectj/DeclareParentsImplementsReweavableTestAspect.java" | |||
debug="true"> |
@@ -0,0 +1,14 @@ | |||
import org.aspectj.lang.annotation.Aspect; | |||
import java.lang.annotation.*; | |||
public aspect SA { | |||
public static void main(String[] args) { | |||
Annotation[] annotations = SA.class.getAnnotations(); | |||
if (annotations.length != 1) throw new RuntimeException("Should have one annotation but has "+annotations.length); | |||
Aspect aspectAnnotation = (Aspect) annotations[0]; | |||
System.out.println(aspectAnnotation); | |||
if (!aspectAnnotation.value().equals("")) throw new RuntimeException("value should be empty"); | |||
} | |||
} |
@@ -5,9 +5,9 @@ public aspect SimpleAspect { | |||
public static void main(String[] args) { | |||
Annotation[] annotations = SimpleAspect.class.getAnnotations(); | |||
if (annotations.length != 1) throw new RuntimeException("Should have one annotation"); | |||
if (annotations.length != 1) throw new RuntimeException("Should have one annotation but has "+annotations.length); | |||
Aspect aspectAnnotation = (Aspect) annotations[0]; | |||
if (!aspectAnnotation.value().equals("")) throw new RuntimeException("value should be empty"); | |||
} | |||
} | |||
} |
@@ -119,9 +119,9 @@ public class LTWTests extends org.aspectj.testing.XMLBasedAjcTestCase { | |||
runTest("JDK14 LTW with XML"); | |||
} | |||
public void testJ14LTWWithASPECTPATH() { | |||
runTest("JDK14 LTW with ASPECTPATH"); | |||
} | |||
// public void testJ14LTWWithASPECTPATH() { | |||
// runTest("JDK14 LTW with ASPECTPATH"); | |||
// } | |||
//public void testDiscardingWovenTypes() { |
@@ -181,10 +181,10 @@ | |||
<stdout> | |||
<line text="Annotations on field1? true"/> | |||
<line text="Annotation count is 4"/> | |||
<line text="@AnnoBoolean(zzz=false, value=true)"/> | |||
<line text="@AnnoBoolean(value=true, zzz=false)"/> | |||
<line text="@AnnoClass(value=class java.lang.Integer, ccc=class java.lang.String)"/> | |||
<line text="@AnnoLong(jjj=111, value=999)"/> | |||
<line text="@AnnoString(sss=xyz, value=set from xml)"/> | |||
<line text="@AnnoLong(value=999, jjj=111)"/> | |||
<line text="@AnnoString(value=set from xml, sss=xyz)"/> | |||
<line text="Annotations on field2? true"/> | |||
<line text="Annotation count is 1"/> | |||
<line text="@AnnoClass(value=class java.lang.String, ccc=class java.lang.String)"/> | |||
@@ -199,13 +199,13 @@ | |||
<line text="Annotations on field1? true"/> | |||
<line text="Annotation count is 4"/> | |||
<line text="@AnnoChar(value=z, ccc=a)"/> | |||
<line text="@AnnoDouble(ddd=3.0, value=99.0)"/> | |||
<line text="@AnnoFloat(fff=4.0, value=6.0)"/> | |||
<line text="@AnnoShort(sss=3, value=8)"/> | |||
<line text="@AnnoDouble(value=99.0, ddd=3.0)"/> | |||
<line text="@AnnoFloat(value=6.0, fff=4.0)"/> | |||
<line text="@AnnoShort(value=8, sss=3)"/> | |||
<line text="Annotations on field2? true"/> | |||
<line text="Annotation count is 2"/> | |||
<line text="@AnnoByte(value=88, bbb=66)"/> | |||
<line text="@AnnoInt(value=99, iii=111)"/> | |||
<line text="@AnnoInt(iii=111, value=99)"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> |
@@ -9,7 +9,7 @@ | |||
</compile> | |||
<run class="Hello"> | |||
<stdout> | |||
<line text="@MyAnnotation(dummy2=korte, dummy1=)"/> | |||
<line text="@MyAnnotation(dummy1=, dummy2=korte)"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> |
@@ -21,6 +21,38 @@ import org.aspectj.testing.XMLBasedAjcTestCase; | |||
*/ | |||
public class Ajc183Tests extends org.aspectj.testing.XMLBasedAjcTestCase { | |||
public void testSuppressTypeNotFound_436653() { | |||
runTest("suppress type not found"); | |||
} | |||
public void testSuppressTypeNotFound_436653_2() { | |||
runTest("suppress type not found 2"); | |||
} | |||
public void testSuppressTypeNotFound_436653_3() { | |||
runTest("suppress type not found 3"); | |||
} | |||
public void testSuppressTypeNotFound_436653_4() { | |||
runTest("suppress type not found 4"); | |||
} | |||
public void testSuppressTypeNotFound_436653_5() { | |||
runTest("suppress type not found 5"); | |||
} | |||
public void testSuppressTypeNotFound_436653_6() { | |||
runTest("suppress type not found 6"); | |||
} | |||
public void testSuppressTypeNotFound_436653_7() { | |||
runTest("suppress type not found 7"); | |||
} | |||
public void testSuppressTypeNotFound_436653_8() { | |||
runTest("suppress type not found 8"); | |||
} | |||
public void testConstantPool_445395_0() { | |||
runTest("constant pool 0"); | |||
} |
@@ -2,6 +2,93 @@ | |||
<suite> | |||
<ajc-test dir="bugs183/436653" title="suppress type not found 4"> | |||
<compile options="-1.8 -Xlint:ignore" files="X.java" outjar="aspects.jar"/> | |||
<compile options="-1.8" files="Runner.java"/> | |||
<run class="Runner" ltw="aop.xml"> | |||
<stdout> | |||
<line text="Code.m() running"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<ajc-test dir="bugs183/436653" title="suppress type not found 5"> | |||
<compile options="-1.8 -Xlint:ignore" files="X.java" outjar="aspects.jar"/> | |||
<compile class="-1.8" files="A.java"/> | |||
<compile options="-1.8" files="Runner.java"/> | |||
<run class="Runner" ltw="aop.xml"> | |||
<stdout> | |||
<line text="x"/> | |||
<line text="Code.m() running"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<!-- annotation style aspect, missing type so deactivated --> | |||
<ajc-test dir="bugs183/436653" title="suppress type not found 6"> | |||
<compile options="-1.8 -Xlint:ignore" files="AnnoX.java" outjar="aspects.jar"/> | |||
<compile options="-1.8" files="Runner.java"/> | |||
<run class="Runner" ltw="aop2.xml"> | |||
<stdout> | |||
<line text="Code.m() running"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<!-- annotation style aspect, type not missing so not deactivated --> | |||
<ajc-test dir="bugs183/436653" title="suppress type not found 7"> | |||
<compile options="-1.8 -Xlint:ignore" files="AnnoX.java A.java" outjar="aspects.jar"/> | |||
<compile options="-1.8" files="Runner.java"/> | |||
<run class="Runner" ltw="aop2.xml"> | |||
<stdout> | |||
<line text="x"/> | |||
<line text="Code.m() running"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<!-- annotation style aspect, type not missing so not deactivated --> | |||
<ajc-test dir="bugs183/436653" title="suppress type not found 8"> | |||
<compile options="-1.8 -Xlint:ignore" files="AnnoX.java A.java" outjar="aspects.jar"/> | |||
<compile options="-1.8 -showWeaveInfo" files="Runner.java" aspectpath="aspects.jar"> | |||
<message kind="weave" text="Join point 'method-execution(void Code.m())' in Type 'Code' (Runner.java:8) advised by before advice from 'X' (aspects.jar!AnnoX.class(from AnnoX.java))"/> | |||
</compile> | |||
<run class="Runner"> | |||
<stdout> | |||
<line text="x"/> | |||
<line text="Code.m() running"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<ajc-test dir="bugs183/436653" title="suppress type not found 3"> | |||
<compile options="-1.8" files="A.java" outjar="typeA.jar"/> | |||
<compile options="-1.8" files="B.java" outjar="typeB.jar"/> | |||
<!-- adviceDidNotMatch messages are suppressed here --> | |||
<compile options="-1.8" files="XA3.java XCode.java" outjar="aspects.jar" classpath="typeA.jar"/> | |||
<compile options="-1.8 -verbose" files="Code.java" classpath="typeA.jar" aspectpath="aspects.jar"> | |||
<!-- '*' is a hint that we care about only this message, not other messages. avoids needing to list them all --> | |||
<message kind="info" text="*deactivating aspect 'XA2' as it requires type 'B' which cannot be found on the classpath"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="bugs183/436653" title="suppress type not found 2"> | |||
<compile options="-1.8" files="A.java" outjar="typeA.jar"/> | |||
<!-- adviceDidNotMatch messages are suppressed here --> | |||
<compile options="-1.8" files="XA2.java XCode.java" outjar="aspects.jar" classpath="typeA.jar"/> | |||
<compile options="-1.8" files="Code.java" aspectpath="aspects.jar"> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="bugs183/436653" title="suppress type not found"> | |||
<compile options="-1.8" files="A.java" outjar="typeA.jar"/> | |||
<!-- adviceDidNotMatch messages are suppressed here --> | |||
<compile options="-1.8" files="XA.java XCode.java" outjar="aspects.jar" classpath="typeA.jar"/> | |||
<compile options="-1.8" files="Code.java" aspectpath="aspects.jar"> | |||
<message kind="error" text="can't determine modifiers of missing type A"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="bugs183/445395" title="constant pool 0"> | |||
<compile options="-1.8" files="Code.java"> | |||
</compile> |
@@ -241,7 +241,7 @@ public class AjdeInteractionTestbed extends TestCase { | |||
File projectBase = new File(sandboxDir, pname); | |||
ICompilerConfiguration icc = compiler.getCompilerConfiguration(); | |||
List currentFiles = icc.getProjectSourceFiles(); | |||
List filesForCompilation = new ArrayList(); | |||
List<String> filesForCompilation = new ArrayList<String>(); | |||
collectUpFiles(projectBase, projectBase, filesForCompilation); | |||
boolean changed = false; | |||
for (int i = 0; i < filesForCompilation.size(); i++) { |
@@ -33,7 +33,7 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio | |||
private Set aspectPath = null; | |||
private Map sourcePathResources = null; | |||
private IOutputLocationManager outputLocationManager = null; | |||
private List dependants; | |||
private List<String> dependants; | |||
private Map javaOptionsMap; | |||
private Set<File> inpath; | |||
private String encoding = null; | |||
@@ -41,9 +41,9 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio | |||
private String processor; | |||
private String processorPath; | |||
private String nonstandardoptions; | |||
private List modifiedFiles; | |||
private List modifiedDirs; | |||
private List projectSourceFiles = new ArrayList(); | |||
private List<File> modifiedFiles; | |||
private List<String> modifiedDirs; | |||
private List<String> projectSourceFiles = new ArrayList(); | |||
private List xmlConfigFiles = new ArrayList(); | |||
private String projectPath; | |||
@@ -129,7 +129,7 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio | |||
return xmlConfigFiles; | |||
} | |||
public List getProjectSourceFilesChanged() { | |||
public List<File> getProjectSourceFilesChanged() { | |||
log("ICompilerConfiguration.getProjectSourceFilesChanged()"); | |||
return modifiedFiles; | |||
} | |||
@@ -146,7 +146,7 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio | |||
public void addDependancy(String projectItDependsOn) { | |||
if (dependants == null) { | |||
dependants = new ArrayList(); | |||
dependants = new ArrayList<String>(); | |||
} | |||
dependants.add(projectItDependsOn); | |||
} | |||
@@ -187,19 +187,19 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio | |||
this.changed |= ICompilerConfiguration.NONSTANDARDOPTIONS_CHANGED; | |||
} | |||
public void setProjectSourceFiles(List projectSourceFiles) { | |||
public void setProjectSourceFiles(List<String> projectSourceFiles) { | |||
this.projectSourceFiles = projectSourceFiles; | |||
this.changed |= ICompilerConfiguration.PROJECTSOURCEFILES_CHANGED; | |||
} | |||
public void setProjectXmlConfigFiles(List xmlConfigFiles) { | |||
public void setProjectXmlConfigFiles(List<String> xmlConfigFiles) { | |||
this.xmlConfigFiles = xmlConfigFiles; | |||
this.changed |= ICompilerConfiguration.XMLCONFIG_CHANGED; | |||
} | |||
public void addProjectSourceFileChanged(File f) { | |||
if (this.modifiedFiles == null) { | |||
this.modifiedFiles = new ArrayList(); | |||
this.modifiedFiles = new ArrayList<File>(); | |||
} | |||
if (f != null) { | |||
modifiedFiles.add(f); | |||
@@ -208,7 +208,7 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio | |||
public void addClasspathEntryChanged(String f) { | |||
if (this.modifiedDirs == null) { | |||
this.modifiedDirs = new ArrayList(); | |||
this.modifiedDirs = new ArrayList<String>(); | |||
} | |||
if (f != null) { | |||
modifiedDirs.add(f); |
@@ -587,6 +587,11 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
ensureAnnotationsUnpacked(); | |||
return annotations; | |||
} | |||
public boolean hasAnnotations() { | |||
ensureAnnotationsUnpacked(); | |||
return annotations.length != 0; | |||
} | |||
public boolean hasAnnotation(UnresolvedType ofType) { | |||
// Due to re-entrancy we may be in the middle of unpacking the annotations already... in which case use this slow |
@@ -1016,11 +1016,52 @@ public class BcelWorld extends World implements Repository { | |||
@Override | |||
public boolean hasUnsatisfiedDependency(ResolvedType aspectType) { | |||
String aspectName = aspectType.getName(); | |||
if (aspectType.hasAnnotations()) { | |||
AnnotationAJ[] annos = aspectType.getAnnotations(); | |||
for (AnnotationAJ anno: annos) { | |||
if (anno.getTypeName().equals("org.aspectj.lang.annotation.RequiredTypes")) { | |||
String values = anno.getStringFormOfValue("value"); // Example: "[A,org.foo.Bar]" | |||
if (values != null && values.length() > 2) { | |||
values = values.substring(1,values.length()-1); | |||
StringTokenizer tokenizer = new StringTokenizer(values,","); | |||
boolean anythingMissing = false; | |||
while (tokenizer.hasMoreElements()) { | |||
String requiredTypeName = tokenizer.nextToken(); | |||
ResolvedType rt = resolve(UnresolvedType.forName(requiredTypeName)); | |||
if (rt.isMissing()) { | |||
if (!getMessageHandler().isIgnoring(IMessage.INFO)) { | |||
getMessageHandler().handleMessage( | |||
MessageUtil.info("deactivating aspect '" + aspectName + "' as it requires type '" | |||
+ requiredTypeName + "' which cannot be found on the classpath")); | |||
} | |||
anythingMissing = true; | |||
if (aspectRequiredTypes == null) { | |||
aspectRequiredTypes = new HashMap<String,String>(); | |||
} | |||
// Record that it has an invalid type reference | |||
aspectRequiredTypes.put(aspectName,requiredTypeName); | |||
} | |||
} | |||
if (anythingMissing) { | |||
return true; | |||
} | |||
else { | |||
return false; | |||
} | |||
} | |||
else { | |||
// no value specified for annotation | |||
return false; | |||
} | |||
} | |||
} | |||
} | |||
if (aspectRequiredTypes == null) { | |||
// no aspects require anything, so there can be no unsatisfied dependencies | |||
return false; | |||
} | |||
String aspectName = aspectType.getName(); | |||
if (!aspectRequiredTypesProcessed.contains(aspectName)) { | |||
String requiredTypeName = aspectRequiredTypes.get(aspectName); | |||
if (requiredTypeName==null) { | |||
@@ -1053,7 +1094,7 @@ public class BcelWorld extends World implements Repository { | |||
if (aspectRequiredTypes == null) { | |||
aspectRequiredTypes = new HashMap<String, String>(); | |||
} | |||
aspectRequiredTypes.put(aspectClassName, requiredType); | |||
aspectRequiredTypes.put(aspectClassName,requiredType); | |||
} | |||
/** |
@@ -13,6 +13,8 @@ | |||
package org.aspectj.weaver.bcel; | |||
import java.lang.reflect.Modifier; | |||
import java.util.Objects; | |||
import java.util.function.Consumer; | |||
import org.aspectj.weaver.Advice; | |||
import org.aspectj.weaver.BcweaverTests; | |||
@@ -108,11 +110,20 @@ public class WorldTestCase extends CommonWorldTests { | |||
modifiersTest(iter, abstractPublic | Modifier.INTERFACE); | |||
fieldsTest(iter, ResolvedMember.NONE); | |||
methodsTest(iter, new Member[] { MemberImpl.method(iter, 0, "hasNext", "()Z"), MemberImpl.method(iter, 0, "remove", "()V"), | |||
MemberImpl.method(iter, 0, "next", "()Ljava/lang/Object;"), }); | |||
methodsTest(iter, new Member[] { | |||
MemberImpl.method(iter, 0, "hasNext", "()Z"), | |||
MemberImpl.method(iter, 0, "remove", "()V"), | |||
MemberImpl.method(iter, 0, "next", "()Ljava/lang/Object;"), | |||
MemberImpl.method(iter, 0, "forEachRemaining", "(Ljava/util/function/Consumer;)V") | |||
// default void forEachRemaining(Consumer<? super E> action) { | |||
// Objects.requireNonNull(action); | |||
// while (hasNext()) | |||
// action.accept(next()); | |||
// } | |||
}); | |||
ResolvedMember remove = iter.lookupMethod(MemberImpl.method(iter, 0, "remove", "()V")); | |||
assertNotNull("iterator doesn't have remove", remove); | |||
modifiersTest(remove, abstractPublic | Modifier.INTERFACE); | |||
modifiersTest(remove, Modifier.PUBLIC | Modifier.INTERFACE); // no longer abstract in Java8 (default instead) | |||
exceptionsTest(remove, UnresolvedType.NONE); | |||
ResolvedMember clone = iter.lookupMethod(MemberImpl.method(UnresolvedType.OBJECT, 0, "clone", "()Ljava/lang/Object;")); |
@@ -92,6 +92,14 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR | |||
} | |||
return annotations; | |||
} | |||
@Override | |||
public boolean hasAnnotations() { | |||
if (annotations == null) { | |||
annotations = annotationFinder.getAnnotations(getBaseClass(), getWorld()); | |||
} | |||
return annotations.length != 0; | |||
} | |||
@Override | |||
public boolean hasAnnotation(UnresolvedType ofType) { |