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
#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 |
classStartIndex = fileContents.toString().indexOf("<H2>\nClass "); | classStartIndex = fileContents.toString().indexOf("<H2>\nClass "); | ||||
br = false; | 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); | int classEndIndex = fileContents.toString().indexOf("</H2>", classStartIndex); | ||||
if (classStartIndex != -1 && classEndIndex != -1) { | if (classStartIndex != -1 && classEndIndex != -1) { | ||||
String classLine = fileContents.toString().substring(classStartIndex, classEndIndex); | String classLine = fileContents.toString().substring(classStartIndex, classEndIndex); | ||||
fileContents.insert(secondClassStartIndex, sb.toString()); | 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(); | file.delete(); |
} | } | ||||
/** | /** | ||||
* 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 htmlFile | ||||
* @param an array of requiredStrings | * @param an array of requiredStrings | ||||
* @return a List of those strings not found | * @return a List of those strings not found | ||||
* @throws Exception | * @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++) { | for (int i = 0; i < requiredStrings.length; i++) { | ||||
String string = requiredStrings[i]; | String string = requiredStrings[i]; | ||||
if (!containsString(htmlFile,string)) { | |||||
if (!containsString(htmlFile, string)) { | |||||
missingStrings.add(string); | missingStrings.add(string); | ||||
} | } | ||||
} | } |
import java.io.File; | import java.io.File; | ||||
import java.util.List; | import java.util.List; | ||||
import org.aspectj.util.FileUtil; | |||||
import org.aspectj.util.LangUtil; | 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. | * A long way to go until full coverage, but this is the place to add more. | ||||
// ensure that the file is entitled "Aspect ClassA.InnerAspect" rather | // ensure that the file is entitled "Aspect ClassA.InnerAspect" rather | ||||
// than "Class ClassA.InnerAspect" | // 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>", | "<PRE>static aspect <B>ClassA.InnerAspect</B><DT>extends java.lang.Object</DL>", | ||||
"Class ClassA.InnerAspect", | "Class ClassA.InnerAspect", | ||||
"<PRE>static class <B>ClassA.InnerAspect</B><DT>extends java.lang.Object</DL>"}; | "<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 | // get the html file for the enclosing class | ||||
File htmlFileClass = new File(getAbsolutePathOutdir() + "/foo/ClassA.html"); | File htmlFileClass = new File(getAbsolutePathOutdir() + "/foo/ClassA.html"); | ||||
// ensure that the file is entitled "Class ClassA" and | // ensure that the file is entitled "Class ClassA" and | ||||
// has not been changed to "Aspect ClassA" | // 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>", | "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); | 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 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>")); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
// ensure that the file is entitled "Aspect PkgVisibleClass.NestedAspect" rather | // ensure that the file is entitled "Aspect PkgVisibleClass.NestedAspect" rather | ||||
// than "Class PkgVisibleClass.NestedAspect" | // 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()); | 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 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 | // get the html file for the enclosing class | ||||
File htmlFileClass = new File(getAbsolutePathOutdir() + "/PkgVisibleClass.html"); | File htmlFileClass = new File(getAbsolutePathOutdir() + "/PkgVisibleClass.html"); | ||||
if (!htmlFileClass.exists()) { | if (!htmlFileClass.exists()) { | ||||
// ensure that the file is entitled "Class PkgVisibleClass" and | // ensure that the file is entitled "Class PkgVisibleClass" and | ||||
// has not been changed to "Aspect PkgVisibleClass" | // 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()); | 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>")); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
} | } | ||||
// ensure that the file is entitled "Aspect ClassWithNestedAspect.NestedAspect" | // ensure that the file is entitled "Aspect ClassWithNestedAspect.NestedAspect" | ||||
// rather than "Class 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", | "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()); | 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 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 | // get the html file for the enclosing class | ||||
File htmlFileClass = new File(getAbsolutePathOutdir() + "/pkg/ClassWithNestedAspect.html"); | File htmlFileClass = new File(getAbsolutePathOutdir() + "/pkg/ClassWithNestedAspect.html"); | ||||
// ensure that the file is entitled "Class ClassWithNestedAspect" and | // ensure that the file is entitled "Class ClassWithNestedAspect" and | ||||
// has not been changed to "Aspect ClassWithNestedAspect" | // 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()); | 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>")); | |||||
} | |||||
} | } | ||||
/** | /** |
/* ******************************************************************* | |||||
* 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(); | |||||
} |
if (args.size() > nextArgIndex) { | if (args.size() > nextArgIndex) { | ||||
// buildConfig.getAjOptions().put(AjCompilerOptions.OPTION_Inpath, CompilerOptions.PRESERVE); | // 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(), | StringTokenizer st = new StringTokenizer(((ConfigParser.Arg) args.get(nextArgIndex)).getValue(), | ||||
File.pathSeparator); | File.pathSeparator); | ||||
while (st.hasMoreTokens()) { | while (st.hasMoreTokens()) { | ||||
buildConfig.setMakeReflectable(true); | buildConfig.setMakeReflectable(true); | ||||
} else if (arg.equals("-sourceroots")) { | } else if (arg.equals("-sourceroots")) { | ||||
if (args.size() > nextArgIndex) { | if (args.size() > nextArgIndex) { | ||||
List sourceRoots = new ArrayList(); | |||||
List<File> sourceRoots = new ArrayList<File>(); | |||||
StringTokenizer st = new StringTokenizer(((ConfigParser.Arg) args.get(nextArgIndex)).getValue(), | StringTokenizer st = new StringTokenizer(((ConfigParser.Arg) args.get(nextArgIndex)).getValue(), | ||||
File.pathSeparator); | File.pathSeparator); | ||||
while (st.hasMoreTokens()) { | while (st.hasMoreTokens()) { |
// For e37 moved the check down to this level | // For e37 moved the check down to this level | ||||
return; | return; | ||||
} | } | ||||
if ((binding.tagBits & TagBits.AnnotationResolved) != 0) { | |||||
// possibly resolution occurred during hasUnsatisfiedDependency()... | |||||
binding.tagBits = (binding.tagBits & ~TagBits.AnnotationResolved); | |||||
} | |||||
Annotation atAspectAnnotation = AtAspectJAnnotationFactory.createAspectAnnotation(perClause.toDeclarationString(), | Annotation atAspectAnnotation = AtAspectJAnnotationFactory.createAspectAnnotation(perClause.toDeclarationString(), | ||||
declarationSourceStart); | declarationSourceStart); | ||||
Annotation privilegedAnnotation = null; | Annotation privilegedAnnotation = null; | ||||
System.arraycopy(old, 0, annotations, 0, old.length); | System.arraycopy(old, 0, annotations, 0, old.length); | ||||
System.arraycopy(toAdd, 0, annotations, old.length, toAdd.length); | System.arraycopy(toAdd, 0, annotations, old.length, toAdd.length); | ||||
} | } | ||||
TypeDeclaration.resolveAnnotations(staticInitializerScope, annotations, binding); | |||||
} | } | ||||
public void generateCode(ClassFile enclosingClassFile) { | public void generateCode(ClassFile enclosingClassFile) { |
*/ | */ | ||||
public AnnotationAJ[] getAnnotations() { | public AnnotationAJ[] getAnnotations() { | ||||
int declarationAnnoCount = (declaration.annotations == null ? 0 : declaration.annotations.length); | 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 | return annotations; // only do this once | ||||
} | } | ||||
if (!annotationsFullyResolved || annotations.length!=declarationAnnoCount) { | if (!annotationsFullyResolved || annotations.length!=declarationAnnoCount) { | ||||
} | } | ||||
return annotations; | 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. | * Convert one eclipse annotation into an AnnotationX object containing an AnnotationAJ object. |
private String text; | private String text; | ||||
private String sourceFileName; | private String sourceFileName; | ||||
private ISourceLocation[] seeAlsos; | private ISourceLocation[] seeAlsos; | ||||
public boolean careAboutOtherMessages = true; | |||||
/** | /** | ||||
* Create a message that will match any compiler message on the given line. | * Create a message that will match any compiler message on the given line. | ||||
public Message(int line, String text) { | public Message(int line, String text) { | ||||
this.line = line; | this.line = line; | ||||
this.text = 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); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
this.sourceFileName = srcFileName.toString(); | this.sourceFileName = srcFileName.toString(); | ||||
} | } | ||||
this.text = 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); | |||||
} | |||||
this.seeAlsos = seeAlso; | this.seeAlsos = seeAlso; | ||||
} | } | ||||
*/ | */ | ||||
public Message(String text) { | public Message(String text) { | ||||
this.text = 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); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
Collections.EMPTY_LIST, Collections.EMPTY_LIST); | Collections.EMPTY_LIST, Collections.EMPTY_LIST); | ||||
boolean ignoreInfos = true; | 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. | * Set to true to enable or disable comparison of information messages. | ||||
* @param errors The set of error messages to test for - can pass null to indicate empty set. | * @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. | * @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) { | if (infos != null) { | ||||
this.infos = infos; | this.infos = infos; | ||||
ignoreInfos = false; | ignoreInfos = false; | ||||
} else { | } 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 | * 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. | * 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); | this(infos, warnings, errors, null, null); | ||||
} | } | ||||
* Create a message specification to test a CompilationResult for a given set of warning, and error messages. The presence | * 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. | * 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); | this(null, warnings, errors, null, null); | ||||
} | } | ||||
} | } | ||||
public void assertMessages(CompilationResult result, String message, MessageSpec expected) { | public void assertMessages(CompilationResult result, String message, MessageSpec expected) { | ||||
if (result == null) | if (result == null) | ||||
fail("Attempt to compare null compilation results against expected."); | 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> extraFails = copyAll(result.getFailMessages()); | ||||
List<IMessage> extraInfos = copyAll(result.getInfoMessages()); | List<IMessage> extraInfos = copyAll(result.getInfoMessages()); | ||||
List<IMessage> extraWarnings = copyAll(result.getWarningMessages()); | List<IMessage> extraWarnings = copyAll(result.getWarningMessages()); | ||||
return ret; | return ret; | ||||
} | } | ||||
private List copyAll(List in) { | |||||
private <T> List<T> copyAll(List<T> in) { | |||||
if (in == Collections.EMPTY_LIST) | if (in == Collections.EMPTY_LIST) | ||||
return in; | 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()); | out.add(iter.next()); | ||||
} | } | ||||
return out; | return out; | ||||
* @param missingElements the missing messages, when passed in must contain all of the expected messages | * @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 | * @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)) { | 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()) { | if (!messages.isEmpty()) { | ||||
buff.append("Missing expected "); | buff.append("Missing expected "); | ||||
buff.append(type); | buff.append(type); | ||||
buff.append(" messages:\n"); | 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("\t"); | ||||
buff.append(iter.next().toString()); | buff.append(iter.next().toString()); | ||||
buff.append("\n"); | buff.append("\n"); |
/** | /** | ||||
* Exception to use inside the bcweaver. | * Exception to use inside the bcweaver. | ||||
*/ | */ | ||||
@SuppressWarnings("serial") | |||||
public class BCException extends RuntimeException { | public class BCException extends RuntimeException { | ||||
Throwable thrown; | Throwable thrown; | ||||
public AnnotationAJ[] getAnnotations() { | public AnnotationAJ[] getAnnotations() { | ||||
return resolvedTypeX.getAnnotations(); | return resolvedTypeX.getAnnotations(); | ||||
} | } | ||||
public boolean hasAnnotations() { | |||||
return resolvedTypeX.hasAnnotations(); | |||||
} | |||||
public ResolvedType[] getAnnotationTypes() { | public ResolvedType[] getAnnotationTypes() { | ||||
return resolvedTypeX.getAnnotationTypes(); | return resolvedTypeX.getAnnotationTypes(); |
public AnnotationAJ[] getAnnotations() { | public AnnotationAJ[] getAnnotations() { | ||||
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate"); | throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate"); | ||||
} | } | ||||
public boolean hasAnnotations() { | |||||
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate"); | |||||
} | |||||
public ResolvedType[] getAnnotationTypes() { | public ResolvedType[] getAnnotationTypes() { | ||||
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate"); | throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate"); |
return getDelegate().getAnnotations(); | return getDelegate().getAnnotations(); | ||||
} | } | ||||
@Override | |||||
public boolean hasAnnotations() { | |||||
return getDelegate().hasAnnotations(); | |||||
} | |||||
@Override | @Override | ||||
public void addAnnotation(AnnotationAJ annotationX) { | public void addAnnotation(AnnotationAJ annotationX) { | ||||
if (annotations == null) { | if (annotations == null) { |
public boolean hasBeenWoven(); | public boolean hasBeenWoven(); | ||||
public boolean hasAnnotations(); | |||||
} | } |
public AnnotationAJ[] getAnnotations() { | public AnnotationAJ[] getAnnotations() { | ||||
throw new RuntimeException("ResolvedType.getAnnotations() should never be called"); | 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 | * Note: Only overridden by ReferenceType subtype |
case UNTOUCHED: | case UNTOUCHED: | ||||
throw new RuntimeException("unexpected UNWOVEN"); | throw new RuntimeException("unexpected UNWOVEN"); | ||||
case WOVEN: | case WOVEN: | ||||
return new WeaverStateInfo(Collections.EMPTY_LIST, true, isReweavable, isReweavableCompressed, isReweavableDiff); | |||||
return new WeaverStateInfo(Collections.<Entry>emptyList(), true, isReweavable, isReweavableCompressed, isReweavableDiff); | |||||
case EXTENDED: | case EXTENDED: | ||||
boolean isCompressed = false; | boolean isCompressed = false; | ||||
if (s.isAtLeast169()) { | if (s.isAtLeast169()) { | ||||
} | } | ||||
int n = s.readShort(); | int n = s.readShort(); | ||||
List l = new ArrayList(); | |||||
List<Entry> l = new ArrayList<Entry>(); | |||||
for (int i = 0; i < n; i++) { | for (int i = 0; i < n; i++) { | ||||
// conditional on version | // conditional on version | ||||
UnresolvedType aspectType = null; | UnresolvedType aspectType = null; |
* @see org.aspectj.weaver.patterns.NameBindingPointcut#getBindingTypePatterns() | * @see org.aspectj.weaver.patterns.NameBindingPointcut#getBindingTypePatterns() | ||||
*/ | */ | ||||
public List getBindingTypePatterns() { | public List getBindingTypePatterns() { | ||||
List l = new ArrayList(); | |||||
List<BindingTypePattern> l = new ArrayList<BindingTypePattern>(); | |||||
TypePattern[] pats = arguments.getTypePatterns(); | TypePattern[] pats = arguments.getTypePatterns(); | ||||
for (int i = 0; i < pats.length; i++) { | for (int i = 0; i < pats.length; i++) { | ||||
if (pats[i] instanceof BindingTypePattern) { | if (pats[i] instanceof BindingTypePattern) { | ||||
l.add(pats[i]); | |||||
l.add((BindingTypePattern)pats[i]); | |||||
} | } | ||||
} | } | ||||
return l; | return l; |
char[] chars = input.toCharArray(); | char[] chars = input.toCharArray(); | ||||
int i = 0; | int i = 0; | ||||
List tokens = new ArrayList(); | |||||
List<BasicToken> tokens = new ArrayList<BasicToken>(); | |||||
while (i < chars.length) { | while (i < chars.length) { | ||||
char ch = chars[i++]; | char ch = chars[i++]; |
// no annotations in Java 1.4 | // no annotations in Java 1.4 | ||||
return AnnotationAJ.EMPTY_ARRAY; | return AnnotationAJ.EMPTY_ARRAY; | ||||
} | } | ||||
public boolean hasAnnotations() { | |||||
return false; | |||||
} | |||||
/* | /* | ||||
* (non-Javadoc) | * (non-Javadoc) |
return null; | return null; | ||||
} | } | ||||
@SuppressWarnings("unused") | |||||
private void checkAlwaysMatches(String pointcutExpression, String type, String methodName, String methodSignature) { | private void checkAlwaysMatches(String pointcutExpression, String type, String methodName, String methodSignature) { | ||||
StandardPointcutExpression ex = pointcutParser.parsePointcutExpression(pointcutExpression); | StandardPointcutExpression ex = pointcutParser.parsePointcutExpression(pointcutExpression); | ||||
assertNotNull(ex); | assertNotNull(ex); | ||||
assertTrue(b); | assertTrue(b); | ||||
} | } | ||||
@SuppressWarnings("unused") | |||||
private void checkNeverMatches(String pointcutExpression, String type, String methodName, String methodSignature) { | private void checkNeverMatches(String pointcutExpression, String type, String methodName, String methodSignature) { | ||||
StandardPointcutExpression ex = pointcutParser.parsePointcutExpression(pointcutExpression); | StandardPointcutExpression ex = pointcutParser.parsePointcutExpression(pointcutExpression); | ||||
assertNotNull(ex); | assertNotNull(ex); |
} | } | ||||
protected void mungersTest(ResolvedType ty, ShadowMunger[] x) { | 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()]); | ShadowMunger[] array = (ShadowMunger[]) l.toArray(new ShadowMunger[l.size()]); | ||||
TestUtil.assertSetEquals(ty + " mungers:", x, array); | TestUtil.assertSetEquals(ty + " mungers:", x, array); | ||||
} | } |
public static String[] parseIds(String str) { | public static String[] parseIds(String str) { | ||||
if (str.length() == 0) | if (str.length() == 0) | ||||
return ZERO_STRINGS; | return ZERO_STRINGS; | ||||
List l = new ArrayList(); | |||||
List<String> l = new ArrayList<String>(); | |||||
int start = 0; | int start = 0; | ||||
while (true) { | while (true) { | ||||
int i = str.indexOf(',', start); | int i = str.indexOf(',', start); |
assertFalse("no match expected", sMatch.matchesJoinPoint(thisOjb, targetObj, args).matches()); | assertFalse("no match expected", sMatch.matchesJoinPoint(thisOjb, targetObj, args).matches()); | ||||
} | } | ||||
@SuppressWarnings("unused") | |||||
private static class A { | private static class A { | ||||
public void anInt(int i) { | public void anInt(int i) { | ||||
} | } | ||||
} | } | ||||
@SuppressWarnings("unused") | |||||
private static class B extends A { | private static class B extends A { | ||||
public void x(A a) { | public void x(A a) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
@SuppressWarnings("unused") | |||||
private static class C { | private static class C { | ||||
public void z(A a, C c) { | public void z(A a, C c) { | ||||
} | } |
import java.io.ByteArrayOutputStream; | import java.io.ByteArrayOutputStream; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.lang.reflect.Modifier; | import java.lang.reflect.Modifier; | ||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import org.aspectj.weaver.CompressingDataOutputStream; | import org.aspectj.weaver.CompressingDataOutputStream; | ||||
import org.aspectj.weaver.ConstantPoolReader; | |||||
import org.aspectj.weaver.ConstantPoolWriter; | |||||
import org.aspectj.weaver.VersionedDataInputStream; | import org.aspectj.weaver.VersionedDataInputStream; | ||||
import org.aspectj.weaver.World; | import org.aspectj.weaver.World; | ||||
import org.aspectj.weaver.reflect.ReflectionWorld; | import org.aspectj.weaver.reflect.ReflectionWorld; |
} | } | ||||
protected AjcTestCase.MessageSpec buildMessageSpec() { | 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();) { | for (Iterator iter = expected.iterator(); iter.hasNext();) { | ||||
ExpectedMessageSpec exMsg = (ExpectedMessageSpec) iter.next(); | ExpectedMessageSpec exMsg = (ExpectedMessageSpec) iter.next(); | ||||
String kind = exMsg.getKind(); | String kind = exMsg.getKind(); | ||||
if (kind.equals("info")) { | if (kind.equals("info")) { | ||||
if (infos == null) infos = new ArrayList(); | |||||
if (infos == null) infos = new ArrayList<AjcTestCase.Message>(); | |||||
infos.add(exMsg.toMessage()); | infos.add(exMsg.toMessage()); | ||||
} else if (kind.equals("warning")) { | } else if (kind.equals("warning")) { | ||||
warnings.add(exMsg.toMessage()); | warnings.add(exMsg.toMessage()); |
public class A {} |
import org.aspectj.lang.annotation.*; | |||||
@RequiredTypes("A") | |||||
@Aspect | |||||
class X { | |||||
@Before("execution(* Code.*(..))") | |||||
public void m() { | |||||
System.out.println("x"); | |||||
} | |||||
} |
public class B {} |
public class Code { | |||||
public void m() {} | |||||
} |
public class Runner { | |||||
public static void main(String []argv) { | |||||
new Code().m(); | |||||
} | |||||
} | |||||
class Code { | |||||
public void m() { | |||||
System.out.println("Code.m() running"); | |||||
} | |||||
} |
import org.aspectj.lang.annotation.*; | |||||
@RequiredTypes("A") | |||||
aspect X { | |||||
before(): execution(* Code.*(..)) {System.out.println("x");} | |||||
} |
import org.aspectj.lang.annotation.*; | |||||
aspect XA { | |||||
@SuppressAjWarnings("adviceDidNotMatch") | |||||
before(): execution(* A.*(..)) {} | |||||
} | |||||
import org.aspectj.lang.annotation.*; | |||||
// Aspect deactivated if A is missing | |||||
@RequiredTypes("A") | |||||
aspect XA2 { | |||||
@SuppressAjWarnings("adviceDidNotMatch") | |||||
before(): execution(* A.*(..)) {} | |||||
} | |||||
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.*(..)) {} | |||||
} | |||||
import org.aspectj.lang.annotation.*; | |||||
aspect XB { | |||||
before(): execution(* B.*(..)) {} | |||||
} | |||||
import org.aspectj.lang.annotation.*; | |||||
aspect XCode { | |||||
@SuppressAjWarnings("adviceDidNotMatch") | |||||
before(): execution(* Cod*.*(..)) {} | |||||
} | |||||
<aspectj> | |||||
<aspects> | |||||
<aspect name="X"/> | |||||
</aspects> | |||||
<weaver options="-verbose"/> | |||||
</aspectj> | |||||
<aspectj> | |||||
<aspects> | |||||
<aspect name="X"/> | |||||
</aspects> | |||||
<weaver options="-verbose"/> | |||||
</aspectj> | |||||
Annotation aa = m.getAnnotation(Ann.class); | Annotation aa = m.getAnnotation(Ann.class); | ||||
System.err.println("Ann.class retrieved is: "+aa); | 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:"+ | throw new RuntimeException("Incorrect output, expected:"+ | ||||
"@Ann(id=goodbye, anInt=4) but got "+aa.toString()); | "@Ann(id=goodbye, anInt=4) but got "+aa.toString()); | ||||
<target name="compile:javac"> | <target name="compile:javac"> | ||||
<!-- compile only javac compilable stuff, exclude the one that needs other dependencies --> | <!-- 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}" | srcdir="${basedir}" | ||||
includes="ataspectj/*" | includes="ataspectj/*" | ||||
excludes="ataspectj/UnweavableTest.java" | excludes="ataspectj/UnweavableTest.java" | ||||
<target name="ltw.Aspect2MainTest"> | <target name="ltw.Aspect2MainTest"> | ||||
<!-- javac Aspect2 --> | <!-- 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}" | srcdir="${basedir}" | ||||
includes="ataspectj/ltwreweavable/Aspect2.java" | includes="ataspectj/ltwreweavable/Aspect2.java" | ||||
debug="true"> | debug="true"> | ||||
</target> | </target> | ||||
<target name="ltw.Unweavable"> | <target name="ltw.Unweavable"> | ||||
<javac target="1.5" destdir="${aj.sandbox}" | |||||
<javac source="1.5" target="1.5" destdir="${aj.sandbox}" | |||||
srcdir="${basedir}" | srcdir="${basedir}" | ||||
includes="ataspectj/UnweavableTest.java, ataspectj/TestHelper.java" | includes="ataspectj/UnweavableTest.java, ataspectj/TestHelper.java" | ||||
debug="true"> | debug="true"> | ||||
<target name="ltw.Decp2"> | <target name="ltw.Decp2"> | ||||
<!-- javac compile the 2nd aspect --> | <!-- javac compile the 2nd aspect --> | ||||
<javac target="1.5" destdir="${aj.sandbox}" | |||||
<javac source="1.5" target="1.5" destdir="${aj.sandbox}" | |||||
srcdir="${basedir}" | srcdir="${basedir}" | ||||
includes="ataspectj/DeclareParentsImplementsReweavableTestAspect.java" | includes="ataspectj/DeclareParentsImplementsReweavableTestAspect.java" | ||||
debug="true"> | debug="true"> |
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"); | |||||
} | |||||
} |
public static void main(String[] args) { | public static void main(String[] args) { | ||||
Annotation[] annotations = SimpleAspect.class.getAnnotations(); | 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]; | Aspect aspectAnnotation = (Aspect) annotations[0]; | ||||
if (!aspectAnnotation.value().equals("")) throw new RuntimeException("value should be empty"); | if (!aspectAnnotation.value().equals("")) throw new RuntimeException("value should be empty"); | ||||
} | } | ||||
} | |||||
} |
runTest("JDK14 LTW with XML"); | runTest("JDK14 LTW with XML"); | ||||
} | } | ||||
public void testJ14LTWWithASPECTPATH() { | |||||
runTest("JDK14 LTW with ASPECTPATH"); | |||||
} | |||||
// public void testJ14LTWWithASPECTPATH() { | |||||
// runTest("JDK14 LTW with ASPECTPATH"); | |||||
// } | |||||
//public void testDiscardingWovenTypes() { | //public void testDiscardingWovenTypes() { |
<stdout> | <stdout> | ||||
<line text="Annotations on field1? true"/> | <line text="Annotations on field1? true"/> | ||||
<line text="Annotation count is 4"/> | <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="@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="Annotations on field2? true"/> | ||||
<line text="Annotation count is 1"/> | <line text="Annotation count is 1"/> | ||||
<line text="@AnnoClass(value=class java.lang.String, ccc=class java.lang.String)"/> | <line text="@AnnoClass(value=class java.lang.String, ccc=class java.lang.String)"/> | ||||
<line text="Annotations on field1? true"/> | <line text="Annotations on field1? true"/> | ||||
<line text="Annotation count is 4"/> | <line text="Annotation count is 4"/> | ||||
<line text="@AnnoChar(value=z, ccc=a)"/> | <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="Annotations on field2? true"/> | ||||
<line text="Annotation count is 2"/> | <line text="Annotation count is 2"/> | ||||
<line text="@AnnoByte(value=88, bbb=66)"/> | <line text="@AnnoByte(value=88, bbb=66)"/> | ||||
<line text="@AnnoInt(value=99, iii=111)"/> | |||||
<line text="@AnnoInt(iii=111, value=99)"/> | |||||
</stdout> | </stdout> | ||||
</run> | </run> | ||||
</ajc-test> | </ajc-test> |
</compile> | </compile> | ||||
<run class="Hello"> | <run class="Hello"> | ||||
<stdout> | <stdout> | ||||
<line text="@MyAnnotation(dummy2=korte, dummy1=)"/> | |||||
<line text="@MyAnnotation(dummy1=, dummy2=korte)"/> | |||||
</stdout> | </stdout> | ||||
</run> | </run> | ||||
</ajc-test> | </ajc-test> |
*/ | */ | ||||
public class Ajc183Tests extends 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() { | public void testConstantPool_445395_0() { | ||||
runTest("constant pool 0"); | runTest("constant pool 0"); | ||||
} | } |
<suite> | <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"> | <ajc-test dir="bugs183/445395" title="constant pool 0"> | ||||
<compile options="-1.8" files="Code.java"> | <compile options="-1.8" files="Code.java"> | ||||
</compile> | </compile> |
File projectBase = new File(sandboxDir, pname); | File projectBase = new File(sandboxDir, pname); | ||||
ICompilerConfiguration icc = compiler.getCompilerConfiguration(); | ICompilerConfiguration icc = compiler.getCompilerConfiguration(); | ||||
List currentFiles = icc.getProjectSourceFiles(); | List currentFiles = icc.getProjectSourceFiles(); | ||||
List filesForCompilation = new ArrayList(); | |||||
List<String> filesForCompilation = new ArrayList<String>(); | |||||
collectUpFiles(projectBase, projectBase, filesForCompilation); | collectUpFiles(projectBase, projectBase, filesForCompilation); | ||||
boolean changed = false; | boolean changed = false; | ||||
for (int i = 0; i < filesForCompilation.size(); i++) { | for (int i = 0; i < filesForCompilation.size(); i++) { |
private Set aspectPath = null; | private Set aspectPath = null; | ||||
private Map sourcePathResources = null; | private Map sourcePathResources = null; | ||||
private IOutputLocationManager outputLocationManager = null; | private IOutputLocationManager outputLocationManager = null; | ||||
private List dependants; | |||||
private List<String> dependants; | |||||
private Map javaOptionsMap; | private Map javaOptionsMap; | ||||
private Set<File> inpath; | private Set<File> inpath; | ||||
private String encoding = null; | private String encoding = null; | ||||
private String processor; | private String processor; | ||||
private String processorPath; | private String processorPath; | ||||
private String nonstandardoptions; | 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 List xmlConfigFiles = new ArrayList(); | ||||
private String projectPath; | private String projectPath; | ||||
return xmlConfigFiles; | return xmlConfigFiles; | ||||
} | } | ||||
public List getProjectSourceFilesChanged() { | |||||
public List<File> getProjectSourceFilesChanged() { | |||||
log("ICompilerConfiguration.getProjectSourceFilesChanged()"); | log("ICompilerConfiguration.getProjectSourceFilesChanged()"); | ||||
return modifiedFiles; | return modifiedFiles; | ||||
} | } | ||||
public void addDependancy(String projectItDependsOn) { | public void addDependancy(String projectItDependsOn) { | ||||
if (dependants == null) { | if (dependants == null) { | ||||
dependants = new ArrayList(); | |||||
dependants = new ArrayList<String>(); | |||||
} | } | ||||
dependants.add(projectItDependsOn); | dependants.add(projectItDependsOn); | ||||
} | } | ||||
this.changed |= ICompilerConfiguration.NONSTANDARDOPTIONS_CHANGED; | this.changed |= ICompilerConfiguration.NONSTANDARDOPTIONS_CHANGED; | ||||
} | } | ||||
public void setProjectSourceFiles(List projectSourceFiles) { | |||||
public void setProjectSourceFiles(List<String> projectSourceFiles) { | |||||
this.projectSourceFiles = projectSourceFiles; | this.projectSourceFiles = projectSourceFiles; | ||||
this.changed |= ICompilerConfiguration.PROJECTSOURCEFILES_CHANGED; | this.changed |= ICompilerConfiguration.PROJECTSOURCEFILES_CHANGED; | ||||
} | } | ||||
public void setProjectXmlConfigFiles(List xmlConfigFiles) { | |||||
public void setProjectXmlConfigFiles(List<String> xmlConfigFiles) { | |||||
this.xmlConfigFiles = xmlConfigFiles; | this.xmlConfigFiles = xmlConfigFiles; | ||||
this.changed |= ICompilerConfiguration.XMLCONFIG_CHANGED; | this.changed |= ICompilerConfiguration.XMLCONFIG_CHANGED; | ||||
} | } | ||||
public void addProjectSourceFileChanged(File f) { | public void addProjectSourceFileChanged(File f) { | ||||
if (this.modifiedFiles == null) { | if (this.modifiedFiles == null) { | ||||
this.modifiedFiles = new ArrayList(); | |||||
this.modifiedFiles = new ArrayList<File>(); | |||||
} | } | ||||
if (f != null) { | if (f != null) { | ||||
modifiedFiles.add(f); | modifiedFiles.add(f); | ||||
public void addClasspathEntryChanged(String f) { | public void addClasspathEntryChanged(String f) { | ||||
if (this.modifiedDirs == null) { | if (this.modifiedDirs == null) { | ||||
this.modifiedDirs = new ArrayList(); | |||||
this.modifiedDirs = new ArrayList<String>(); | |||||
} | } | ||||
if (f != null) { | if (f != null) { | ||||
modifiedDirs.add(f); | modifiedDirs.add(f); |
ensureAnnotationsUnpacked(); | ensureAnnotationsUnpacked(); | ||||
return annotations; | return annotations; | ||||
} | } | ||||
public boolean hasAnnotations() { | |||||
ensureAnnotationsUnpacked(); | |||||
return annotations.length != 0; | |||||
} | |||||
public boolean hasAnnotation(UnresolvedType ofType) { | 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 | // Due to re-entrancy we may be in the middle of unpacking the annotations already... in which case use this slow |
@Override | @Override | ||||
public boolean hasUnsatisfiedDependency(ResolvedType aspectType) { | 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) { | if (aspectRequiredTypes == null) { | ||||
// no aspects require anything, so there can be no unsatisfied dependencies | // no aspects require anything, so there can be no unsatisfied dependencies | ||||
return false; | return false; | ||||
} | } | ||||
String aspectName = aspectType.getName(); | |||||
if (!aspectRequiredTypesProcessed.contains(aspectName)) { | if (!aspectRequiredTypesProcessed.contains(aspectName)) { | ||||
String requiredTypeName = aspectRequiredTypes.get(aspectName); | String requiredTypeName = aspectRequiredTypes.get(aspectName); | ||||
if (requiredTypeName==null) { | if (requiredTypeName==null) { | ||||
if (aspectRequiredTypes == null) { | if (aspectRequiredTypes == null) { | ||||
aspectRequiredTypes = new HashMap<String, String>(); | aspectRequiredTypes = new HashMap<String, String>(); | ||||
} | } | ||||
aspectRequiredTypes.put(aspectClassName, requiredType); | |||||
aspectRequiredTypes.put(aspectClassName,requiredType); | |||||
} | } | ||||
/** | /** |
package org.aspectj.weaver.bcel; | package org.aspectj.weaver.bcel; | ||||
import java.lang.reflect.Modifier; | import java.lang.reflect.Modifier; | ||||
import java.util.Objects; | |||||
import java.util.function.Consumer; | |||||
import org.aspectj.weaver.Advice; | import org.aspectj.weaver.Advice; | ||||
import org.aspectj.weaver.BcweaverTests; | import org.aspectj.weaver.BcweaverTests; | ||||
modifiersTest(iter, abstractPublic | Modifier.INTERFACE); | modifiersTest(iter, abstractPublic | Modifier.INTERFACE); | ||||
fieldsTest(iter, ResolvedMember.NONE); | 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")); | ResolvedMember remove = iter.lookupMethod(MemberImpl.method(iter, 0, "remove", "()V")); | ||||
assertNotNull("iterator doesn't have remove", remove); | 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); | exceptionsTest(remove, UnresolvedType.NONE); | ||||
ResolvedMember clone = iter.lookupMethod(MemberImpl.method(UnresolvedType.OBJECT, 0, "clone", "()Ljava/lang/Object;")); | ResolvedMember clone = iter.lookupMethod(MemberImpl.method(UnresolvedType.OBJECT, 0, "clone", "()Ljava/lang/Object;")); |
} | } | ||||
return annotations; | return annotations; | ||||
} | } | ||||
@Override | |||||
public boolean hasAnnotations() { | |||||
if (annotations == null) { | |||||
annotations = annotationFinder.getAnnotations(getBaseClass(), getWorld()); | |||||
} | |||||
return annotations.length != 0; | |||||
} | |||||
@Override | @Override | ||||
public boolean hasAnnotation(UnresolvedType ofType) { | public boolean hasAnnotation(UnresolvedType ofType) { |