diff options
author | Andy Clement <aclement@pivotal.io> | 2018-01-31 17:21:15 -0800 |
---|---|---|
committer | Andy Clement <aclement@pivotal.io> | 2018-01-31 17:21:15 -0800 |
commit | d6378eeec8c1928462f8561d23fafda5012b790c (patch) | |
tree | b284fae6130eeb739939a7fe7d8ff505241b7c99 | |
parent | 7f0dc0dd21115bfcc9d0ba830e57cc369054d3d5 (diff) | |
parent | 381ccd8684cc181451d44fda4e3044098367fb52 (diff) | |
download | aspectj-d6378eeec8c1928462f8561d23fafda5012b790c.tar.gz aspectj-d6378eeec8c1928462f8561d23fafda5012b790c.zip |
merged
280 files changed, 20471 insertions, 1686 deletions
diff --git a/ajbrowser/ajbrowser.mf.txt b/ajbrowser/ajbrowser.mf.txt index 3974ff57c..ce8030986 100644 --- a/ajbrowser/ajbrowser.mf.txt +++ b/ajbrowser/ajbrowser.mf.txt @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Main-Class: org.aspectj.tools.ajbrowser.Main +Automatic-Module-Name: org.aspectj.tools Name: org/aspectj/tools/ Specification-Title: AspectJ Tools Classes diff --git a/ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserCompilerConfiguration.java b/ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserCompilerConfiguration.java index 26f20bef2..35f676e1b 100644 --- a/ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserCompilerConfiguration.java +++ b/ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserCompilerConfiguration.java @@ -124,4 +124,14 @@ public class BrowserCompilerConfiguration implements ICompilerConfiguration { return null; } + @Override + public String getModulepath() { + return null; + } + + @Override + public String getModuleSourcepath() { + return null; + } + } diff --git a/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java b/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java index ef3a56e69..8f8351759 100644 --- a/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java +++ b/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java @@ -61,10 +61,11 @@ public interface ICompilerConfiguration extends CompilerConfigurationChangeFlags */ public List<File> getProjectSourceFilesChanged(); - /** - * @return the classpath to use - */ public String getClasspath(); + + public String getModulepath(); + + public String getModuleSourcepath(); /** * @return the IOutputLocationManager associated with this compiler configuration diff --git a/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java index 4ab05c968..5577a01af 100644 --- a/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java +++ b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java @@ -37,6 +37,7 @@ import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.Message; import org.aspectj.bridge.SourceLocation; import org.aspectj.bridge.context.CompilationAndWeavingContext; +import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath; import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.aspectj.util.LangUtil; @@ -277,6 +278,14 @@ public class AjdeCoreBuildManager { both.addAll(configClasspath); both.addAll(toAdd); config.setClasspath(both); + Classpath[] checkedClasspaths = config.getCheckedClasspaths(); + ArrayList<Classpath> cps = parser.handleClasspath(toAdd, compilerConfig.getProjectEncoding()); + Classpath[] newCheckedClasspaths = new Classpath[checkedClasspaths.length+cps.size()]; + System.arraycopy(checkedClasspaths, 0, newCheckedClasspaths, 0, checkedClasspaths.length); + for (int i=0;i<cps.size();i++) { + newCheckedClasspaths[checkedClasspaths.length+i] = cps.get(i); + } + config.setCheckedClasspaths(newCheckedClasspaths); } } @@ -295,18 +304,18 @@ public class AjdeCoreBuildManager { } // Process the INPATH - mergeInto(config.getInpath(), compilerConfig.getInpath()); + config.addToInpath(compilerConfig.getInpath()); // bug 168840 - calling 'setInPath(..)' creates BinarySourceFiles which // are used to see if there have been changes in classes on the inpath if (config.getInpath() != null) { - config.setInPath(config.getInpath()); + config.processInPath(); } // Process the SOURCE PATH RESOURCES config.setSourcePathResources(compilerConfig.getSourcePathResources()); // Process the ASPECTPATH - mergeInto(config.getAspectpath(), compilerConfig.getAspectPath()); + config.addToAspectpath(compilerConfig.getAspectPath()); // Process the JAVA OPTIONS MAP Map<String,String> jom = compilerConfig.getJavaOptionsMap(); @@ -347,17 +356,6 @@ public class AjdeCoreBuildManager { return config; } - private <T> void mergeInto(Collection<T> target, Collection<T> source) { - if ((null == target) || (null == source)) { - return; - } - for (T next : source) { - if (!target.contains(next)) { - target.add(next); - } - } - } - /** * Helper method for configure build options. This reads all command-line options specified in the non-standard options text * entry and sets any corresponding unset values in config. diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java b/ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java index c3a46c047..013786611 100644 --- a/ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java +++ b/ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java @@ -22,6 +22,7 @@ import java.util.Set; import org.aspectj.tools.ajc.AjcTests; import org.aspectj.util.FileUtil; +import org.aspectj.util.LangUtil; /** * Test implementation of ICompilerConfiguration. Allows users to configure the settings via setter methods. By default returns null @@ -58,8 +59,15 @@ public class TestCompilerConfiguration implements ICompilerConfiguration { } public String getClasspath() { - return projectPath + File.pathSeparator + System.getProperty("sun.boot.class.path") + File.pathSeparator - + AjcTests.aspectjrtClasspath(); + StringBuilder classpath = new StringBuilder(); + classpath.append(projectPath); + if (LangUtil.is19VMOrGreater()) { + classpath.append(File.pathSeparator).append(LangUtil.getJrtFsFilePath()); + } else { + classpath.append(File.pathSeparator).append(System.getProperty("sun.boot.class.path")); + } + classpath.append(File.pathSeparator).append(AjcTests.aspectjrtClasspath()); + return classpath.toString(); } public Set<File> getInpath() { @@ -179,4 +187,14 @@ public class TestCompilerConfiguration implements ICompilerConfiguration { return null; } + @Override + public String getModulepath() { + return null; + } + + @Override + public String getModuleSourcepath() { + return null; + } + } diff --git a/ajde/testsrc/org/aspectj/ajde/ui/utils/TestCompilerConfiguration.java b/ajde/testsrc/org/aspectj/ajde/ui/utils/TestCompilerConfiguration.java index 2e5520a45..8c3b4ac1f 100644 --- a/ajde/testsrc/org/aspectj/ajde/ui/utils/TestCompilerConfiguration.java +++ b/ajde/testsrc/org/aspectj/ajde/ui/utils/TestCompilerConfiguration.java @@ -25,6 +25,7 @@ import org.aspectj.ajde.core.IOutputLocationManager; import org.aspectj.ajde.core.JavaOptions; import org.aspectj.tools.ajc.AjcTests; import org.aspectj.util.FileUtil; +import org.aspectj.util.LangUtil; /** * Test implementation of ICompilerConfiguration. Allows users to configure the settings via setter methods. By default returns null @@ -64,8 +65,12 @@ public class TestCompilerConfiguration implements ICompilerConfiguration { } public String getClasspath() { - return projectPath + File.pathSeparator + System.getProperty("sun.boot.class.path") + File.pathSeparator + String cp = projectPath + File.pathSeparator + System.getProperty("sun.boot.class.path") + File.pathSeparator + AjcTests.aspectjrtClasspath(); + if (LangUtil.is19VMOrGreater()) { + cp = LangUtil.getJrtFsFilePath()+File.pathSeparator+cp; + } + return cp; } public Set getInpath() { @@ -184,4 +189,14 @@ public class TestCompilerConfiguration implements ICompilerConfiguration { return null; } + @Override + public String getModulepath() { + return null; + } + + @Override + public String getModuleSourcepath() { + return null; + } + } diff --git a/ajdoc/.settings/org.eclipse.jdt.core.prefs b/ajdoc/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..f42de363a --- /dev/null +++ b/ajdoc/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/ajdoc/ajdoc.mf.txt b/ajdoc/ajdoc.mf.txt index 6eddf9ffe..8ccc1f6de 100644 --- a/ajdoc/ajdoc.mf.txt +++ b/ajdoc/ajdoc.mf.txt @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Main-Class: org.aspectj.tools.ajdoc.Main +Automatic-Module-Name: org.aspectj.tools Name: org/aspectj/tools/ Specification-Title: AspectJ Tools Classes diff --git a/ajdoc/src/org/aspectj/tools/ajdoc/HtmlDecorator.java b/ajdoc/src/org/aspectj/tools/ajdoc/HtmlDecorator.java index f873c3e55..ec492fce9 100644 --- a/ajdoc/src/org/aspectj/tools/ajdoc/HtmlDecorator.java +++ b/ajdoc/src/org/aspectj/tools/ajdoc/HtmlDecorator.java @@ -48,7 +48,7 @@ class HtmlDecorator { private static final String ITD_FIELD_SUMMARY = "Inter-Type Field Summary"; private static final String ITD_CONSTRUCTOR_SUMMARY = "Inter-Type Constructor Summary"; - static List visibleFileList = new ArrayList(); + static List<String> visibleFileList = new ArrayList<String>(); static Hashtable declIDTable = null; static File rootDir = null; static String docVisibilityModifier; @@ -291,22 +291,22 @@ class HtmlDecorator { } static void addAspectDocumentation(IProgramElement node, StringBuffer fileBuffer, int index) { - List pointcuts = new ArrayList(); - List advice = new ArrayList(); - List declares = new ArrayList(); - List methodsDeclaredOn = StructureUtil.getDeclareInterTypeTargets(node, IProgramElement.Kind.INTER_TYPE_METHOD); + List<IProgramElement> pointcuts = new ArrayList<IProgramElement>(); + List<IProgramElement> advice = new ArrayList<IProgramElement>(); + List<IProgramElement> declares = new ArrayList<IProgramElement>(); + List<IProgramElement> methodsDeclaredOn = StructureUtil.getDeclareInterTypeTargets(node, IProgramElement.Kind.INTER_TYPE_METHOD); if (methodsDeclaredOn != null && !methodsDeclaredOn.isEmpty()) { insertDeclarationsSummary(fileBuffer, methodsDeclaredOn, ITD_METHOD_SUMMARY, index); } - List fieldsDeclaredOn = StructureUtil.getDeclareInterTypeTargets(node, IProgramElement.Kind.INTER_TYPE_FIELD); + List<IProgramElement> fieldsDeclaredOn = StructureUtil.getDeclareInterTypeTargets(node, IProgramElement.Kind.INTER_TYPE_FIELD); if (fieldsDeclaredOn != null && !fieldsDeclaredOn.isEmpty()) { insertDeclarationsSummary(fileBuffer, fieldsDeclaredOn, ITD_FIELD_SUMMARY, index); } - List constDeclaredOn = StructureUtil.getDeclareInterTypeTargets(node, IProgramElement.Kind.INTER_TYPE_CONSTRUCTOR); + List<IProgramElement> constDeclaredOn = StructureUtil.getDeclareInterTypeTargets(node, IProgramElement.Kind.INTER_TYPE_CONSTRUCTOR); if (fieldsDeclaredOn != null && !constDeclaredOn.isEmpty()) { insertDeclarationsSummary(fileBuffer, constDeclaredOn, ITD_CONSTRUCTOR_SUMMARY, index); } - for (Iterator it = node.getChildren().iterator(); it.hasNext();) { + for (Iterator<IProgramElement> it = node.getChildren().iterator(); it.hasNext();) { IProgramElement member = (IProgramElement) it.next(); if (member.getKind().equals(IProgramElement.Kind.POINTCUT)) { pointcuts.add(member); @@ -329,17 +329,17 @@ class HtmlDecorator { insertDeclarationsDetails(fileBuffer, advice, ADVICE_DETAIL, index); } // add the 'aspect declarations' information against the type - List parentsDeclaredOn = StructureUtil.getDeclareInterTypeTargets(node, IProgramElement.Kind.DECLARE_PARENTS); + List<IProgramElement> parentsDeclaredOn = StructureUtil.getDeclareInterTypeTargets(node, IProgramElement.Kind.DECLARE_PARENTS); if (parentsDeclaredOn != null && parentsDeclaredOn.size() > 0) { decorateDocWithRel(node, fileBuffer, index, parentsDeclaredOn, HtmlRelationshipKind.ASPECT_DECLARATIONS); } // add the 'annotated by' information against the type - List annotatedBy = StructureUtil.getTargets(node, IRelationship.Kind.DECLARE_INTER_TYPE, "annotated by"); + List<String> annotatedBy = StructureUtil.getTargets(node, IRelationship.Kind.DECLARE_INTER_TYPE, "annotated by"); if (annotatedBy != null && annotatedBy.size() > 0) { decorateDocWithRel(node, fileBuffer, index, annotatedBy, HtmlRelationshipKind.ANNOTATED_BY); } // add the 'advised by' information against the type - List advisedBy = StructureUtil.getTargets(node, IRelationship.Kind.ADVICE); + List<String> advisedBy = StructureUtil.getTargets(node, IRelationship.Kind.ADVICE); if (advisedBy != null && advisedBy.size() > 0) { decorateDocWithRel(node, fileBuffer, index, advisedBy, HtmlRelationshipKind.ADVISED_BY); } @@ -621,16 +621,16 @@ class HtmlDecorator { } static void decorateMemberDocumentation(IProgramElement node, StringBuffer fileContentsBuffer, int index) { - List targets = StructureUtil.getTargets(node, IRelationship.Kind.ADVICE); + List<String> targets = StructureUtil.getTargets(node, IRelationship.Kind.ADVICE); decorateDocWithRel(node, fileContentsBuffer, index, targets, HtmlRelationshipKind.ADVISED_BY); - List warnings = StructureUtil.getTargets(node, IRelationship.Kind.DECLARE, "matches declare"); + List<String> warnings = StructureUtil.getTargets(node, IRelationship.Kind.DECLARE, "matches declare"); decorateDocWithRel(node, fileContentsBuffer, index, warnings, HtmlRelationshipKind.MATCHES_DECLARE); - List softenedBy = StructureUtil.getTargets(node, IRelationship.Kind.DECLARE, "softened by"); + List<String> softenedBy = StructureUtil.getTargets(node, IRelationship.Kind.DECLARE, "softened by"); decorateDocWithRel(node, fileContentsBuffer, index, softenedBy, HtmlRelationshipKind.SOFTENED_BY); - List annotatedBy = StructureUtil.getTargets(node, IRelationship.Kind.DECLARE_INTER_TYPE, "annotated by"); + List<String> annotatedBy = StructureUtil.getTargets(node, IRelationship.Kind.DECLARE_INTER_TYPE, "annotated by"); decorateDocWithRel(node, fileContentsBuffer, index, annotatedBy, HtmlRelationshipKind.ANNOTATED_BY); } diff --git a/ajdoc/src/org/aspectj/tools/ajdoc/JavadocRunner.java b/ajdoc/src/org/aspectj/tools/ajdoc/JavadocRunner.java index b0ab3cd21..37b727175 100644 --- a/ajdoc/src/org/aspectj/tools/ajdoc/JavadocRunner.java +++ b/ajdoc/src/org/aspectj/tools/ajdoc/JavadocRunner.java @@ -14,9 +14,12 @@ package org.aspectj.tools.ajdoc; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import org.aspectj.util.LangUtil; + /** * @author Mik Kersten */ @@ -62,7 +65,12 @@ class JavadocRunner { // defaultSecurityManager.checkPermission( permission, context ); // } // } ); - + + // Need to do something different on Java > 9 due to removal of standard doclet I think +// if (LangUtil.is19VMOrGreater()) { +// // Not visible according to module rules... +// clazz = Class.forName("jdk.javadoc.internal.tool.Main"); +// } try { // for JDK 1.4 and above call the execute method... Class jdMainClass = com.sun.tools.javadoc.Main.class; diff --git a/ajdoc/src/org/aspectj/tools/ajdoc/Main.java b/ajdoc/src/org/aspectj/tools/ajdoc/Main.java index 5c9047dcb..e8f1472b5 100644 --- a/ajdoc/src/org/aspectj/tools/ajdoc/Main.java +++ b/ajdoc/src/org/aspectj/tools/ajdoc/Main.java @@ -47,24 +47,24 @@ public class Main implements Config { private static final String FAIL_MESSAGE = "> compile failed, exiting ajdoc"; /** Command line options. */ - static Vector options; + static Vector<String> options; /** Options to pass to ajc. */ - static Vector ajcOptions; + static Vector<String> ajcOptions; /** All of the files to be processed by ajdoc. */ - static Vector filenames; + static Vector<String> filenames; /** List of files to pass to javadoc. */ - static Vector fileList; + static Vector<String> fileList; /** List of packages to pass to javadoc. */ - static Vector packageList; + static Vector<String> packageList; /** Default to package visiblity. */ static String docModifier = "package"; - static Vector sourcepath; + static Vector<String> sourcepath; static boolean verboseMode = false; static boolean packageMode = false; @@ -85,13 +85,13 @@ public class Main implements Config { private static String outputWorkingDir = Config.WORKING_DIR; public static void clearState() { - options = new Vector(); - ajcOptions = new Vector(); - filenames = new Vector(); - fileList = new Vector(); - packageList = new Vector(); + options = new Vector<String>(); + ajcOptions = new Vector<String>(); + filenames = new Vector<String>(); + fileList = new Vector<String>(); + packageList = new Vector<String>(); docModifier = "package"; - sourcepath = new Vector(); + sourcepath = new Vector<String>(); verboseMode = false; packageMode = false; rootDir = null; @@ -169,7 +169,7 @@ public class Main implements Config { * package-summary properly. */ private static void packageHTML(AsmManager model, File[] inputFiles) throws IOException { - ArrayList dirList = new ArrayList(); + ArrayList<String> dirList = new ArrayList<String>(); for (int i = 0; i < inputFiles.length; i++) { String packageName = StructureUtil.getPackageDeclarationFromFile(model, inputFiles[i]); // Only copy the package.html file once. @@ -192,7 +192,7 @@ public class Main implements Config { String pathName = outputWorkingDir + File.separator + packageName.replace('.', File.separatorChar); File packageDir = new File(pathName); if (!packageDir.exists()) { - dirList.add(packageDir); + dirList.add(packageName); continue; } packageName = packageName.replace('.', '/'); // !!! @@ -273,7 +273,6 @@ public class Main implements Config { javadocargs[options.size() + k] = StructureUtil.translateAjPathName(signatureFiles[k].getCanonicalPath()); } } - JavadocRunner.callJavadoc(javadocargs); } @@ -345,8 +344,8 @@ public class Main implements Config { } } - static Vector getSourcePath() { - Vector sourcePath = new Vector(); + static Vector<String> getSourcePath() { + Vector<String> sourcePath = new Vector<String>(); boolean found = false; for (int i = 0; i < options.size(); i++) { String currOption = (String) options.elementAt(i); @@ -455,14 +454,14 @@ public class Main implements Config { String line = ""; line = br.readLine(); StringTokenizer st = new StringTokenizer(line, " "); - List argList = new ArrayList(); + List<String> argList = new ArrayList<String>(); while (st.hasMoreElements()) { - argList.add(st.nextElement()); + argList.add(st.nextToken()); } // System.err.println(argList); args = new String[argList.size()]; int counter = 0; - for (Iterator it = argList.iterator(); it.hasNext();) { + for (Iterator<String> it = argList.iterator(); it.hasNext();) { args[counter] = (String) it.next(); counter++; } @@ -474,7 +473,7 @@ public class Main implements Config { ioe.printStackTrace(); } } - List vargs = new LinkedList(Arrays.asList(args)); + List<String> vargs = new LinkedList<String>(Arrays.asList(args)); vargs.add("-Xset:minimalModel=false"); parseArgs(vargs, new File(".")); // !!! @@ -488,7 +487,7 @@ public class Main implements Config { arg = arg + File.pathSeparator; // makes things easier for ourselves StringTokenizer tokenizer = new StringTokenizer(arg, File.pathSeparator); while (tokenizer.hasMoreElements()) { - sourcepath.addElement(tokenizer.nextElement()); + sourcepath.addElement(tokenizer.nextToken()); } } @@ -705,7 +704,7 @@ public class Main implements Config { } static void expandAtSignFile(String filename, File currentWorkingDir) { - List result = new LinkedList(); + List<String> result = new LinkedList<String>(); File atFile = qualifiedFile(filename, currentWorkingDir); String atFileParent = atFile.getParent(); @@ -730,6 +729,7 @@ public class Main implements Config { continue; result.add(line); } + stream.close(); } catch (IOException e) { System.err.println("Error while reading the @ file " + atFile.getPath() + ".\n" + e); System.exit(-1); diff --git a/ajdoc/src/org/aspectj/tools/ajdoc/StructureUtil.java b/ajdoc/src/org/aspectj/tools/ajdoc/StructureUtil.java index 6f9ad7790..3d866b625 100644 --- a/ajdoc/src/org/aspectj/tools/ajdoc/StructureUtil.java +++ b/ajdoc/src/org/aspectj/tools/ajdoc/StructureUtil.java @@ -31,7 +31,7 @@ public class StructureUtil { * * @return null if a relationship of that kind is not found */ - public static List /* String */getTargets(IProgramElement node, IRelationship.Kind kind) { + public static List<String> getTargets(IProgramElement node, IRelationship.Kind kind) { return getTargets(node, kind, null); } @@ -41,21 +41,21 @@ public class StructureUtil { * * @return null if a relationship of that kind is not found */ - public static List /* String */getTargets(IProgramElement node, IRelationship.Kind kind, String relName) { - List relations = new ArrayList(); - List rels = node.getModel().getRelationshipMap().get(node); + public static List<String> getTargets(IProgramElement node, IRelationship.Kind kind, String relName) { + List<IRelationship> relations = new ArrayList<IRelationship>(); + List<IRelationship> rels = node.getModel().getRelationshipMap().get(node); if (rels != null) { relations.addAll(rels); } - for (Iterator iter = node.getChildren().iterator(); iter.hasNext();) { + for (Iterator<IProgramElement> iter = node.getChildren().iterator(); iter.hasNext();) { IProgramElement child = (IProgramElement) iter.next(); // if we're not a type, or if we are and the child is code, then // we want to get the relationships for this child - this means that the // correct relationships appear against the type in the ajdoc if (!node.getKind().isType() || child.getKind().equals(IProgramElement.Kind.CODE)) { - List childRelations = node.getModel().getRelationshipMap().get(child); + List<IRelationship> childRelations = node.getModel().getRelationshipMap().get(child); if (childRelations != null) { - for (Iterator iterator = childRelations.iterator(); iterator.hasNext();) { + for (Iterator<IRelationship> iterator = childRelations.iterator(); iterator.hasNext();) { IRelationship rel = (IRelationship) iterator.next(); if (!relations.contains(rel)) { relations.add(rel); @@ -66,13 +66,12 @@ public class StructureUtil { } if (relations == null || relations.isEmpty()) return null; - List targets = new ArrayList(); - for (Iterator it = relations.iterator(); it.hasNext();) { + List<String> targets = new ArrayList<String>(); + for (Iterator<IRelationship> it = relations.iterator(); it.hasNext();) { IRelationship rtn = (IRelationship) it.next(); if (rtn.getKind().equals(kind) && ((relName != null && relName.equals(rtn.getName())) || relName == null)) { - List targs = rtn.getTargets(); - for (Iterator iter = targs.iterator(); iter.hasNext();) { - String element = (String) iter.next(); + List<String> targs = rtn.getTargets(); + for (String element: targs) { if (!targets.contains(element)) { targets.add(element); } @@ -82,14 +81,13 @@ public class StructureUtil { return targets; } - static List /* IProgramElement */getDeclareInterTypeTargets(IProgramElement node, IProgramElement.Kind kind) { - List targets = new ArrayList(); - List stringTargets = StructureUtil.getTargets(node, IRelationship.Kind.DECLARE_INTER_TYPE); + static List<IProgramElement> getDeclareInterTypeTargets(IProgramElement node, IProgramElement.Kind kind) { + List<IProgramElement> targets = new ArrayList<IProgramElement>(); + List<String> stringTargets = StructureUtil.getTargets(node, IRelationship.Kind.DECLARE_INTER_TYPE); if (stringTargets == null) { return null; } - for (Iterator iter = stringTargets.iterator(); iter.hasNext();) { - String element = (String) iter.next(); + for (String element: stringTargets) { IProgramElement ipe = node.getModel().getHierarchy().findElementForHandle(element); if (ipe != null && ipe.getKind().equals(kind)) { targets.add(ipe); @@ -98,13 +96,12 @@ public class StructureUtil { return targets; } - public static List/* String */getDeclareTargets(IProgramElement node) { - List relations = node.getModel().getRelationshipMap().get(node); - List targets = null; + public static List<String> getDeclareTargets(IProgramElement node) { + List<IRelationship> relations = node.getModel().getRelationshipMap().get(node); + List<String> targets = null; if (relations == null) return null; - for (Iterator it = relations.iterator(); it.hasNext();) { - IRelationship rtn = (IRelationship) it.next(); + for (IRelationship rtn: relations) { if (rtn.getKind().isDeclareKind()) { targets = rtn.getTargets(); } diff --git a/ajdoc/testsrc/org/aspectj/tools/ajdoc/AjdocTestCase.java b/ajdoc/testsrc/org/aspectj/tools/ajdoc/AjdocTestCase.java index 2db299f37..ea9a81875 100644 --- a/ajdoc/testsrc/org/aspectj/tools/ajdoc/AjdocTestCase.java +++ b/ajdoc/testsrc/org/aspectj/tools/ajdoc/AjdocTestCase.java @@ -19,6 +19,7 @@ import junit.framework.AssertionFailedError; import junit.framework.TestCase; import org.aspectj.tools.ajc.Ajc; +import org.aspectj.util.LangUtil; /** * This class is the super class of all Ajdoc tests. It creates a sandbox directory and provides utility methods for copying over @@ -159,8 +160,14 @@ public class AjdocTestCase extends TestCase { if (inputFiles.length == 0) { fail("need to pass some files into ajdoc"); } - if (!sourceLevel.equals("1.3") && !sourceLevel.equals("1.4") && !sourceLevel.equals("1.5")) { - fail("need to pass ajdoc '1.3', '1.4', or '1.5' as the source level"); + if (!sourceLevel.equals("1.3") && + !sourceLevel.equals("1.4") && + !sourceLevel.equals("1.5") && + !sourceLevel.equals("1.6") && + !sourceLevel.equals("1.7") && + !sourceLevel.equals("1.8") && + !sourceLevel.equals("1.9")) { + fail("need to pass ajdoc '1.3' > '1.9' as the source level"); } String[] args = new String[6 + inputFiles.length + ajOptions.length]; args[0] = "-source"; @@ -185,8 +192,16 @@ public class AjdocTestCase extends TestCase { if (!visibility.equals("public") && !visibility.equals("protected") && !visibility.equals("private")) { fail("need to pass 'public','protected' or 'private' visibility to ajdoc"); } - if (!sourceLevel.equals("1.3") && !sourceLevel.equals("1.4") && !sourceLevel.equals("1.5")) { - fail("need to pass ajdoc '1.3', '1.4', or '1.5' as the source level"); + if (!sourceLevel.equals("1.3") && + !sourceLevel.equals("1.4") && + !sourceLevel.equals("1.5") && + !sourceLevel.equals("1.6") && + !sourceLevel.equals("1.7") && + !sourceLevel.equals("1.8") && + !sourceLevel.equals("1.9") && + !sourceLevel.startsWith("9") && + !sourceLevel.startsWith("10")) { + fail("need to pass suitable version to ajdoc as the source level"); } if (inputFiles.length == 0) { fail("need to pass some files into ajdoc"); @@ -202,7 +217,12 @@ public class AjdocTestCase extends TestCase { args[1] = "-source"; args[2] = sourceLevel; args[3] = "-classpath"; - args[4] = AjdocTests.ASPECTJRT_PATH.getPath(); + StringBuilder classpath = new StringBuilder(); + if (LangUtil.is19VMOrGreater()) { + classpath.append(LangUtil.getJrtFsFilePath()).append(File.pathSeparator); + } + classpath.append(AjdocTests.ASPECTJRT_PATH.getPath()); + args[4] = classpath.toString(); args[5] = "-d"; args[6] = getAbsolutePathOutdir(); // args[7] = "-Xset:minimalModel=false"; diff --git a/ajdoc/testsrc/org/aspectj/tools/ajdoc/BugTests.java b/ajdoc/testsrc/org/aspectj/tools/ajdoc/BugTests.java index 647b71b22..163774864 100644 --- a/ajdoc/testsrc/org/aspectj/tools/ajdoc/BugTests.java +++ b/ajdoc/testsrc/org/aspectj/tools/ajdoc/BugTests.java @@ -69,7 +69,7 @@ public class BugTests extends AjdocTestCase { initialiseProject("pr148906"); File[] files = {new File(getAbsoluteProjectDir() + "/C.java")}; String[] ajOptions = {new String("-aspectpath"), new String(getAbsoluteProjectDir() + File.separator + "simple.jar")}; - runAjdoc(files,"1.5",ajOptions); + runAjdoc(files,"1.6",ajOptions); assertFalse("expected clean build of project but found that build aborted",Main.hasAborted()); File html = new File(getAbsolutePathOutdir() + File.separator + "C.html"); if (!html.exists()) { @@ -90,7 +90,7 @@ public class BugTests extends AjdocTestCase { initialiseProject("pr148906"); File[] files = {new File(getAbsoluteProjectDir() + "/C.java")}; String[] ajOptions = {new String("-outxml"),new String("-aspectpath"), new String(getAbsoluteProjectDir() + File.separator + "simple.jar")}; - runAjdoc(files,"1.5",ajOptions); + runAjdoc(files,"1.6",ajOptions); assertFalse("expected clean build of project but found that build aborted",Main.hasAborted()); File html = new File(getAbsolutePathOutdir() + File.separator + "C.html"); if (!html.exists()) { diff --git a/ajdoc/testsrc/org/aspectj/tools/ajdoc/CoverageTestCase.java b/ajdoc/testsrc/org/aspectj/tools/ajdoc/CoverageTestCase.java index 6ee7f7a88..af9ab0ed9 100644 --- a/ajdoc/testsrc/org/aspectj/tools/ajdoc/CoverageTestCase.java +++ b/ajdoc/testsrc/org/aspectj/tools/ajdoc/CoverageTestCase.java @@ -16,7 +16,6 @@ import java.util.List; import org.aspectj.util.LangUtil; - /** * A long way to go until full coverage, but this is the place to add more. * @@ -56,7 +55,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testCoveragePublicMode() throws Exception { File[] files = {file3,file9}; - runAjdoc("public","1.4",files); + runAjdoc("public","9",files); // have passed the "public" modifier as well as // one public and one package visible class. There @@ -88,7 +87,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAJdocHasAspectTitle() throws Exception { File[] files = {new File(getAbsoluteProjectDir() + "/pkg/A.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/A.html"); if (!htmlFile.exists()) { fail("couldn't find " + htmlFile.getAbsolutePath()+ " - were there compilation errors?"); @@ -102,7 +101,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAJdocHasClassTitle() throws Exception { File[] files = {new File(getAbsoluteProjectDir() + "/pkg/C.java")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/C.html"); if (!htmlFile.exists()) { fail("couldn't find " + htmlFile.getAbsolutePath()+ " - were there compilation errors?"); @@ -118,7 +117,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testInnerAspect() throws Exception { File[] files = {file1, file2}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/ClassA.InnerAspect.html"); if (!htmlFile.exists()) { @@ -206,7 +205,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdviceNamingCoverage() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/AdviceNamingCoverage.html"); if (!htmlFile.exists()) { @@ -238,7 +237,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdvisesRelationshipCoverage() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/AdvisesRelationshipCoverage.html"); if (!htmlFile.exists()) { @@ -291,7 +290,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdvisedByMethodExecution() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html"); if (!htmlFile.exists()) { @@ -322,7 +321,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdvisedByConstructorExecution() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html"); if (!htmlFile.exists()) { @@ -353,7 +352,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdvisedByMethodCall() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html"); if (!htmlFile.exists()) { @@ -384,7 +383,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdvisedByConstructorCall() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html"); if (!htmlFile.exists()) { @@ -415,7 +414,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdvisedByGet() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html"); if (!htmlFile.exists()) { @@ -446,7 +445,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdvisedBySet() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html"); if (!htmlFile.exists()) { @@ -495,7 +494,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdvisedByInitialization() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html"); if (!htmlFile.exists()) { @@ -523,7 +522,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdvisedByStaticInitialization() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html"); if (!htmlFile.exists()) { @@ -544,7 +543,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdvisedByHandler() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point.html"); if (!htmlFile.exists()) { @@ -582,7 +581,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testTwoBeforeAdvice() throws Exception { File[] files = {new File(getAbsoluteProjectDir() + "/pkg/A2.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/C2.html"); if (!htmlFile.exists()) { @@ -628,7 +627,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testNoSpuriousAdvisedByRels() throws Exception { File[] files = {file4}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/AdvisesRelationshipCoverage.html"); if (!htmlFile.exists()) { @@ -647,7 +646,7 @@ public class CoverageTestCase extends AjdocTestCase { public void testCoverage() { File[] files = {aspect1,file0,file1,file2,file3,file4,file5,file6, file7,file8,file9,file10}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); } /** @@ -657,7 +656,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testNestedAspect() throws Exception { File[] files = {file9}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/PkgVisibleClass.NestedAspect.html"); if (!htmlFile.exists()) { @@ -739,7 +738,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testNestedAspectWithSimilarName() throws Exception { File[] files = {new File(getAbsoluteProjectDir() + "/pkg/ClassWithNestedAspect.java")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/ClassWithNestedAspect.NestedAspect.html"); if (!htmlFile.exists()) { @@ -820,7 +819,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdviceInNestedAspect() throws Exception { File[] files = {new File(getAbsoluteProjectDir() + "/pkg/ClassWithNestedAspect.java")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/ClassWithNestedAspect.NestedAspect.html"); if (!htmlFile.exists()) { @@ -851,7 +850,7 @@ public class CoverageTestCase extends AjdocTestCase { */ public void testAdvisedByInNestedAspect() throws Exception { File[] files = {new File(getAbsoluteProjectDir() + "/pkg/ClassWithNestedAspect.java")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/ClassWithNestedAspect.html"); if (!htmlFile.exists()) { diff --git a/ajdoc/testsrc/org/aspectj/tools/ajdoc/DeclareFormsTest.java b/ajdoc/testsrc/org/aspectj/tools/ajdoc/DeclareFormsTest.java index fbb711bdc..130a43a9e 100644 --- a/ajdoc/testsrc/org/aspectj/tools/ajdoc/DeclareFormsTest.java +++ b/ajdoc/testsrc/org/aspectj/tools/ajdoc/DeclareFormsTest.java @@ -39,7 +39,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testCoverage() { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareCoverage.java")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); } /** @@ -49,7 +49,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testDeclareStatments() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareCoverage2.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/DeclareCoverage2.html"); if (!htmlFile.exists()) { @@ -84,7 +84,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testDeclareWarning() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareCoverage2.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/DeclareCoverage2.html"); if (!htmlFile.exists()) { @@ -116,7 +116,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testMatchesDeclareCall() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareCoverage2.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Main2.html"); if (!htmlFile.exists()) { @@ -149,7 +149,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testMatchesDeclareExecution() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareCoverage2.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point2.html"); if (!htmlFile.exists()) { @@ -180,7 +180,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testDeclareParents() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareCoverage2.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/DeclareCoverage2.html"); if (!htmlFile.exists()) { @@ -211,7 +211,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testAspectDeclarations() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareCoverage2.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Point2.html"); if (!htmlFile.exists()) { @@ -234,7 +234,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testDeclareSoft() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareCoverage2.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/DeclareCoverage2.html"); if (!htmlFile.exists()) { @@ -265,7 +265,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testSoftenedBy() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareCoverage2.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/Main2.html"); if (!htmlFile.exists()) { @@ -304,7 +304,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testDeclareAnnotation() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareAtType.aj")}; - runAjdoc("private","1.5",files); + runAjdoc("private","1.6",files); // Aspect AnnotationTest should contain within it's declare // detail and summary the declare annotation statement. @@ -350,7 +350,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testMethodAnnotatedBy() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareAtMethod.aj")}; - runAjdoc("private","1.5",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/C.html"); if (!htmlFile.exists()) { @@ -383,7 +383,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testConstructorAnnotatedBy() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareAtConstructor.aj")}; - runAjdoc("private","1.5",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/C.html"); if (!htmlFile.exists()) { @@ -417,7 +417,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testFieldAnnotatedBy() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareAtField.aj")}; - runAjdoc("private","1.5",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/C.html"); if (!htmlFile.exists()) { @@ -451,7 +451,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testTypeAnnotatedBy() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareAtType.aj")}; - runAjdoc("private","1.5",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/C.html"); if (!htmlFile.exists()) { @@ -474,7 +474,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testMatchesDeclareAndAdvisedBy() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "A.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/C.html"); if (!htmlFile.exists()) { @@ -520,7 +520,7 @@ public class DeclareFormsTest extends AjdocTestCase { public void testTwoDeclareParents() throws Exception { initialiseProject("declareForms"); File[] files = {new File(getAbsoluteProjectDir() + File.separatorChar + "DeclareParents.aj")}; - runAjdoc("private","1.4",files); + runAjdoc("private","1.6",files); File htmlFile = new File(getAbsolutePathOutdir() + "/foo/DeclareParents.html"); if (!htmlFile.exists()) { diff --git a/aspectj5rt/.settings/org.eclipse.jdt.core.prefs b/aspectj5rt/.settings/org.eclipse.jdt.core.prefs index 8d1e54a3c..b42efae28 100644 --- a/aspectj5rt/.settings/org.eclipse.jdt.core.prefs +++ b/aspectj5rt/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,3 @@ -#Tue Jan 16 09:21:46 GMT 2007 eclipse.preferences.version=1 org.eclipse.jdt.core.builder.cleanOutputFolder=clean org.eclipse.jdt.core.builder.duplicateResourceTask=warning @@ -8,9 +7,9 @@ org.eclipse.jdt.core.circularClasspath=error org.eclipse.jdt.core.classpath.exclusionPatterns=enabled org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.compliance=1.7 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -58,6 +57,6 @@ org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore -org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.source=1.7 org.eclipse.jdt.core.incompatibleJDKLevel=ignore org.eclipse.jdt.core.incompleteClasspath=error diff --git a/aspectj5rt/aspectj5rt.mf.txt b/aspectj5rt/aspectj5rt.mf.txt index 5092d4233..dcc05a161 100644 --- a/aspectj5rt/aspectj5rt.mf.txt +++ b/aspectj5rt/aspectj5rt.mf.txt @@ -1,4 +1,5 @@ Manifest-Version: 1.0 +Automatic-Module-Name: org.aspectj.runtime Name: org/aspectj/lang/ Specification-Title: AspectJ Runtime Classes diff --git a/bcel-builder/.isJava5 b/bcel-builder/.isJava7 index 136d06384..136d06384 100644 --- a/bcel-builder/.isJava5 +++ b/bcel-builder/.isJava7 diff --git a/bcel-builder/.settings/org.eclipse.jdt.core.prefs b/bcel-builder/.settings/org.eclipse.jdt.core.prefs index 52e4117af..a7d4334af 100644 --- a/bcel-builder/.settings/org.eclipse.jdt.core.prefs +++ b/bcel-builder/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ -#Tue Sep 08 17:08:00 PDT 2009 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.compliance=1.7 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -54,4 +54,4 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=di org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/bcel-builder/src/org/aspectj/apache/bcel/Constants.java b/bcel-builder/src/org/aspectj/apache/bcel/Constants.java index 0bba78fc4..85abecff7 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/Constants.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/Constants.java @@ -80,6 +80,8 @@ public interface Constants { public final static short MINOR_1_7 = 0; public final static short MAJOR_1_8 = 52; public final static short MINOR_1_8 = 0; + public final static short MAJOR_1_9 = 53; + public final static short MINOR_1_9 = 0; // Defaults public final static short MAJOR = MAJOR_1_1; public final static short MINOR = MINOR_1_1; @@ -107,11 +109,27 @@ public interface Constants { public final static short ACC_STRICT = 0x0800; public final static short ACC_SYNTHETIC = 0x1000; + public final static short ACC_ANNOTATION = 0x2000; public final static short ACC_ENUM = 0x4000; + public final static int ACC_MODULE = 0x8000; public final static short ACC_BRIDGE = 0x0040; public final static short ACC_VARARGS = 0x0080; + // Module related + // Indicates that any module which depends on the current module, + // implicitly declares a dependence on the module indicated by this entry. + public final static int MODULE_ACC_TRANSITIVE = 0x0020; + // Indicates that this dependence is mandatory in the static phase, i.e., at + // compile time, but is optional in the dynamic phase, i.e., at run time. + public final static int MODULE_ACC_STATIC_PHASE = 0x0040; + // Indicates that this dependence was not explicitly or implicitly declared + // in the source of the module declaration. + public final static int MODULE_ACC_SYNTHETIC = 0x1000; + // Indicates that this dependence was implicitly declared in the source of + // the module declaration + public final static int MODULE_ACC_MANDATED = 0x8000; + // Applies to classes compiled by new compilers only public final static short ACC_SUPER = 0x0020; @@ -136,10 +154,17 @@ public interface Constants { public final static byte CONSTANT_MethodHandle = 15; public final static byte CONSTANT_MethodType = 16; public final static byte CONSTANT_InvokeDynamic = 18; + + // J9: + public final static byte CONSTANT_Module = 19; + public final static byte CONSTANT_Package = 20; + public final static String[] CONSTANT_NAMES = { "", "CONSTANT_Utf8", "", "CONSTANT_Integer", "CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double", "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref", "CONSTANT_Methodref", - "CONSTANT_InterfaceMethodref", "CONSTANT_NameAndType","","","CONSTANT_MethodHandle","CONSTANT_MethodType","","CONSTANT_InvokeDynamic" }; + "CONSTANT_InterfaceMethodref", "CONSTANT_NameAndType","","","CONSTANT_MethodHandle","CONSTANT_MethodType","","CONSTANT_InvokeDynamic", + // J9: + "CONSTANT_Module", "CONSTANT_Package"}; /** * The name of the static initializer, also called "class initialization method" or "interface initialization @@ -617,8 +642,13 @@ public interface Constants { public static final byte ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = 20; public static final byte ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = 21; public static final byte ATTR_METHOD_PARAMETERS = 22; - - public static final short KNOWN_ATTRIBUTES = 23; + + // J9: + public static final byte ATTR_MODULE = 23; + public static final byte ATTR_MODULE_PACKAGES = 24; + public static final byte ATTR_MODULE_MAIN_CLASS = 25; + + public static final short KNOWN_ATTRIBUTES = 26; public static final String[] ATTRIBUTE_NAMES = { "SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", "LocalVariableTable", @@ -626,7 +656,7 @@ public interface Constants { "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", "RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations", "LocalVariableTypeTable", "EnclosingMethod", "AnnotationDefault","BootstrapMethods", "RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations", - "MethodParameters" + "MethodParameters", "Module", "ModulePackages", "ModuleMainClass" }; /** diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java index 34ed08f5e..edc8d22c9 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java @@ -167,6 +167,12 @@ public abstract class Attribute implements Cloneable, Node, Serializable { return new RuntimeInvisTypeAnnos(idx, len, file, cpool); case Constants.ATTR_METHOD_PARAMETERS: return new MethodParameters(idx, len, file, cpool); + case Constants.ATTR_MODULE: + return new Module(idx, len, file, cpool); + case Constants.ATTR_MODULE_PACKAGES: + return new ModulePackages(idx, len, file, cpool); + case Constants.ATTR_MODULE_MAIN_CLASS: + return new ModuleMainClass(idx, len, file, cpool); default: throw new IllegalStateException(); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java index f7e794c8c..54882beee 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java @@ -180,7 +180,6 @@ public final class ClassParser { superclassnameIndex = file.readUnsignedShort(); } - /** Read constant pool entries */ private final void readConstantPool() throws IOException { try { cpool = new ConstantPool(file); diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java index 9280083a8..0a9340649 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java @@ -103,6 +103,10 @@ public interface ClassVisitor { public void visitConstantString(ConstantString obj); + public void visitConstantModule(ConstantModule obj); + + public void visitConstantPackage(ConstantPackage obj); + public void visitConstantUtf8(ConstantUtf8 obj); public void visitConstantValue(ConstantValue obj); @@ -162,4 +166,9 @@ public interface ClassVisitor { public void visitLocalVariableTypeTable(LocalVariableTypeTable obj); public void visitMethodParameters(MethodParameters methodParameters); + + // J9: + public void visitModule(Module module); + public void visitModulePackages(ModulePackages modulePackage); + public void visitModuleMainClass(ModuleMainClass moduleMainClass); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java index 2110bdc08..6fbbff3a3 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java @@ -135,6 +135,8 @@ public abstract class Constant implements Cloneable, Node { return new ConstantMethodType(dis); case Constants.CONSTANT_InvokeDynamic: return new ConstantInvokeDynamic(dis); + case Constants.CONSTANT_Module: return new ConstantModule(dis); + case Constants.CONSTANT_Package: return new ConstantPackage(dis); default: throw new ClassFormatException("Invalid byte tag in constant pool: " + b); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantModule.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantModule.java new file mode 100644 index 000000000..efe4d3a1b --- /dev/null +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantModule.java @@ -0,0 +1,111 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2017 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Represents a module. + * + * See http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.4.11 + * + * @author Andy Clement + */ +public final class ConstantModule extends Constant { + + private int nameIndex; + + ConstantModule(DataInputStream file) throws IOException { + this(file.readUnsignedShort()); + } + + public ConstantModule(int nameIndex) { + super(Constants.CONSTANT_Module); + this.nameIndex = nameIndex; + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantModule(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(nameIndex); + } + + @Override + public Integer getValue() { + return nameIndex; + } + + public final int getNameIndex() { + return nameIndex; + } + + @Override + public final String toString() { + return super.toString() + "(name_index = " + nameIndex + ")"; + } + + public String getModuleName(ConstantPool cpool) { + Constant c = cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); + return ((ConstantUtf8) c).getValue(); + } +} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPackage.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPackage.java new file mode 100644 index 000000000..70f22c749 --- /dev/null +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPackage.java @@ -0,0 +1,111 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2017 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Represents a module. + * + * See http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.4.12 + * + * @author Andy Clement + */ +public final class ConstantPackage extends Constant { + + private int nameIndex; + + ConstantPackage(DataInputStream file) throws IOException { + this(file.readUnsignedShort()); + } + + public ConstantPackage(int nameIndex) { + super(Constants.CONSTANT_Package); + this.nameIndex = nameIndex; + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantPackage(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(nameIndex); + } + + @Override + public Integer getValue() { + return nameIndex; + } + + public final int getNameIndex() { + return nameIndex; + } + + @Override + public final String toString() { + return super.toString() + "(name_index = " + nameIndex + ")"; + } + + public String getPackageName(ConstantPool cpool) { + Constant c = cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); + return ((ConstantUtf8) c).getValue(); + } +} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java index 4e160ba3d..be5b84564 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java @@ -275,6 +275,20 @@ public class ConstantPool implements Node { assert c.tag == Constants.CONSTANT_Utf8; return (ConstantUtf8) c; } + + public ConstantModule getConstantModule(int index) { + Constant c = getConstant(index); + assert c != null; + assert c.tag == Constants.CONSTANT_Module; + return (ConstantModule)c; + } + + public ConstantPackage getConstantPackage(int index) { + Constant c = getConstant(index); + assert c != null; + assert c.tag == Constants.CONSTANT_Package; + return (ConstantPackage)c; + } public String getConstantString_CONSTANTClass(int index) { ConstantClass c = (ConstantClass) getConstant(index, Constants.CONSTANT_Class); @@ -770,4 +784,12 @@ public class ConstantPool implements Node { System.arraycopy(pool, 0, cs, 0, poolSize); return new ConstantPool(cs); } + + public String getModuleName(int moduleIndex) { + return getConstantModule(moduleIndex).getModuleName(this); + } + + public String getPackageName(int packageIndex) { + return getConstantPackage(packageIndex).getPackageName(this); + } }
\ No newline at end of file diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Module.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Module.java new file mode 100644 index 000000000..5eef18cde --- /dev/null +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Module.java @@ -0,0 +1,664 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2016-17 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * This class is derived from <em>Attribute</em> and represents the module + * information captured in a class file. + * http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html + * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.25 + * + * @author Andy Clement + */ +public final class Module extends Attribute { + + private static final String[] NO_MODULE_NAMES = {}; + + private int moduleNameIndex; // u2 module_name_index + private int moduleFlags; // u2 module_flags + private int moduleVersionIndex; // u2 module_version_index + private Require[] requires; + private Export[] exports; + private Open[] opens; + private Uses[] uses; + private Provide[] provides; + + private byte[] moduleInfo; + private int ptr; + private boolean unpacked = false; + + public Module(Module module) { + super(module.getTag(), module.getNameIndex(), module.getLength(), module.getConstantPool()); + moduleInfo = module.getBytes(); + } + + public Module(int nameIndex, int length, byte[] data, ConstantPool cp) { + super(Constants.ATTR_MODULE, nameIndex, length, cp); + } + + Module(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { + this(nameIndex, length, (byte[])null, cp); + moduleInfo = new byte[length]; + stream.read(moduleInfo); + unpacked = false; + } + + public class Require { + + private final int moduleIndex; + private final int flags; + private final int versionIndex; + + public Require(int moduleIndex, int flags, int versionIndex) { + this.moduleIndex = moduleIndex; + this.flags = flags; + this.versionIndex = versionIndex; + } + + public String getModuleName() { + return cpool.getModuleName(moduleIndex); + } + + public int getFlags() { + return flags; + } + + public int getVersionIndex() { + return versionIndex; + } + + public String getVersionString() { + if (versionIndex == 0) { + return null; + } else { + return cpool.getConstantUtf8(versionIndex).getValue(); + } + } + + public String getFlagsAsString() { + StringBuilder s = new StringBuilder(); + if ((flags & Constants.MODULE_ACC_TRANSITIVE)!=0) { + s.append(" transitive"); + } + if ((flags & Constants.MODULE_ACC_STATIC_PHASE)!=0) { + s.append(" static"); + } + if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) { + s.append(" synthetic"); + } + if ((flags & Constants.MODULE_ACC_MANDATED)!=0) { + s.append(" mandated"); + } + return s.toString(); + } + + public String toString() { + return "requires"+getFlagsAsString()+" "+getModuleName()+(versionIndex==0?"":" "+getVersionString()); + } + } + + + public class Export { + + private final int packageIndex; + private final int flags; + private final int[] toModuleIndices; + + public Export(int packageIndex, int flags, int[] toModuleIndices) { + this.packageIndex = packageIndex; + this.flags = flags; + this.toModuleIndices = toModuleIndices; + } + + public int getPackageIndex() { + return packageIndex; + } + + public int getFlags() { + return flags; + } + + public int[] getToModuleIndices() { + return toModuleIndices; + } + + public String getPackage() { + return cpool.getPackageName(packageIndex); + } + + public String getFlagsAsString() { + StringBuilder s = new StringBuilder(); + if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) { + s.append(" synthetic"); + } + if ((flags & Constants.MODULE_ACC_MANDATED)!=0) { + s.append(" synthetic"); + } + return s.toString(); + } + + public String[] getToModuleNames() { + if (toModuleIndices==null) { + return NO_MODULE_NAMES; + } + String[] toModuleNames = new String[toModuleIndices.length]; + for (int i=0;i<toModuleIndices.length;i++) { + toModuleNames[i] = cpool.getModuleName(toModuleIndices[i]); + } + return toModuleNames; + } + + public String toString() { + StringBuilder s =new StringBuilder(); + s.append("exports").append(getFlagsAsString()).append(" ").append(getPackage().replace('/', '.')); + String[] toModules = getToModuleNames(); + if (toModules.length!=0) { + s.append(" to "); + for (int i=0;i<toModules.length;i++) { + if (i>0) { + s.append(", "); + } + s.append(toModules[i]); + } + } + return s.toString().trim(); + } + } + + + public class Open { + + private final int packageIndex; + private final int flags; + private final int[] toModuleIndices; + + public Open(int packageIndex, int flags, int[] toModuleIndices) { + this.packageIndex = packageIndex; + this.flags = flags; + this.toModuleIndices = toModuleIndices; + } + + public int getPackageIndex() { + return packageIndex; + } + + public int getFlags() { + return flags; + } + + public int[] getToModuleIndices() { + return toModuleIndices; + } + + public String getPackage() { + return cpool.getPackageName(packageIndex); + } + + public String getFlagsAsString() { + StringBuilder s = new StringBuilder(); + if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) { + s.append(" synthetic"); + } + if ((flags & Constants.MODULE_ACC_MANDATED)!=0) { + s.append(" synthetic"); + } + return s.toString(); + } + + public String[] getToModuleNames() { + if (toModuleIndices==null) { + return NO_MODULE_NAMES; + } + String[] toModuleNames = new String[toModuleIndices.length]; + for (int i=0;i<toModuleIndices.length;i++) { + toModuleNames[i] = cpool.getModuleName(toModuleIndices[i]); + } + return toModuleNames; + } + + public String toString() { + StringBuilder s =new StringBuilder(); + s.append("opens").append(getFlagsAsString()).append(" ").append(getPackage().replace('/', '.')); + String[] toModules = getToModuleNames(); + if (toModules.length!=0) { + s.append(" to "); + for (int i=0;i<toModules.length;i++) { + if (i>0) { + s.append(", "); + } + s.append(toModules[i]); + } + } + return s.toString().trim(); + } + } + + public class Provide { + private final int providedTypeIndex; + private final int[] withTypeIndices; + + public Provide(int providedTypeIndex, int[] withTypeIndices) { + this.providedTypeIndex = providedTypeIndex; + this.withTypeIndices = withTypeIndices; + } + + public String getProvidedType() { + return cpool.getConstantString_CONSTANTClass(providedTypeIndex); + } + + public int getProvidedTypeIndex() { + return providedTypeIndex; + } + + public String[] getWithTypeStrings() { + String[] result = new String[withTypeIndices.length]; + for (int i=0;i<withTypeIndices.length;i++) { + result[i] = cpool.getConstantString_CONSTANTClass(withTypeIndices[i]); + } + return result; + } + + public int[] getWithTypeIndices() { + return withTypeIndices; + } + + public String toString() { + StringBuilder s =new StringBuilder(); + s.append("provides ").append(getProvidedType().replace('/', '.')); + s.append(" with "); + String[] withtypes = getWithTypeStrings(); + for (int i=0;i< withtypes.length;i++) { + if (i>0) s.append(","); + s.append(withtypes[i].replace('/','.')); + } + return s.toString(); + } + } + + public class Uses { + private final int typeNameIndex; + + public Uses(int typeNameIndex) { + this.typeNameIndex = typeNameIndex; + } + + public String getTypeName() { + return cpool.getConstantString_CONSTANTClass(typeNameIndex); + } + + public int getTypeNameIndex() { + return typeNameIndex; + } + + public String toString() { + StringBuilder s =new StringBuilder(); + s.append("uses ").append(getTypeName().replace('/', '.')); + return s.toString().trim(); + } + } + + private final int readInt() { + return ((moduleInfo[ptr++] & 0xFF) << 24) + ((moduleInfo[ptr++] & 0xFF) << 16) + + ((moduleInfo[ptr++] & 0xFF) << 8) + (moduleInfo[ptr++] & 0xFF); + } + + private final int readUnsignedShort() { + return ((moduleInfo[ptr++] & 0xff) << 8) + (moduleInfo[ptr++] & 0xff); + } + + private final int readUnsignedShort(int offset) { + return ((moduleInfo[offset++] & 0xff) << 8) + (moduleInfo[offset] & 0xff); + } + + // Format: http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.25 + private void ensureUnpacked() { + if (!unpacked) { + ptr = 0; + moduleNameIndex = readUnsignedShort(); + moduleFlags = readUnsignedShort(); + moduleVersionIndex = readUnsignedShort(); + + int count = readUnsignedShort(); + requires = new Require[count]; + for (int i = 0; i < count; i++) { + requires[i] = new Require(readUnsignedShort(), readUnsignedShort(), readUnsignedShort()); + } + + count = readUnsignedShort(); + exports = new Export[count]; + for (int i = 0; i < count; i++) { + int index = readUnsignedShort(); + int flags = readUnsignedShort(); + int toCount = readUnsignedShort(); + int[] to = new int[toCount]; + for (int j = 0; j < toCount; j++) { + to[j] = readUnsignedShort(); + } + exports[i] = new Export(index, flags, to); + } + + count = readUnsignedShort(); + opens = new Open[count]; + for (int i = 0; i < count; i++) { + int index = readUnsignedShort(); + int flags = readUnsignedShort(); + int toCount = readUnsignedShort(); + int[] to = new int[toCount]; + for (int j = 0; j < toCount; j++) { + to[j] = readUnsignedShort(); + } + opens[i] = new Open(index, flags, to); + } + count = readUnsignedShort(); + uses = new Uses[count]; + for (int i = 0; i < count; i++) { + uses[i] = new Uses(readUnsignedShort()); + } + count = readUnsignedShort(); + provides = new Provide[count]; + for (int i = 0; i < count; i++) { + int index = readUnsignedShort(); + int toCount = readUnsignedShort(); + int[] to = new int[toCount]; + for (int j = 0; j < toCount; j++) { + to[j] = readUnsignedShort(); + } + provides[i] = new Provide(index, to); + } + unpacked = true; + } + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + if (!unpacked) { + file.write(moduleInfo); + } else { + + file.writeShort(moduleNameIndex); + file.writeShort(moduleFlags); + file.writeShort(moduleVersionIndex); + + file.writeShort(requires.length); + for (int i = 0; i < requires.length; i++) { + file.writeShort(requires[i].moduleIndex); + file.writeShort(requires[i].flags); + file.writeShort(requires[i].versionIndex); + } + file.writeShort(exports.length); + for (Export export : exports) { + file.writeShort(export.packageIndex); + int[] toIndices = export.toModuleIndices; + file.writeShort(toIndices.length); + for (int index : toIndices) { + file.writeShort(index); + } + } + file.writeShort(opens.length); + for (Open open : opens) { + file.writeShort(open.packageIndex); + int[] toIndices = open.toModuleIndices; + file.writeShort(toIndices.length); + for (int index : toIndices) { + file.writeShort(index); + } + } + file.writeShort(uses.length); + for (Uses use : uses) { + file.writeShort(use.getTypeNameIndex()); + } + file.writeShort(provides.length); + for (Provide provide : provides) { + file.writeShort(provide.providedTypeIndex); + int[] toIndices = provide.withTypeIndices; + file.writeShort(toIndices.length); + for (int index : toIndices) { + file.writeShort(index); + } + } + } + } + + public String toStringRequires() { + StringBuilder s = new StringBuilder(); + s.append('#').append(requires.length); + if (requires.length > 0) { + for (Require require : requires) { + s.append(' '); + s.append(require.moduleIndex).append(':').append(require.flags); + } + } + return s.toString(); + } + + public String toStringExports() { + StringBuilder s = new StringBuilder(); + s.append('#').append(exports.length); + if (exports.length > 0) { + for (Export export : exports) { + s.append(' '); + s.append(export.packageIndex).append(":["); + int[] toIndices = export.toModuleIndices; + for (int i = 0; i < toIndices.length; i++) { + if (i > 0) + s.append(','); + s.append(toIndices[i]); + } + s.append("]"); + } + } + return s.toString(); + } + + public String toStringOpens() { + StringBuilder s = new StringBuilder(); + s.append('#').append(opens.length); + if (opens.length > 0) { + for (Open open : opens) { + s.append(' '); + s.append(open.packageIndex).append(":["); + int[] toIndices = open.toModuleIndices; + for (int i = 0; i < toIndices.length; i++) { + if (i > 0) + s.append(','); + s.append(toIndices[i]); + } + s.append("]"); + } + } + return s.toString(); + } + + public String toStringUses() { + StringBuilder s = new StringBuilder(); + s.append('#').append(uses.length); + if (uses.length > 0) { + for (Uses use : uses) { + s.append(' '); + s.append(use.getTypeName()); + } + } + return s.toString(); + } + + public String toStringProvides() { + StringBuilder s = new StringBuilder(); + s.append('#').append(provides.length); + if (provides.length > 0) { + for (Provide provide : provides) { + s.append(' '); + s.append(provide.providedTypeIndex).append(":["); + int[] indices = provide.withTypeIndices; + for (int i = 0; i < indices.length; i++) { + if (i > 0) + s.append(','); + s.append(indices[i]); + } + s.append("]"); + } + } + return s.toString(); + } + + @Override + public final String toString() { + StringBuilder s = new StringBuilder(); + ensureUnpacked(); + s.append("Module("); + if (requires.length != 0) { + s.append("requires="); + s.append(toStringRequires()); + s.append(" "); + } + if (exports.length != 0) { + s.append("exports="); + s.append(toStringExports()); + s.append(" "); + } + if (opens.length != 0) { + s.append("opens="); + s.append(toStringOpens()); + s.append(" "); + } + if (uses.length != 0) { + s.append("uses="); + s.append(toStringUses()); + s.append(" "); + } + if (provides.length != 0) { + s.append("provides="); + s.append(toStringProvides()); + s.append(" "); + } + return s.toString().trim()+")"; + } + + /** + * @return deep copy of this attribute // + */ +// @Override +// public Attribute copy(ConstantPool constant_pool) { +// return (Module) clone(); +// } + + @Override + public void accept(ClassVisitor v) { + v.visitModule(this); + } + + public Require[] getRequires() { + ensureUnpacked(); + return requires; + } + + public String[] getRequiredModuleNames() { + ensureUnpacked(); + String[] results = new String[requires.length]; + for (int i=0;i<requires.length;i++) { + results[i] = cpool.getModuleName(requires[i].moduleIndex); + } + return results; + } + + public byte[] getBytes() { + return moduleInfo; + } + + public Export[] getExports() { + ensureUnpacked(); + return exports; + } + + public Open[] getOpens() { + ensureUnpacked(); + return opens; + } + + public Uses[] getUses() { + ensureUnpacked(); + return uses; + } + + public Provide[] getProvides() { + ensureUnpacked(); + return provides; + } + + public String getModuleName() { + return ((ConstantModule)cpool.getConstant(moduleNameIndex)).getModuleName(cpool); + } + + public int getModuleFlags() { + // 0x0020 (ACC_OPEN) - Indicates that this module is open. + // 0x1000 (ACC_SYNTHETIC) - Indicates that this module was not explicitly or implicitly declared. + // 0x8000 (ACC_MANDATED) - Indicates that this module was implicitly declared + return moduleFlags; + } + + /** @return the module version or null if no version information specified */ + public String getModuleVersion() { + if (moduleVersionIndex == 0) { + return null; + } else { + return cpool.getConstantUtf8(moduleVersionIndex).getValue(); + } + } +} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModuleMainClass.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModuleMainClass.java new file mode 100644 index 000000000..3fa500a8e --- /dev/null +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModuleMainClass.java @@ -0,0 +1,106 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2017 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Indicates the main class of a module. + * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.26 + * + * @author Andy Clement + */ +public final class ModuleMainClass extends Attribute { + + private int mainClassIndex; + + public ModuleMainClass(ModuleMainClass c) { + this(c.getNameIndex(), c.getLength(), c.getMainClassIndex(), c.getConstantPool()); + } + + public ModuleMainClass(int nameIndex, int length, int mainClassIndex, ConstantPool cp) { + super(Constants.ATTR_MODULE_MAIN_CLASS, nameIndex, length, cp); + this.mainClassIndex = mainClassIndex; + } + + ModuleMainClass(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { + this(nameIndex, length, 0, cp); + this.mainClassIndex = stream.readUnsignedShort(); + } + + @Override + public void accept(ClassVisitor v) { + v.visitModuleMainClass(this); + } + + @Override + public final void dump(DataOutputStream stream) throws IOException { + super.dump(stream); + stream.writeShort(mainClassIndex); + } + + public final int getMainClassIndex() { + return mainClassIndex; + } + + @Override + public final String toString() { + return cpool.getConstantString_CONSTANTClass(mainClassIndex); + } + +} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModulePackages.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModulePackages.java new file mode 100644 index 000000000..37da4bc47 --- /dev/null +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModulePackages.java @@ -0,0 +1,126 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2017 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Indicates all the packages of a module that are exported or opened by the module attribute. + * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.26 + * + * @author Andy Clement + */ +public final class ModulePackages extends Attribute { + + private static int[] NO_PACKAGES = new int[0]; + private int[] packageIndices; + + public ModulePackages(ModulePackages c) { + this(c.getNameIndex(), c.getLength(), c.getPackageIndices(), c.getConstantPool()); + } + + public ModulePackages(int nameIndex, int length, int[] packageIndices, ConstantPool cp) { + super(Constants.ATTR_MODULE_PACKAGES, nameIndex, length, cp); + setPackageIndices(packageIndices); + } + + ModulePackages(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { + this(nameIndex, length, (int[]) null, cp); + int packageIndicesCount = stream.readUnsignedShort(); + packageIndices = new int[packageIndicesCount]; + for (int i = 0; i < packageIndicesCount; i++) { + packageIndices[i] = stream.readUnsignedShort(); + } + } + + @Override + public void accept(ClassVisitor v) { + v.visitModulePackages(this); + } + + @Override + public final void dump(DataOutputStream stream) throws IOException { + super.dump(stream); + stream.writeShort(packageIndices.length); + for (int i = 0; i < packageIndices.length; i++) { + stream.writeShort(packageIndices[i]); + } + } + + public final int[] getPackageIndices() { + return packageIndices; + } + + public final void setPackageIndices(int[] packageIndices) { + if (packageIndices == null) { + this.packageIndices = NO_PACKAGES; + } else { + this.packageIndices = packageIndices; + } + } + + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < packageIndices.length; i++) { + buf.append(cpool.getPackageName(packageIndices[i]) + "\n"); + } + return buf.toString(); + } + +} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java index 4ff25bd55..c5db1904a 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java @@ -82,6 +82,10 @@ public class InstructionFactory implements InstructionConstants { this(null, cp); } + public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, Type[] arg_types, short kind) { + return createInvoke(class_name, name, ret_type, arg_types, kind, false); + } + /** * Create an invoke instruction. * @@ -90,14 +94,15 @@ public class InstructionFactory implements InstructionConstants { * @param ret_type return type of method * @param arg_types argument types of method * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, or INVOKESPECIAL + * @param isInterface for an invokestatic on an interface allows us to tell this method the target is an interface * @see Constants */ - public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, Type[] arg_types, short kind) { + public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, Type[] arg_types, short kind, boolean isInterface) { String signature = Utility.toMethodSignature(ret_type, arg_types); int index; - if (kind == Constants.INVOKEINTERFACE) { + if (kind == Constants.INVOKEINTERFACE || isInterface) { index = cp.addInterfaceMethodref(class_name, name, signature); } else if (kind == Constants.INVOKEDYNAMIC){ throw new IllegalStateException("NYI"); diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderRepository.java b/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderRepository.java index eb33d8b4e..e3c59556b 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderRepository.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/util/ClassLoaderRepository.java @@ -88,15 +88,13 @@ public class ClassLoaderRepository implements Repository { private ClassLoaderReference loaderRef; // Choice of cache... - private WeakHashMap /* <URL,SoftRef(JavaClass)> */<URL, SoftReference<JavaClass>> localCache = new WeakHashMap<URL, SoftReference<JavaClass>>(); - private static SoftHashMap /* <URL,JavaClass> */sharedCache = new SoftHashMap(Collections - .synchronizedMap(new HashMap<Object, SpecialValue>())); + private WeakHashMap<URL, SoftReference<JavaClass>> localCache = new WeakHashMap<URL, SoftReference<JavaClass>>(); + private static SoftHashMap /* <URL,JavaClass> */sharedCache = new SoftHashMap(Collections.synchronizedMap(new HashMap<Object, SpecialValue>())); // For fast translation of the classname *intentionally not static* private SoftHashMap /* <String,URL> */nameMap = new SoftHashMap(new HashMap(), false); - public static boolean useSharedCache = System.getProperty("org.aspectj.apache.bcel.useSharedCache", "true").equalsIgnoreCase( - "true"); + public static boolean useSharedCache = System.getProperty("org.aspectj.apache.bcel.useSharedCache", "true").equalsIgnoreCase("true"); private static int cacheHitsShared = 0; private static int missSharedEvicted = 0; // Misses in shared cache access due to reference GC diff --git a/bcel-builder/src/org/aspectj/apache/bcel/util/ClassPath.java b/bcel-builder/src/org/aspectj/apache/bcel/util/ClassPath.java index d346256cb..0f5df2d4d 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/util/ClassPath.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/util/ClassPath.java @@ -1,9 +1,7 @@ -package org.aspectj.apache.bcel.util; - /* ==================================================================== * The Apache Software License, Version 1.1 * - * Copyright (c) 2001 The Apache Software Foundation. All rights + * Copyright (c) 2001, 2017 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,326 +51,501 @@ package org.aspectj.apache.bcel.util; * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ +package org.aspectj.apache.bcel.util; import java.util.*; import java.util.zip.*; + import java.io.*; +import java.net.URI; +import java.nio.file.FileVisitResult; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.DirectoryStream; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; /** * Responsible for loading (class) files from the CLASSPATH. Inspired by * sun.tools.ClassPath. * - * @version $Id: ClassPath.java,v 1.5 2009/09/09 19:56:20 aclement Exp $ - * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> + * @author M. Dahm + * @author Mario Ivankovits + * @author Andy Clement */ public class ClassPath implements Serializable { - private static ClassPath SYSTEM_CLASS_PATH = null; - - private PathEntry[] paths; - private String class_path; - - public static ClassPath getSystemClassPath() { - if (SYSTEM_CLASS_PATH == null) { - SYSTEM_CLASS_PATH = new ClassPath(); - } - return SYSTEM_CLASS_PATH; - } - /** - * Search for classes in given path. - */ - public ClassPath(String class_path) { - this.class_path = class_path; - - ArrayList<PathEntry> vec = new ArrayList<PathEntry>(); - - for(StringTokenizer tok=new StringTokenizer(class_path, - System.getProperty("path.separator")); - tok.hasMoreTokens();) - { - String path = tok.nextToken(); - - if(!path.equals("")) { - File file = new File(path); - - try { - if(file.exists()) { - if(file.isDirectory()) - vec.add(new Dir(path)); - else - vec.add(new Zip(new ZipFile(file))); - } - } catch(IOException e) { - System.err.println("CLASSPATH component " + file + ": " + e); + private static final String JRT_FS = "jrt-fs.jar"; + + private static ClassPath SYSTEM_CLASS_PATH = null; + + private PathEntry[] paths; + private String class_path; + + public static ClassPath getSystemClassPath() { + if (SYSTEM_CLASS_PATH == null) { + SYSTEM_CLASS_PATH = new ClassPath(); + } + return SYSTEM_CLASS_PATH; } - } - } - - paths = new PathEntry[vec.size()]; - vec.toArray(paths); - } - - /** - * Search for classes in CLASSPATH. - * @deprecated Use SYSTEM_CLASS_PATH constant - */ - public ClassPath() { - this(getClassPath()); - } - - /** @return used class path string - */ - public String toString() { - return class_path; - } - - public int hashCode() { - return class_path.hashCode(); - } - - public boolean equals(Object o) { - if(o instanceof ClassPath) { - return class_path.equals(((ClassPath)o).class_path); - } - - return false; - } - - private static final void getPathComponents(String path, ArrayList<String> list) { - if(path != null) { - StringTokenizer tok = new StringTokenizer(path, File.pathSeparator); - - while(tok.hasMoreTokens()) { - String name = tok.nextToken(); - File file = new File(name); - - if(file.exists()) - list.add(name); - } - } - } - - /** Checks for class path components in the following properties: - * "java.class.path", "sun.boot.class.path", "java.ext.dirs" - * - * @return class path as used by default by BCEL - */ - public static final String getClassPath() { - String class_path = System.getProperty("java.class.path"); - String boot_path = System.getProperty("sun.boot.class.path"); - String ext_path = System.getProperty("java.ext.dirs"); - - ArrayList<String> list = new ArrayList<String>(); - - getPathComponents(class_path, list); - getPathComponents(boot_path, list); - - ArrayList<String> dirs = new ArrayList<String>(); - getPathComponents(ext_path, dirs); - - for(Iterator<String> e = dirs.iterator(); e.hasNext(); ) { - File ext_dir = new File(e.next()); - String[] extensions = ext_dir.list(new FilenameFilter() { - public boolean accept(File dir, String name) { - name = name.toLowerCase(); - return name.endsWith(".zip") || name.endsWith(".jar"); + + /** + * Search for classes in given path. + */ + public ClassPath(String class_path) { + this.class_path = class_path; + + ArrayList<PathEntry> vec = new ArrayList<PathEntry>(); + + for (StringTokenizer tok = new StringTokenizer(class_path, System.getProperty("path.separator")); tok + .hasMoreTokens();) { + String path = tok.nextToken(); + + if (!path.equals("")) { + File file = new File(path); + + try { + if (file.exists()) { + if (file.isDirectory()) { + vec.add(new Dir(path)); + } else if (file.getName().endsWith("jrt-fs.jar")) { // TODO a bit crude... + vec.add(new JImage()); + } else { + vec.add(new Zip(new ZipFile(file))); + } + } + } catch (IOException e) { + System.err.println("CLASSPATH component " + file + ": " + e); + } + } + } + + paths = new PathEntry[vec.size()]; + vec.toArray(paths); } - }); - - if(extensions != null) - for(int i=0; i < extensions.length; i++) - list.add(ext_path + File.separatorChar + extensions[i]); - } - - StringBuffer buf = new StringBuffer(); - - for(Iterator<String> e = list.iterator(); e.hasNext(); ) { - buf.append(e.next()); - - if(e.hasNext()) - buf.append(File.pathSeparatorChar); - } - - return buf.toString().intern(); - } - - /** - * @param name fully qualified class name, e.g. java.lang.String - * @return input stream for class - */ - public InputStream getInputStream(String name) throws IOException { - return getInputStream(name, ".class"); - } - - /** - * Return stream for class or resource on CLASSPATH. - * - * @param name fully qualified file name, e.g. java/lang/String - * @param suffix file name ends with suff, e.g. .java - * @return input stream for file on class path - */ - public InputStream getInputStream(String name, String suffix) throws IOException { - InputStream is = null; - - try { - is = getClass().getClassLoader().getResourceAsStream(name + suffix); - } catch(Exception e) { } - - if(is != null) - return is; - - return getClassFile(name, suffix).getInputStream(); - } - - /** - * @param name fully qualified file name, e.g. java/lang/String - * @param suffix file name ends with suff, e.g. .java - * @return class file for the java class - */ - public ClassFile getClassFile(String name, String suffix) throws IOException { - for(int i=0; i < paths.length; i++) { - ClassFile cf; - - if((cf = paths[i].getClassFile(name, suffix)) != null) - return cf; - } - - throw new IOException("Couldn't find: " + name + suffix); - } - - /** - * @param name fully qualified class name, e.g. java.lang.String - * @return input stream for class - */ - public ClassFile getClassFile(String name) throws IOException { - return getClassFile(name, ".class"); - } - - /** - * @param name fully qualified file name, e.g. java/lang/String - * @param suffix file name ends with suffix, e.g. .java - * @return byte array for file on class path - */ - public byte[] getBytes(String name, String suffix) throws IOException { - InputStream is = getInputStream(name, suffix); - - if(is == null) - throw new IOException("Couldn't find: " + name + suffix); - - DataInputStream dis = new DataInputStream(is); - byte[] bytes = new byte[is.available()]; - dis.readFully(bytes); - dis.close(); is.close(); - - return bytes; - } - - /** - * @return byte array for class - */ - public byte[] getBytes(String name) throws IOException { - return getBytes(name, ".class"); - } - - /** - * @param name name of file to search for, e.g. java/lang/String.java - * @return full (canonical) path for file - */ - public String getPath(String name) throws IOException { - int index = name.lastIndexOf('.'); - String suffix = ""; - - if(index > 0) { - suffix = name.substring(index); - name = name.substring(0, index); - } - - return getPath(name, suffix); - } - - /** - * @param name name of file to search for, e.g. java/lang/String - * @param suffix file name suffix, e.g. .java - * @return full (canonical) path for file, if it exists - */ - public String getPath(String name, String suffix) throws IOException { - return getClassFile(name, suffix).getPath(); - } - - private static abstract class PathEntry implements Serializable { - abstract ClassFile getClassFile(String name, String suffix) throws IOException; - } - - /** Contains information about file/ZIP entry of the Java class. - */ - public interface ClassFile { - /** @return input stream for class file. - */ - public abstract InputStream getInputStream() throws IOException; - - /** @return canonical path to class file. - */ - public abstract String getPath(); - - /** @return base path of found class, i.e. class is contained relative - * to that path, which may either denote a directory, or zip file - */ - public abstract String getBase(); - - /** @return modification time of class file. - */ - public abstract long getTime(); - - /** @return size of class file. - */ - public abstract long getSize(); - } - - private static class Dir extends PathEntry { - private String dir; - - Dir(String d) { dir = d; } - - ClassFile getClassFile(String name, String suffix) throws IOException { - final File file = new File(dir + File.separatorChar + - name.replace('.', File.separatorChar) + suffix); - - return file.exists()? new ClassFile() { - public InputStream getInputStream() throws IOException { return new FileInputStream(file); } - - public String getPath() { try { - return file.getCanonicalPath(); - } catch(IOException e) { return null; } + /** + * Search for classes in CLASSPATH. + * + * @deprecated Use SYSTEM_CLASS_PATH constant + */ + public ClassPath() { + this(getClassPath()); } - public long getTime() { return file.lastModified(); } - public long getSize() { return file.length(); } - public String getBase() { return dir; } - } : null; - } + /** + * @return used class path string + */ + public String toString() { + return class_path; + } - public String toString() { return dir; } - } + public int hashCode() { + return class_path.hashCode(); + } - private static class Zip extends PathEntry { - private ZipFile zip; + public boolean equals(Object o) { + if (o instanceof ClassPath) { + return class_path.equals(((ClassPath) o).class_path); + } - Zip(ZipFile z) { zip = z; } + return false; + } - ClassFile getClassFile(String name, String suffix) throws IOException { - final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix); + private static final void getPathComponents(String path, ArrayList<String> list) { + if (path != null) { + StringTokenizer tok = new StringTokenizer(path, File.pathSeparator); - return (entry != null)? new ClassFile() { - public InputStream getInputStream() throws IOException { return zip.getInputStream(entry); } - public String getPath() { return entry.toString(); } - public long getTime() { return entry.getTime(); } - public long getSize() { return entry.getSize(); } - public String getBase() { - return zip.getName(); + while (tok.hasMoreTokens()) { + String name = tok.nextToken(); + File file = new File(name); + + if (file.exists()) + list.add(name); + } + } } - } : null; - } - } -} + /** + * Checks for class path components in the following properties: + * "java.class.path", "sun.boot.class.path", "java.ext.dirs" + * + * @return class path as used by default by BCEL + */ + public static final String getClassPath() { + String class_path = System.getProperty("java.class.path"); + String boot_path = System.getProperty("sun.boot.class.path"); + String ext_path = System.getProperty("java.ext.dirs"); + String vm_version = System.getProperty("java.version"); + + ArrayList<String> list = new ArrayList<String>(); + + getPathComponents(class_path, list); + getPathComponents(boot_path, list); + + ArrayList<String> dirs = new ArrayList<String>(); + getPathComponents(ext_path, dirs); + + for (Iterator<String> e = dirs.iterator(); e.hasNext();) { + File ext_dir = new File(e.next()); + String[] extensions = ext_dir.list(new FilenameFilter() { + public boolean accept(File dir, String name) { + name = name.toLowerCase(); + return name.endsWith(".zip") || name.endsWith(".jar"); + } + }); + + if (extensions != null) + for (int i = 0; i < extensions.length; i++) + list.add(ext_path + File.separatorChar + extensions[i]); + } + + StringBuffer buf = new StringBuffer(); + + for (Iterator<String> e = list.iterator(); e.hasNext();) { + buf.append(e.next()); + + if (e.hasNext()) + buf.append(File.pathSeparatorChar); + } + + // On Java9 the sun.boot.class.path won't be set. System classes accessible through JRT filesystem + if (vm_version.startsWith("9")) { + buf.insert(0, File.pathSeparatorChar); + buf.insert(0, System.getProperty("java.home") + File.separator + "lib" + File.separator + JRT_FS); + } + + return buf.toString().intern(); + } + + /** + * @param name + * fully qualified class name, e.g. java.lang.String + * @return input stream for class + */ + public InputStream getInputStream(String name) throws IOException { + return getInputStream(name, ".class"); + } + + /** + * Return stream for class or resource on CLASSPATH. + * + * @param name + * fully qualified file name, e.g. java/lang/String + * @param suffix + * file name ends with suff, e.g. .java + * @return input stream for file on class path + */ + public InputStream getInputStream(String name, String suffix) throws IOException { + InputStream is = null; + + try { + is = getClass().getClassLoader().getResourceAsStream(name + suffix); + } catch (Exception e) { + } + + if (is != null) + return is; + + return getClassFile(name, suffix).getInputStream(); + } + + /** + * @param name + * fully qualified file name, e.g. java/lang/String + * @param suffix + * file name ends with suff, e.g. .java + * @return class file for the java class + */ + public ClassFile getClassFile(String name, String suffix) throws IOException { + for (int i = 0; i < paths.length; i++) { + ClassFile cf; + + if ((cf = paths[i].getClassFile(name, suffix)) != null) + return cf; + } + + throw new IOException("Couldn't find: " + name + suffix); + } + + /** + * @param name + * fully qualified class name, e.g. java.lang.String + * @return input stream for class + */ + public ClassFile getClassFile(String name) throws IOException { + return getClassFile(name, ".class"); + } + + /** + * @param name + * fully qualified file name, e.g. java/lang/String + * @param suffix + * file name ends with suffix, e.g. .java + * @return byte array for file on class path + */ + public byte[] getBytes(String name, String suffix) throws IOException { + InputStream is = getInputStream(name, suffix); + + if (is == null) + throw new IOException("Couldn't find: " + name + suffix); + + DataInputStream dis = new DataInputStream(is); + byte[] bytes = new byte[is.available()]; + dis.readFully(bytes); + dis.close(); + is.close(); + + return bytes; + } + + /** + * @return byte array for class + */ + public byte[] getBytes(String name) throws IOException { + return getBytes(name, ".class"); + } + + /** + * @param name + * name of file to search for, e.g. java/lang/String.java + * @return full (canonical) path for file + */ + public String getPath(String name) throws IOException { + int index = name.lastIndexOf('.'); + String suffix = ""; + + if (index > 0) { + suffix = name.substring(index); + name = name.substring(0, index); + } + + return getPath(name, suffix); + } + + /** + * @param name + * name of file to search for, e.g. java/lang/String + * @param suffix + * file name suffix, e.g. .java + * @return full (canonical) path for file, if it exists + */ + public String getPath(String name, String suffix) throws IOException { + return getClassFile(name, suffix).getPath(); + } + + private static abstract class PathEntry implements Serializable { + abstract ClassFile getClassFile(String name, String suffix) throws IOException; + } + + /** + * Contains information about file/ZIP entry of the Java class. + */ + public interface ClassFile { + /** + * @return input stream for class file. + */ + public abstract InputStream getInputStream() throws IOException; + + /** + * @return canonical path to class file. + */ + public abstract String getPath(); + + /** + * @return base path of found class, i.e. class is contained relative to + * that path, which may either denote a directory, or zip file + */ + public abstract String getBase(); + + /** + * @return modification time of class file. + */ + public abstract long getTime(); + + /** + * @return size of class file. + */ + public abstract long getSize(); + } + + private static class Dir extends PathEntry { + private String dir; + + Dir(String d) { + dir = d; + } + + ClassFile getClassFile(String name, String suffix) throws IOException { + final File file = new File(dir + File.separatorChar + name.replace('.', File.separatorChar) + suffix); + + return file.exists() ? new ClassFile() { + public InputStream getInputStream() throws IOException { + return new FileInputStream(file); + } + + public String getPath() { + try { + return file.getCanonicalPath(); + } catch (IOException e) { + return null; + } + + } + + public long getTime() { + return file.lastModified(); + } + + public long getSize() { + return file.length(); + } + public String getBase() { + return dir; + } + + } : null; + } + + public String toString() { + return dir; + } + } + + private static class JImage extends PathEntry { + + private static URI JRT_URI = URI.create("jrt:/"); //$NON-NLS-1$ + private static String MODULES_PATH = "modules"; //$NON-NLS-1$ + private static String JAVA_BASE_PATH = "java.base"; //$NON-NLS-1$ + + private java.nio.file.FileSystem fs; + private final Map<String, Path> fileMap; + + JImage() { + fs = FileSystems.getFileSystem(JRT_URI); + fileMap = buildFileMap(); + } + + private Map<String, Path> buildFileMap() { + final Map<String, Path> fileMap = new HashMap<>(); + final java.nio.file.PathMatcher matcher = fs.getPathMatcher("glob:*.class"); + Iterable<java.nio.file.Path> roots = fs.getRootDirectories(); + for (java.nio.file.Path path : roots) { + try { + Files.walkFileTree(path, new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (file.getNameCount() > 2 + && matcher.matches(file.getFileName())) { + Path classPath = file.subpath(2, file.getNameCount()); + fileMap.put(classPath.toString(), file); + } + + return FileVisitResult.CONTINUE; + } + }); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + return fileMap; + } + + private static class ByteBasedClassFile implements ClassFile { + + private byte[] bytes; + private ByteArrayInputStream bais; + private String path; + private String base; + private long time; + private long size; + + public ByteBasedClassFile(byte[] bytes, String path, String base, long time, long size) { + this.bytes = bytes; + this.path = path; + this.base = base; + this.time = time; + this.size = size; + } + + public InputStream getInputStream() throws IOException { + // TODO too costly to keep these in inflated form in memory? + this.bais = new ByteArrayInputStream(bytes); + return this.bais; + } + + public String getPath() { + return this.path; + } + + public String getBase() { + return this.base; + } + + public long getTime() { + return this.time; + } + + public long getSize() { + return this.size; + } + + } + + ClassFile getClassFile(String name, String suffix) throws IOException { + // Class files are in here under names like this: + // /modules/java.base/java/lang/Object.class (jdk9 b74) + // so within a modules top level qualifier and then the java.base module + String fileName = name.replace('.', '/') + suffix; + Path p = fileMap.get(fileName); + if (p == null) { + return null; + } + byte[] bs = Files.readAllBytes(p); + BasicFileAttributeView bfav = Files.getFileAttributeView(p, BasicFileAttributeView.class); + BasicFileAttributes bfas = bfav.readAttributes(); + long time = bfas.lastModifiedTime().toMillis(); + long size = bfas.size(); + ClassFile cf = new ByteBasedClassFile(bs, "jimage",fileName,time,size); + return cf; + } + } + + private static class Zip extends PathEntry { + private ZipFile zip; + + Zip(ZipFile z) { + zip = z; + } + + ClassFile getClassFile(String name, String suffix) throws IOException { + final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix); + + return (entry != null) ? new ClassFile() { + public InputStream getInputStream() throws IOException { + return zip.getInputStream(entry); + } + + public String getPath() { + return entry.toString(); + } + + public long getTime() { + return entry.getTime(); + } + + public long getSize() { + return entry.getSize(); + } + + public String getBase() { + return zip.getName(); + } + } : null; + } + } +} diff --git a/bcel-builder/testdata/modules/cpl.sh b/bcel-builder/testdata/modules/cpl.sh new file mode 100755 index 000000000..e2988772f --- /dev/null +++ b/bcel-builder/testdata/modules/cpl.sh @@ -0,0 +1,45 @@ +echo "Build simple empty module definition" +cd one +javac module-info.java + +# A pre java9 jar e.g. a-b-c-1.6.10.jar would become a module a.b.c (automated module) +echo "Build empty module definition with automated name a.b.c" +cd .. +cd two/a +javac module-info.java + +echo "Build helper module: b.c.d" +cd ../.. +cd two/b +javac module-info.java + +echo "Build helper module: c.d.e" +cd ../.. +cd two/c +javac module-info.java + +echo "Build code using require variants" +cd ../.. +cd two/d +javac module-info.java --module-path ../a:../b:../c + +echo "Exports variants" +cd ../.. +cd two/e +javac module-info.java C1.java C2.java C3.java -d . --module-path ../a:../b + +echo "Uses variants" +cd ../.. +cd two/f +javac module-info.java I1.java -d . + +echo "Provides variants" +cd ../.. +cd two/g +javac module-info.java I1.java I2.java C1.java C2.java -d . + +echo "Opens variants" +cd ../.. +cd two/h +javac module-info.java C1.java C2.java C3.java --module-path ../a:../b -d . +cd ../.. diff --git a/bcel-builder/testdata/modules/one/module-info.class b/bcel-builder/testdata/modules/one/module-info.class Binary files differnew file mode 100644 index 000000000..f852a1790 --- /dev/null +++ b/bcel-builder/testdata/modules/one/module-info.class diff --git a/bcel-builder/testdata/modules/one/module-info.java b/bcel-builder/testdata/modules/one/module-info.java new file mode 100644 index 000000000..d0913deeb --- /dev/null +++ b/bcel-builder/testdata/modules/one/module-info.java @@ -0,0 +1 @@ +module one {} diff --git a/bcel-builder/testdata/modules/two/a/module-info.class b/bcel-builder/testdata/modules/two/a/module-info.class Binary files differnew file mode 100644 index 000000000..1e64df029 --- /dev/null +++ b/bcel-builder/testdata/modules/two/a/module-info.class diff --git a/bcel-builder/testdata/modules/two/a/module-info.java b/bcel-builder/testdata/modules/two/a/module-info.java new file mode 100644 index 000000000..d4873ccd7 --- /dev/null +++ b/bcel-builder/testdata/modules/two/a/module-info.java @@ -0,0 +1 @@ +module a.b.c { } diff --git a/bcel-builder/testdata/modules/two/b/module-info.class b/bcel-builder/testdata/modules/two/b/module-info.class Binary files differnew file mode 100644 index 000000000..226c01309 --- /dev/null +++ b/bcel-builder/testdata/modules/two/b/module-info.class diff --git a/bcel-builder/testdata/modules/two/b/module-info.java b/bcel-builder/testdata/modules/two/b/module-info.java new file mode 100644 index 000000000..308ba05bb --- /dev/null +++ b/bcel-builder/testdata/modules/two/b/module-info.java @@ -0,0 +1,2 @@ +module b.c.d { +} diff --git a/bcel-builder/testdata/modules/two/c/module-info.class b/bcel-builder/testdata/modules/two/c/module-info.class Binary files differnew file mode 100644 index 000000000..6feb99fc1 --- /dev/null +++ b/bcel-builder/testdata/modules/two/c/module-info.class diff --git a/bcel-builder/testdata/modules/two/c/module-info.java b/bcel-builder/testdata/modules/two/c/module-info.java new file mode 100644 index 000000000..501d75a06 --- /dev/null +++ b/bcel-builder/testdata/modules/two/c/module-info.java @@ -0,0 +1,2 @@ +module c.d.e { +} diff --git a/bcel-builder/testdata/modules/two/d/module-info.class b/bcel-builder/testdata/modules/two/d/module-info.class Binary files differnew file mode 100644 index 000000000..f4f8de0c3 --- /dev/null +++ b/bcel-builder/testdata/modules/two/d/module-info.class diff --git a/bcel-builder/testdata/modules/two/d/module-info.java b/bcel-builder/testdata/modules/two/d/module-info.java new file mode 100644 index 000000000..3593cf9ec --- /dev/null +++ b/bcel-builder/testdata/modules/two/d/module-info.java @@ -0,0 +1,5 @@ +module d.e.f { + requires a.b.c; + requires static b.c.d; + requires transitive c.d.e; +} diff --git a/bcel-builder/testdata/modules/two/e/C1.java b/bcel-builder/testdata/modules/two/e/C1.java new file mode 100644 index 000000000..eb087840d --- /dev/null +++ b/bcel-builder/testdata/modules/two/e/C1.java @@ -0,0 +1,3 @@ +package com.foo1; + +public class C1 {} diff --git a/bcel-builder/testdata/modules/two/e/C2.java b/bcel-builder/testdata/modules/two/e/C2.java new file mode 100644 index 000000000..528b87e02 --- /dev/null +++ b/bcel-builder/testdata/modules/two/e/C2.java @@ -0,0 +1,3 @@ +package com.foo2; + +public class C2 {} diff --git a/bcel-builder/testdata/modules/two/e/C3.java b/bcel-builder/testdata/modules/two/e/C3.java new file mode 100644 index 000000000..205f75fac --- /dev/null +++ b/bcel-builder/testdata/modules/two/e/C3.java @@ -0,0 +1,3 @@ +package com.foo3; + +public class C3 {} diff --git a/bcel-builder/testdata/modules/two/e/com/foo1/C1.class b/bcel-builder/testdata/modules/two/e/com/foo1/C1.class Binary files differnew file mode 100644 index 000000000..6b5bb5fd4 --- /dev/null +++ b/bcel-builder/testdata/modules/two/e/com/foo1/C1.class diff --git a/bcel-builder/testdata/modules/two/e/com/foo2/C2.class b/bcel-builder/testdata/modules/two/e/com/foo2/C2.class Binary files differnew file mode 100644 index 000000000..d9eec8bcd --- /dev/null +++ b/bcel-builder/testdata/modules/two/e/com/foo2/C2.class diff --git a/bcel-builder/testdata/modules/two/e/com/foo3/C3.class b/bcel-builder/testdata/modules/two/e/com/foo3/C3.class Binary files differnew file mode 100644 index 000000000..d64d2fc98 --- /dev/null +++ b/bcel-builder/testdata/modules/two/e/com/foo3/C3.class diff --git a/bcel-builder/testdata/modules/two/e/module-info.class b/bcel-builder/testdata/modules/two/e/module-info.class Binary files differnew file mode 100644 index 000000000..da6cab8c2 --- /dev/null +++ b/bcel-builder/testdata/modules/two/e/module-info.class diff --git a/bcel-builder/testdata/modules/two/e/module-info.java b/bcel-builder/testdata/modules/two/e/module-info.java new file mode 100644 index 000000000..230097050 --- /dev/null +++ b/bcel-builder/testdata/modules/two/e/module-info.java @@ -0,0 +1,5 @@ +module e.f.g { + exports com.foo1; + exports com.foo2 to a.b.c; + exports com.foo3 to a.b.c, b.c.d; +} diff --git a/bcel-builder/testdata/modules/two/f/I1.java b/bcel-builder/testdata/modules/two/f/I1.java new file mode 100644 index 000000000..88029d83c --- /dev/null +++ b/bcel-builder/testdata/modules/two/f/I1.java @@ -0,0 +1,3 @@ +package com.foo1; + +public interface I1 {} diff --git a/bcel-builder/testdata/modules/two/f/com/foo1/I1.class b/bcel-builder/testdata/modules/two/f/com/foo1/I1.class Binary files differnew file mode 100644 index 000000000..da13682c4 --- /dev/null +++ b/bcel-builder/testdata/modules/two/f/com/foo1/I1.class diff --git a/bcel-builder/testdata/modules/two/f/module-info.class b/bcel-builder/testdata/modules/two/f/module-info.class Binary files differnew file mode 100644 index 000000000..f2730410d --- /dev/null +++ b/bcel-builder/testdata/modules/two/f/module-info.class diff --git a/bcel-builder/testdata/modules/two/f/module-info.java b/bcel-builder/testdata/modules/two/f/module-info.java new file mode 100644 index 000000000..78978622c --- /dev/null +++ b/bcel-builder/testdata/modules/two/f/module-info.java @@ -0,0 +1,3 @@ +module f.g.h { + uses com.foo1.I1; +} diff --git a/bcel-builder/testdata/modules/two/g/C1.java b/bcel-builder/testdata/modules/two/g/C1.java new file mode 100644 index 000000000..e25a57ec8 --- /dev/null +++ b/bcel-builder/testdata/modules/two/g/C1.java @@ -0,0 +1,3 @@ +package com.foo1; + +public class C1 implements I1 {} diff --git a/bcel-builder/testdata/modules/two/g/C2.java b/bcel-builder/testdata/modules/two/g/C2.java new file mode 100644 index 000000000..100c37b18 --- /dev/null +++ b/bcel-builder/testdata/modules/two/g/C2.java @@ -0,0 +1,3 @@ +package com.foo2; + +public class C2 implements I2 {} diff --git a/bcel-builder/testdata/modules/two/g/I1.java b/bcel-builder/testdata/modules/two/g/I1.java new file mode 100644 index 000000000..88029d83c --- /dev/null +++ b/bcel-builder/testdata/modules/two/g/I1.java @@ -0,0 +1,3 @@ +package com.foo1; + +public interface I1 {} diff --git a/bcel-builder/testdata/modules/two/g/I2.java b/bcel-builder/testdata/modules/two/g/I2.java new file mode 100644 index 000000000..bd52da822 --- /dev/null +++ b/bcel-builder/testdata/modules/two/g/I2.java @@ -0,0 +1,3 @@ +package com.foo2; + +public interface I2 {} diff --git a/bcel-builder/testdata/modules/two/g/com/foo1/C1.class b/bcel-builder/testdata/modules/two/g/com/foo1/C1.class Binary files differnew file mode 100644 index 000000000..dfc944836 --- /dev/null +++ b/bcel-builder/testdata/modules/two/g/com/foo1/C1.class diff --git a/bcel-builder/testdata/modules/two/g/com/foo1/I1.class b/bcel-builder/testdata/modules/two/g/com/foo1/I1.class Binary files differnew file mode 100644 index 000000000..da13682c4 --- /dev/null +++ b/bcel-builder/testdata/modules/two/g/com/foo1/I1.class diff --git a/bcel-builder/testdata/modules/two/g/com/foo2/C2.class b/bcel-builder/testdata/modules/two/g/com/foo2/C2.class Binary files differnew file mode 100644 index 000000000..aae7ea279 --- /dev/null +++ b/bcel-builder/testdata/modules/two/g/com/foo2/C2.class diff --git a/bcel-builder/testdata/modules/two/g/com/foo2/I2.class b/bcel-builder/testdata/modules/two/g/com/foo2/I2.class Binary files differnew file mode 100644 index 000000000..c31533fbf --- /dev/null +++ b/bcel-builder/testdata/modules/two/g/com/foo2/I2.class diff --git a/bcel-builder/testdata/modules/two/g/module-info.class b/bcel-builder/testdata/modules/two/g/module-info.class Binary files differnew file mode 100644 index 000000000..e92cb26b3 --- /dev/null +++ b/bcel-builder/testdata/modules/two/g/module-info.class diff --git a/bcel-builder/testdata/modules/two/g/module-info.java b/bcel-builder/testdata/modules/two/g/module-info.java new file mode 100644 index 000000000..ac20edce2 --- /dev/null +++ b/bcel-builder/testdata/modules/two/g/module-info.java @@ -0,0 +1,6 @@ +module g.h.i { + exports com.foo1; + exports com.foo2; + provides com.foo1.I1 with com.foo1.C1; + provides com.foo2.I2 with com.foo2.C2; +} diff --git a/bcel-builder/testdata/modules/two/h/C1.java b/bcel-builder/testdata/modules/two/h/C1.java new file mode 100644 index 000000000..eb087840d --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/C1.java @@ -0,0 +1,3 @@ +package com.foo1; + +public class C1 {} diff --git a/bcel-builder/testdata/modules/two/h/C2.java b/bcel-builder/testdata/modules/two/h/C2.java new file mode 100644 index 000000000..528b87e02 --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/C2.java @@ -0,0 +1,3 @@ +package com.foo2; + +public class C2 {} diff --git a/bcel-builder/testdata/modules/two/h/C3.java b/bcel-builder/testdata/modules/two/h/C3.java new file mode 100644 index 000000000..205f75fac --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/C3.java @@ -0,0 +1,3 @@ +package com.foo3; + +public class C3 {} diff --git a/bcel-builder/testdata/modules/two/h/com/foo1/C1.class b/bcel-builder/testdata/modules/two/h/com/foo1/C1.class Binary files differnew file mode 100644 index 000000000..6b5bb5fd4 --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/com/foo1/C1.class diff --git a/bcel-builder/testdata/modules/two/h/com/foo2/C2.class b/bcel-builder/testdata/modules/two/h/com/foo2/C2.class Binary files differnew file mode 100644 index 000000000..d9eec8bcd --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/com/foo2/C2.class diff --git a/bcel-builder/testdata/modules/two/h/com/foo3/C3.class b/bcel-builder/testdata/modules/two/h/com/foo3/C3.class Binary files differnew file mode 100644 index 000000000..d64d2fc98 --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/com/foo3/C3.class diff --git a/bcel-builder/testdata/modules/two/h/module-info.class b/bcel-builder/testdata/modules/two/h/module-info.class Binary files differnew file mode 100644 index 000000000..7f19a1fc8 --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/module-info.class diff --git a/bcel-builder/testdata/modules/two/h/module-info.java b/bcel-builder/testdata/modules/two/h/module-info.java new file mode 100644 index 000000000..253e8c47e --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/module-info.java @@ -0,0 +1,5 @@ +module e.f.g { + opens com.foo1; + opens com.foo2 to a.b.c; + opens com.foo3 to a.b.c, b.c.d; +} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AllTests.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AllTests.java index 2979c12e3..b12094ac2 100644 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AllTests.java +++ b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AllTests.java @@ -12,6 +12,8 @@ package org.aspectj.apache.bcel.classfile.tests; +import org.aspectj.apache.bcel.util.ClassPathTests; + import junit.framework.Test; import junit.framework.TestSuite; @@ -34,6 +36,7 @@ public class AllTests { suite.addTestSuite(AnnotationAccessFlagTest.class); suite.addTestSuite(ElementValueGenTest.class); suite.addTestSuite(FieldAnnotationsTest.class); + suite.addTestSuite(ClassPathTests.class); suite.addTestSuite(AnnotationGenTest.class); suite.addTestSuite(ParameterAnnotationsTest.class); suite.addTestSuite(GeneratingAnnotatedClassesTest.class); diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java index 3311c5386..ef4b8a9a7 100644 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java +++ b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java @@ -1,5 +1,5 @@ /* ******************************************************************* - * Copyright (c) 2004, 2013 IBM, VMware + * Copyright (c) 2004 - 2016 IBM, VMware, Contributors * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 @@ -34,8 +34,7 @@ import org.aspectj.apache.bcel.util.SyntheticRepository; /** * Super class for the Java5 tests, includes various helper methods. */ - -public class BcelTestCase extends TestCase { +public abstract class BcelTestCase extends TestCase { private boolean verbose = false; @@ -175,4 +174,13 @@ public class BcelTestCase extends TestCase { return null; } + public Attribute getAttribute(Attribute[] attrs, String name) { + for (Attribute attr: attrs) { + if (attr.getName().equals(name)) { + return attr; + } + } + return null; + } + } diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java new file mode 100644 index 000000000..454817df8 --- /dev/null +++ b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java @@ -0,0 +1,136 @@ +/* ******************************************************************* + * Copyright (c) 2016-2017 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * ******************************************************************/ + +package org.aspectj.apache.bcel.classfile.tests; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ClassParser; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Module; +import org.aspectj.apache.bcel.classfile.Module.Export; +import org.aspectj.apache.bcel.classfile.Module.Open; +import org.aspectj.apache.bcel.classfile.Module.Provide; +import org.aspectj.apache.bcel.classfile.Module.Require; +import org.aspectj.apache.bcel.classfile.Module.Uses; +import org.aspectj.apache.bcel.classfile.SourceFile; + +/** + * http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html + * + * @author Andy Clement + */ +public class ModuleTest extends BcelTestCase { + + public void testLoadSimpleModuleClass() throws Exception { + String moduleFilename = "testdata/modules/one/module-info.class"; + ClassParser classParser = new ClassParser(moduleFilename); + JavaClass javaClass = classParser.parse(); + assertNotNull(javaClass); + assertEquals(Constants.MAJOR_1_9,javaClass.getMajor()); + assertEquals(Constants.MINOR_1_9,javaClass.getMinor()); + assertEquals(Constants.ACC_MODULE,javaClass.getModifiers()); + assertEquals(0,javaClass.getSuperclassNameIndex()); + assertEquals(0,javaClass.getInterfaceIndices().length); + assertEquals(0,javaClass.getFields().length); + assertEquals(0,javaClass.getMethods().length); + Attribute[] attrs = javaClass.getAttributes(); + assertEquals(2,attrs.length); + SourceFile sourceFile = (SourceFile) getAttribute(attrs,Constants.ATTR_SOURCE_FILE); + Module moduleAttr = (Module) getAttribute(attrs, Constants.ATTR_MODULE); + byte[] originalData = moduleAttr.getBytes(); + String[] requiredModuleNames = moduleAttr.getRequiredModuleNames(); + assertEquals(1,requiredModuleNames.length); + assertEquals("java.base",requiredModuleNames[0]); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + moduleAttr.dump(new DataOutputStream(baos)); + byte[] newData = baos.toByteArray(); + // The 6 offset here is because the newdata includes the 2byte cpool pointer for the name 'Module' + // and the 4byte int length field for the attribute data + if (newData.length!=originalData.length+6) { + fail("Expected the length of the original attribute ("+originalData.length+") to match the new written length ("+newData.length+")"); + } + for (int i=0;i<originalData.length;i++) { + if (originalData[i]!=newData[i+6]) { + fail("byte mismatch at position "+i+" of "+newData.length); + } + } + } + + + public void testRequires() throws Exception { + Module moduleAttr = getModuleAttribute("testdata/modules/two/d/module-info.class"); + Require[] requires = moduleAttr.getRequires(); + assertEquals(4, requires.length); + assertEquals("requires mandated java.base 9",requires[0].toString()); + assertEquals("requires a.b.c",requires[1].toString()); + assertEquals("requires static b.c.d",requires[2].toString()); + assertEquals("requires transitive c.d.e",requires[3].toString()); + assertEquals("java.base",requires[0].getModuleName()); + assertEquals("a.b.c",requires[1].getModuleName()); + assertEquals("b.c.d",requires[2].getModuleName()); + assertEquals("c.d.e",requires[3].getModuleName()); + } + + public void testExports() throws Exception { + Module moduleAttr = getModuleAttribute("testdata/modules/two/e/module-info.class"); + Export[] exports = moduleAttr.getExports(); + assertEquals(3, exports.length); + assertEquals("exports com.foo1", exports[0].toString()); + assertEquals("exports com.foo2 to a.b.c",exports[1].toString()); + assertEquals("exports com.foo3 to a.b.c, b.c.d",exports[2].toString()); + assertEquals("com/foo1",exports[0].getPackage()); + assertEquals("com/foo2",exports[1].getPackage()); + assertEquals("com/foo3",exports[2].getPackage()); + assertEquals("a.b.c",exports[1].getToModuleNames()[0]); + assertEquals("a.b.c",exports[2].getToModuleNames()[0]); + assertEquals("b.c.d",exports[2].getToModuleNames()[1]); + } + + public void testOpens() throws Exception { + Module moduleAttr = getModuleAttribute("testdata/modules/two/h/module-info.class"); + Open[] opens = moduleAttr.getOpens(); + assertEquals(3, opens.length); + assertEquals("opens com.foo1", opens[0].toString()); + assertEquals("opens com.foo2 to a.b.c", opens[1].toString()); + assertEquals("opens com.foo3 to a.b.c, b.c.d", opens[2].toString()); + } + + public void testUses() throws Exception { + Module moduleAttr = getModuleAttribute("testdata/modules/two/f/module-info.class"); + Uses[] uses = moduleAttr.getUses(); + assertEquals(1,uses.length); + assertEquals("com/foo1/I1",uses[0].getTypeName()); + assertEquals("uses com.foo1.I1",uses[0].toString()); + } + + public void testProvides() throws Exception { + Module moduleAttr = getModuleAttribute("testdata/modules/two/g/module-info.class"); + Provide[] provides = moduleAttr.getProvides(); + assertEquals(2,provides.length); + assertEquals("provides com.foo1.I1 with com.foo1.C1",provides[0].toString()); + assertEquals("provides com.foo2.I2 with com.foo2.C2",provides[1].toString()); + assertEquals("com/foo1/I1",provides[0].getProvidedType()); + assertEquals("com/foo1/C1",provides[0].getWithTypeStrings()[0]); + assertEquals("com/foo2/I2",provides[1].getProvidedType()); + assertEquals("com/foo2/C2",provides[1].getWithTypeStrings()[0]); + } + + // --- + + private Module getModuleAttribute(String moduleInfoClass) throws Exception { + ClassParser classParser = new ClassParser(moduleInfoClass); + JavaClass javaClass = classParser.parse(); + return (Module)getAttribute(javaClass.getAttributes(), Constants.ATTR_MODULE); + } + +} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java index df4c2a401..be3e3d5ac 100644 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java +++ b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java @@ -205,17 +205,17 @@ public class TypeAnnotationsTest extends BcelTestCase { checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); // TODO type path bugs in javac b90 according to the spec - checkTypeAnnotationNew(tas[1],8, "@Anno(value=2)"); - checkTypePath(tas[1],new int[]{ - TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0 - }); - checkTypeAnnotationNew(tas[2],13, "@Anno(value=4)"); - checkTypePath(tas[2],TypeAnnotationGen.NO_TYPE_PATH); - checkTypeAnnotationNew(tas[3],13, "@Anno(value=3)"); - checkTypePath(tas[3],new int[]{ - TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0, - TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0 - }); +// checkTypeAnnotationNew(tas[1],8, "@Anno(value=2)"); +// checkTypePath(tas[1],new int[]{ +// TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0 +// }); +// checkTypeAnnotationNew(tas[2],13, "@Anno(value=4)"); +// checkTypePath(tas[2],TypeAnnotationGen.NO_TYPE_PATH); +// checkTypeAnnotationNew(tas[3],13, "@Anno(value=3)"); +// checkTypePath(tas[3],new int[]{ +// TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0, +// TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0 +// }); } diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/util/ClassPathTests.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/util/ClassPathTests.java new file mode 100644 index 000000000..711011213 --- /dev/null +++ b/bcel-builder/testsrc/org/aspectj/apache/bcel/util/ClassPathTests.java @@ -0,0 +1,22 @@ +package org.aspectj.apache.bcel.util; + +import java.io.IOException; + +import org.aspectj.apache.bcel.classfile.tests.BcelTestCase; +import org.aspectj.apache.bcel.util.ClassPath.ClassFile; + +public class ClassPathTests extends BcelTestCase { + + public void testJava9ImageFile() throws IOException { + String sunbootClasspath = System.getProperty("sun.boot.class.path"); + if (sunbootClasspath==null || sunbootClasspath.indexOf(".jimage")==-1) { + // Not java9 + return; + } + ClassPath cp = new ClassPath(sunbootClasspath); + ClassFile cf = cp.getClassFile("java/lang/Object"); + assertNotNull(cf); + assertTrue(cf.getSize()>0); + assertTrue(cf.getTime()>0); + } +} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/util/Play.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/util/Play.java new file mode 100644 index 000000000..abea68c1d --- /dev/null +++ b/bcel-builder/testsrc/org/aspectj/apache/bcel/util/Play.java @@ -0,0 +1,84 @@ +package org.aspectj.apache.bcel.util; + +import java.io.File; +import java.io.FileInputStream; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.ClassParser; +import org.aspectj.apache.bcel.classfile.Field; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos; + +public class Play { + + public static void printBytes(byte[] bs) { + StringBuilder sb = new StringBuilder("Bytes:"+bs.length+"["); + for (int i=0;i<bs.length;i++) { + if (i>0) sb.append(" "); + sb.append(bs[i]); + } + sb.append("]"); + System.out.println(sb); + } + + public static void main(String[] args) throws Exception { + if (args==null || args.length==0 ) { + System.out.println("Specify a file"); + return; + } + if (!args[0].endsWith(".class")) { + args[0] = args[0]+".class"; + } + FileInputStream fis = new FileInputStream(new File(args[0])); + ClassParser cp = new ClassParser(fis,args[0]); + JavaClass jc = cp.parse(); + Attribute[] attributes = jc.getAttributes(); + printUsefulAttributes(attributes); + System.out.println("Fields"); + Field[] fs = jc.getFields(); + if (fs!=null) { + for (Field f: fs) { + System.out.println(f); + printUsefulAttributes(f.getAttributes()); + } + } + System.out.println("Methods"); + Method[] ms = jc.getMethods(); + if (ms!=null) { + for (Method m: ms) { + System.out.println(m); + printUsefulAttributes(m.getAttributes()); + System.out.println("Code attributes:"); + printUsefulAttributes(m.getCode().getAttributes()); + } + } +// Method[] ms = jc.getMethods(); +// for (Method m: ms) { +// System.out.println("=========="); +// System.out.println("Method: "+m.getName()+" modifiers=0x"+Integer.toHexString(m.getModifiers())); +// Attribute[] as = m.getAttributes(); +// for (Attribute a: as) { +// if (a.getName().toLowerCase().contains("synthetic")) { +// System.out.println("> "+a.getName()); +// } +// } +// } + } + + private static void printUsefulAttributes(Attribute[] attributes) throws Exception { + for (Attribute attribute: attributes) { + String n = attribute.getName(); + if (n.equals("RuntimeInvisibleAnnotations") || + n.equals("RuntimeVisibleAnnotations")) { + RuntimeAnnos ra = (RuntimeAnnos)attribute; + // private byte[] annotation_data; + java.lang.reflect.Field f = RuntimeAnnos.class.getDeclaredField("annotation_data"); + f.setAccessible(true); + byte[] bs = (byte[])f.get(ra); +// byte[] bs = unknown.getBytes(); + printBytes(bs); + } + } + } +} diff --git a/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/DescendingVisitor.java b/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/DescendingVisitor.java index 251b94663..69b9e1321 100644 --- a/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/DescendingVisitor.java +++ b/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/DescendingVisitor.java @@ -73,7 +73,9 @@ import org.aspectj.apache.bcel.classfile.ConstantLong; import org.aspectj.apache.bcel.classfile.ConstantMethodHandle; import org.aspectj.apache.bcel.classfile.ConstantMethodType; import org.aspectj.apache.bcel.classfile.ConstantMethodref; +import org.aspectj.apache.bcel.classfile.ConstantModule; import org.aspectj.apache.bcel.classfile.ConstantNameAndType; +import org.aspectj.apache.bcel.classfile.ConstantPackage; import org.aspectj.apache.bcel.classfile.ConstantPool; import org.aspectj.apache.bcel.classfile.ConstantString; import org.aspectj.apache.bcel.classfile.ConstantUtf8; @@ -92,6 +94,9 @@ import org.aspectj.apache.bcel.classfile.LocalVariableTable; import org.aspectj.apache.bcel.classfile.LocalVariableTypeTable; import org.aspectj.apache.bcel.classfile.Method; import org.aspectj.apache.bcel.classfile.MethodParameters; +import org.aspectj.apache.bcel.classfile.Module; +import org.aspectj.apache.bcel.classfile.ModuleMainClass; +import org.aspectj.apache.bcel.classfile.ModulePackages; import org.aspectj.apache.bcel.classfile.Signature; import org.aspectj.apache.bcel.classfile.SourceFile; import org.aspectj.apache.bcel.classfile.StackMap; @@ -107,375 +112,411 @@ import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos; /** - * Traverses a JavaClass with another Visitor object 'piggy-backed' - * that is applied to all components of a JavaClass object. I.e. this - * class supplies the traversal strategy, other classes can make use - * of it. + * Traverses a JavaClass with another Visitor object 'piggy-backed' that is + * applied to all components of a JavaClass object. I.e. this class supplies the + * traversal strategy, other classes can make use of it. * * @version $Id: DescendingVisitor.java,v 1.4 2009/09/15 19:40:22 aclement Exp $ - * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> + * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> */ public class DescendingVisitor implements ClassVisitor { - private JavaClass clazz; - private ClassVisitor visitor; - private Stack<Object> stack = new Stack<Object>(); - - /** @return container of current entitity, i.e., predecessor during traversal - */ - public Object predecessor() { - return predecessor(0); - } - - /** - * @param level nesting level, i.e., 0 returns the direct predecessor - * @return container of current entitity, i.e., predecessor during traversal - */ - public Object predecessor(int level) { - int size = stack.size(); - - if((size < 2) || (level < 0)) - return null; - else - return stack.elementAt(size - (level + 2)); // size - 1 == current - } - - /** @return current object - */ - public Object current() { - return stack.peek(); - } - - /** - * @param clazz Class to traverse - * @param visitor visitor object to apply to all components - */ - public DescendingVisitor(JavaClass clazz, ClassVisitor visitor) { - this.clazz = clazz; - this.visitor = visitor; - } - - /** - * Start traversal. - */ - public void visit() { clazz.accept(this); } - - public void visitJavaClass(JavaClass clazz) { - stack.push(clazz); - clazz.accept(visitor); - - Field[] fields = clazz.getFields(); - for(int i=0; i < fields.length; i++) - fields[i].accept(this); - - Method[] methods = clazz.getMethods(); - for(int i=0; i < methods.length; i++) - methods[i].accept(this); - - AttributeUtils.accept(clazz.getAttributes(),visitor); -// clazz.getAttributes().accept(this); - clazz.getConstantPool().accept(this); - stack.pop(); - } - - public void visitField(Field field) { - stack.push(field); - field.accept(visitor); - AttributeUtils.accept(field.getAttributes(),visitor); -// field.getAttributes().accept(this); - stack.pop(); - } - - public void visitConstantValue(ConstantValue cv) { - stack.push(cv); - cv.accept(visitor); - stack.pop(); - } - - public void visitMethod(Method method) { - stack.push(method); - method.accept(visitor); - AttributeUtils.accept(method.getAttributes(),visitor); - stack.pop(); - } - - public void visitExceptionTable(ExceptionTable table) { - stack.push(table); - table.accept(visitor); - stack.pop(); - } - - public void visitCode(Code code) { - stack.push(code); - code.accept(visitor); - - CodeException[] table = code.getExceptionTable(); - for(int i=0; i < table.length; i++) - table[i].accept(this); - - Attribute[] attributes = code.getAttributes(); - for(int i=0; i < attributes.length; i++) - attributes[i].accept(this); - stack.pop(); - } - - public void visitCodeException(CodeException ce) { - stack.push(ce); - ce.accept(visitor); - stack.pop(); - } - - public void visitLineNumberTable(LineNumberTable table) { - stack.push(table); - table.accept(visitor); - - LineNumber[] numbers = table.getLineNumberTable(); - for(int i=0; i < numbers.length; i++) - numbers[i].accept(this); - stack.pop(); - } - - public void visitLineNumber(LineNumber number) { - stack.push(number); - number.accept(visitor); - stack.pop(); - } - - public void visitLocalVariableTable(LocalVariableTable table) { - stack.push(table); - table.accept(visitor); - - LocalVariable[] vars = table.getLocalVariableTable(); - for(int i=0; i < vars.length; i++) - vars[i].accept(this); - stack.pop(); - } - - public void visitStackMap(StackMap table) { - stack.push(table); - table.accept(visitor); - - StackMapEntry[] vars = table.getStackMap(); - - for(int i=0; i < vars.length; i++) - vars[i].accept(this); - stack.pop(); - } - - public void visitStackMapEntry(StackMapEntry var) { - stack.push(var); - var.accept(visitor); - stack.pop(); - } - - public void visitLocalVariable(LocalVariable var) { - stack.push(var); - var.accept(visitor); - stack.pop(); - } - - public void visitConstantPool(ConstantPool cp) { - stack.push(cp); - cp.accept(visitor); - - Constant[] constants = cp.getConstantPool(); - for(int i=1; i < constants.length; i++) { - if(constants[i] != null) - constants[i].accept(this); - } - - stack.pop(); - } - - public void visitConstantClass(ConstantClass constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - public void visitConstantDouble(ConstantDouble constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - public void visitConstantFieldref(ConstantFieldref constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - public void visitConstantFloat(ConstantFloat constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - public void visitConstantInteger(ConstantInteger constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - public void visitConstantLong(ConstantLong constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - public void visitConstantMethodref(ConstantMethodref constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - public void visitConstantMethodHandle(ConstantMethodHandle constant) { - throw new IllegalStateException("nyi"); - } - - public void visitConstantMethodType(ConstantMethodType obj) { - throw new IllegalStateException("nyi"); - } - - public void visitConstantInvokeDynamic(ConstantInvokeDynamic obj) { - throw new IllegalStateException("nyi"); - } - - public void visitBootstrapMethods(BootstrapMethods obj) { - throw new IllegalStateException("nyi"); - } - - public void visitConstantNameAndType(ConstantNameAndType constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - public void visitConstantString(ConstantString constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - public void visitConstantUtf8(ConstantUtf8 constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - public void visitInnerClasses(InnerClasses ic) { - stack.push(ic); - ic.accept(visitor); - - InnerClass[] ics = ic.getInnerClasses(); - for(int i=0; i < ics.length; i++) - ics[i].accept(this); - stack.pop(); - } - - public void visitInnerClass(InnerClass inner) { - stack.push(inner); - inner.accept(visitor); - stack.pop(); - } - - public void visitDeprecated(Deprecated attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitSignature(Signature attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - // J5SUPPORT: - public void visitEnclosingMethod(EnclosingMethod attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitRuntimeVisibleAnnotations(RuntimeVisAnnos attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitRuntimeInvisibleAnnotations(RuntimeInvisAnnos attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitRuntimeVisibleParameterAnnotations(RuntimeVisParamAnnos attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisParamAnnos attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitMethodParameters(MethodParameters attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitAnnotationDefault(AnnotationDefault attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitLocalVariableTypeTable(LocalVariableTypeTable table) { - stack.push(table); - table.accept(visitor); - - LocalVariable[] vars = table.getLocalVariableTypeTable(); - for(int i=0; i < vars.length; i++) - vars[i].accept(this); - stack.pop(); - } - - public void visitSourceFile(SourceFile attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitSynthetic(Synthetic attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - public void visitUnknown(Unknown attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } + private JavaClass clazz; + private ClassVisitor visitor; + private Stack<Object> stack = new Stack<Object>(); + + /** + * @return container of current entitity, i.e., predecessor during traversal + */ + public Object predecessor() { + return predecessor(0); + } + + /** + * @param level + * nesting level, i.e., 0 returns the direct predecessor + * @return container of current entitity, i.e., predecessor during traversal + */ + public Object predecessor(int level) { + int size = stack.size(); + + if ((size < 2) || (level < 0)) + return null; + else + return stack.elementAt(size - (level + 2)); // size - 1 == current + } + + /** + * @return current object + */ + public Object current() { + return stack.peek(); + } + + /** + * @param clazz + * Class to traverse + * @param visitor + * visitor object to apply to all components + */ + public DescendingVisitor(JavaClass clazz, ClassVisitor visitor) { + this.clazz = clazz; + this.visitor = visitor; + } + + /** + * Start traversal. + */ + public void visit() { + clazz.accept(this); + } + + public void visitJavaClass(JavaClass clazz) { + stack.push(clazz); + clazz.accept(visitor); + + Field[] fields = clazz.getFields(); + for (int i = 0; i < fields.length; i++) + fields[i].accept(this); + + Method[] methods = clazz.getMethods(); + for (int i = 0; i < methods.length; i++) + methods[i].accept(this); + + AttributeUtils.accept(clazz.getAttributes(), visitor); + // clazz.getAttributes().accept(this); + clazz.getConstantPool().accept(this); + stack.pop(); + } + + public void visitField(Field field) { + stack.push(field); + field.accept(visitor); + AttributeUtils.accept(field.getAttributes(), visitor); + // field.getAttributes().accept(this); + stack.pop(); + } + + public void visitConstantValue(ConstantValue cv) { + stack.push(cv); + cv.accept(visitor); + stack.pop(); + } + + public void visitMethod(Method method) { + stack.push(method); + method.accept(visitor); + AttributeUtils.accept(method.getAttributes(), visitor); + stack.pop(); + } + + public void visitExceptionTable(ExceptionTable table) { + stack.push(table); + table.accept(visitor); + stack.pop(); + } + + public void visitCode(Code code) { + stack.push(code); + code.accept(visitor); + + CodeException[] table = code.getExceptionTable(); + for (int i = 0; i < table.length; i++) + table[i].accept(this); + + Attribute[] attributes = code.getAttributes(); + for (int i = 0; i < attributes.length; i++) + attributes[i].accept(this); + stack.pop(); + } + + public void visitCodeException(CodeException ce) { + stack.push(ce); + ce.accept(visitor); + stack.pop(); + } + + public void visitLineNumberTable(LineNumberTable table) { + stack.push(table); + table.accept(visitor); + + LineNumber[] numbers = table.getLineNumberTable(); + for (int i = 0; i < numbers.length; i++) + numbers[i].accept(this); + stack.pop(); + } + + public void visitLineNumber(LineNumber number) { + stack.push(number); + number.accept(visitor); + stack.pop(); + } + + public void visitLocalVariableTable(LocalVariableTable table) { + stack.push(table); + table.accept(visitor); + + LocalVariable[] vars = table.getLocalVariableTable(); + for (int i = 0; i < vars.length; i++) + vars[i].accept(this); + stack.pop(); + } + + public void visitStackMap(StackMap table) { + stack.push(table); + table.accept(visitor); + + StackMapEntry[] vars = table.getStackMap(); + + for (int i = 0; i < vars.length; i++) + vars[i].accept(this); + stack.pop(); + } + + public void visitStackMapEntry(StackMapEntry var) { + stack.push(var); + var.accept(visitor); + stack.pop(); + } + + public void visitLocalVariable(LocalVariable var) { + stack.push(var); + var.accept(visitor); + stack.pop(); + } + + public void visitConstantPool(ConstantPool cp) { + stack.push(cp); + cp.accept(visitor); + + Constant[] constants = cp.getConstantPool(); + for (int i = 1; i < constants.length; i++) { + if (constants[i] != null) + constants[i].accept(this); + } + + stack.pop(); + } + + public void visitConstantClass(ConstantClass constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantDouble(ConstantDouble constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantFieldref(ConstantFieldref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantFloat(ConstantFloat constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantInteger(ConstantInteger constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantLong(ConstantLong constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantMethodref(ConstantMethodref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantMethodHandle(ConstantMethodHandle constant) { + throw new IllegalStateException("nyi"); + } + + public void visitConstantMethodType(ConstantMethodType obj) { + throw new IllegalStateException("nyi"); + } + + public void visitConstantInvokeDynamic(ConstantInvokeDynamic obj) { + throw new IllegalStateException("nyi"); + } + + public void visitBootstrapMethods(BootstrapMethods obj) { + throw new IllegalStateException("nyi"); + } + + public void visitConstantNameAndType(ConstantNameAndType constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantString(ConstantString constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantModule(ConstantModule constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantPackage(ConstantPackage constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantUtf8(ConstantUtf8 constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitInnerClasses(InnerClasses ic) { + stack.push(ic); + ic.accept(visitor); + + InnerClass[] ics = ic.getInnerClasses(); + for (int i = 0; i < ics.length; i++) + ics[i].accept(this); + stack.pop(); + } + + public void visitInnerClass(InnerClass inner) { + stack.push(inner); + inner.accept(visitor); + stack.pop(); + } + + public void visitDeprecated(Deprecated attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitSignature(Signature attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + // J5SUPPORT: + public void visitEnclosingMethod(EnclosingMethod attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitRuntimeVisibleAnnotations(RuntimeVisAnnos attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitRuntimeInvisibleAnnotations(RuntimeInvisAnnos attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitRuntimeVisibleParameterAnnotations(RuntimeVisParamAnnos attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisParamAnnos attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitMethodParameters(MethodParameters attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitAnnotationDefault(AnnotationDefault attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitLocalVariableTypeTable(LocalVariableTypeTable table) { + stack.push(table); + table.accept(visitor); + + LocalVariable[] vars = table.getLocalVariableTypeTable(); + for (int i = 0; i < vars.length; i++) + vars[i].accept(this); + stack.pop(); + } + + public void visitSourceFile(SourceFile attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitSynthetic(Synthetic attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitUnknown(Unknown attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitModule(Module attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitModulePackages(ModulePackages attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitModuleMainClass(ModuleMainClass attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } } diff --git a/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/EmptyClassVisitor.java b/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/EmptyClassVisitor.java index f1b61c1ac..039d204dd 100644 --- a/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/EmptyClassVisitor.java +++ b/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/EmptyClassVisitor.java @@ -68,7 +68,9 @@ import org.aspectj.apache.bcel.classfile.ConstantLong; import org.aspectj.apache.bcel.classfile.ConstantMethodHandle; import org.aspectj.apache.bcel.classfile.ConstantMethodType; import org.aspectj.apache.bcel.classfile.ConstantMethodref; +import org.aspectj.apache.bcel.classfile.ConstantModule; import org.aspectj.apache.bcel.classfile.ConstantNameAndType; +import org.aspectj.apache.bcel.classfile.ConstantPackage; import org.aspectj.apache.bcel.classfile.ConstantPool; import org.aspectj.apache.bcel.classfile.ConstantString; import org.aspectj.apache.bcel.classfile.ConstantUtf8; @@ -87,6 +89,9 @@ import org.aspectj.apache.bcel.classfile.LocalVariableTable; import org.aspectj.apache.bcel.classfile.LocalVariableTypeTable; import org.aspectj.apache.bcel.classfile.Method; import org.aspectj.apache.bcel.classfile.MethodParameters; +import org.aspectj.apache.bcel.classfile.Module; +import org.aspectj.apache.bcel.classfile.ModuleMainClass; +import org.aspectj.apache.bcel.classfile.ModulePackages; import org.aspectj.apache.bcel.classfile.Signature; import org.aspectj.apache.bcel.classfile.SourceFile; import org.aspectj.apache.bcel.classfile.StackMap; @@ -130,6 +135,8 @@ public class EmptyClassVisitor implements ClassVisitor { public void visitConstantNameAndType(ConstantNameAndType obj) {} public void visitConstantPool(ConstantPool obj) {} public void visitConstantString(ConstantString obj) {} + public void visitConstantModule(ConstantModule obj) {} + public void visitConstantPackage(ConstantPackage obj) {} public void visitConstantUtf8(ConstantUtf8 obj) {} public void visitConstantValue(ConstantValue obj) {} public void visitDeprecated(Deprecated obj) {} @@ -150,8 +157,8 @@ public class EmptyClassVisitor implements ClassVisitor { public void visitUnknown(Unknown obj) {} public void visitStackMap(StackMap obj) {} public void visitStackMapEntry(StackMapEntry obj) {} - - // J5SUPPORT: + + // J5: public void visitEnclosingMethod(EnclosingMethod obj) {} public void visitRuntimeVisibleAnnotations(RuntimeVisAnnos attribute) {} public void visitRuntimeInvisibleAnnotations(RuntimeInvisAnnos attribute) {} @@ -160,9 +167,14 @@ public class EmptyClassVisitor implements ClassVisitor { public void visitAnnotationDefault(AnnotationDefault attribute) {} public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) {} - // J8SUPPORT: + // J8: public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos attribute) {} public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos attribute) {} public void visitMethodParameters(MethodParameters attribute) {} + // J9: + public void visitModule(Module attribute) {} + public void visitModulePackages(ModulePackages attribute) {} + public void visitModuleMainClass(ModuleMainClass attribute) {} + } diff --git a/build/build.xml b/build/build.xml index cc1250e21..eeb019c33 100644 --- a/build/build.xml +++ b/build/build.xml @@ -275,7 +275,7 @@ <target name="maven.init" > <property name="org.apache.maven.ant.version" value="2.0.10"/> -<property name="org.springframework.build.aws.maven.version" value="2.0.0.RELEASE"/> + <property name="org.springframework.build.aws.maven.version" value="2.0.0.RELEASE"/> <!-- <ivy:cachepath resolveId="maven.ant.tasks.classpath" pathid="maven.ant.tasks.classpath" organisation="org.apache.maven" module="com.springsource.org.apache.maven.ant" @@ -287,6 +287,10 @@ --> <maven:install-provider groupId="org.springframework.build.aws" artifactId="org.springframework.build.aws.maven" version="${org.springframework.build.aws.maven.version}"/> +<!-- + <maven:install-provider groupId="org.springframework.build" artifactId="aws.maven" + version="${org.springframework.build.aws.maven.version}"/> +--> </target> @@ -836,7 +840,7 @@ ant -propertyfile XXX publishtomaven <target name="publishtomaven_milestone" depends="maven.init"> - <property name="suffix" value="1.8.11.RC1"/> + <property name="suffix" value="1.9.0.BETA-6"/> <property name="build.root" value="/Users/aclement/gits/org.aspectj/aj-build"/> <property name="adjusted.release.type" value="milestone"/> diff --git a/build/products/aspectj/install/intro.html b/build/products/aspectj/install/intro.html index d958ca1f8..b29bb9484 100644 --- a/build/products/aspectj/install/intro.html +++ b/build/products/aspectj/install/intro.html @@ -1,10 +1,10 @@ <html> <body> -<h2 align="center">Installer for AspectJ 8 Development Kit<sup><small>TM</small></sup></h2> +<h2 align="center">Installer for AspectJ 9 Development Kit<sup><small>TM</small></sup></h2> <p align="center">Version ${build.version.long} built on ${build.date}</p> -<p>This installs the complete AspectJ 8 Development Kit (AJDK) distribution, with +<p>This installs the complete AspectJ 9 Development Kit (AJDK) distribution, with the compiler, aspect libraries, structure browser, ant tasks, documentation, and examples. This distribution is covered by the Eclipse Public License (see diff --git a/build/src/$installer$/org/aspectj/Main.java b/build/src/$installer$/org/aspectj/Main.java index b5da78d49..748b035ae 100644 --- a/build/src/$installer$/org/aspectj/Main.java +++ b/build/src/$installer$/org/aspectj/Main.java @@ -997,10 +997,9 @@ class LocationPane extends WizardPane implements ActionListener { //XXX would like to find the place they last chose... public String getDefaultLocation() { if (context.onWindows()) { - //XXX hard-coded majorminor version needs to be fixed by 1.1 release - return "c:\\aspectj1.8"; + return "c:\\aspectj1.9"; } else { - return new File(System.getProperty("user.home"), "aspectj1.8").getAbsolutePath(); + return new File(System.getProperty("user.home"), "aspectj1.9").getAbsolutePath(); } } diff --git a/build/src/org/aspectj/internal/tools/ant/taskdefs/AntBuilder.java b/build/src/org/aspectj/internal/tools/ant/taskdefs/AntBuilder.java index aeb9b11b7..24a31f492 100644 --- a/build/src/org/aspectj/internal/tools/ant/taskdefs/AntBuilder.java +++ b/build/src/org/aspectj/internal/tools/ant/taskdefs/AntBuilder.java @@ -413,7 +413,7 @@ public class AntBuilder extends Builder { * @see org.aspectj.internal.tools.build.Builder#buildAntecedants(Module) */ protected Result[] getAntecedantResults(Result moduleResult) { - Hashtable<String,Target> targets = new Hashtable<>(); + Hashtable<String,Target> targets = new Hashtable<String, Target>(); makeTargetsForResult(moduleResult, targets); String targetName = resultToTargetName(moduleResult); // bug: doc says topoSort returns String, but returns Target @@ -423,7 +423,7 @@ public class AntBuilder extends Builder { if (0 == result.size()) { return new Result[0]; } - ArrayList<String> toReturn = new ArrayList<>(); + ArrayList<String> toReturn = new ArrayList<String>(); for (Iterator<Target> iter = result.iterator(); iter.hasNext();) { Target target = (Target) iter.next(); String name = target.getName(); diff --git a/build/src/org/aspectj/internal/tools/ant/taskdefs/Checklics.java b/build/src/org/aspectj/internal/tools/ant/taskdefs/Checklics.java index c05ee23ba..295a1faea 100644 --- a/build/src/org/aspectj/internal/tools/ant/taskdefs/Checklics.java +++ b/build/src/org/aspectj/internal/tools/ant/taskdefs/Checklics.java @@ -82,7 +82,7 @@ public class Checklics extends MatchingTask { License MPL_ONLY = new License(MPL_ONLY_TAG, LIC_MPL); License MPL_PARC = new License(MPL_PARC_TAG, LIC_MPL, PARC); License PARC_COPYRIGHT = new License(PARC_COPYRIGHT_TAG, null, PARC); - LICENSES = new Hashtable<>(); + LICENSES = new Hashtable<String,License>(); LICENSES.put(APL.tag, APL); LICENSES.put(MPL.tag, MPL); LICENSES.put(MPL_PARC.tag, MPL_PARC); @@ -463,7 +463,7 @@ class HeaderInfo { this.lastLine = lastLine; this.file = file; this.hasLicense = hasLicense; - List<String> newYears = new ArrayList<>(); + List<String> newYears = new ArrayList<String>(); newYears.addAll(years); Collections.sort(newYears); this.years = Collections.unmodifiableList(newYears); @@ -611,7 +611,7 @@ class Header { } public static HeaderInfo checkFile(final File file) { - ArrayList<String> years = new ArrayList<>(); + ArrayList<String> years = new ArrayList<String>(); int endLine = 0; BufferedReader input = null; int lineNum = 0; diff --git a/build/src/org/aspectj/internal/tools/ant/taskdefs/ConditionalTask.java b/build/src/org/aspectj/internal/tools/ant/taskdefs/ConditionalTask.java index 7a9092352..fdff0d7c1 100644 --- a/build/src/org/aspectj/internal/tools/ant/taskdefs/ConditionalTask.java +++ b/build/src/org/aspectj/internal/tools/ant/taskdefs/ConditionalTask.java @@ -168,7 +168,7 @@ public abstract class ConditionalTask extends Task { protected List<String> getFalses() { Iterator<If> iter = ifs().iterator(); - List<String> result = new Vector<>(); + List<String> result = new Vector<String>(); while (iter.hasNext()) { If next = (If) iter.next(); String name = next.getName(); diff --git a/build/src/org/aspectj/internal/tools/build/Builder.java b/build/src/org/aspectj/internal/tools/build/Builder.java index 4fe47ced4..72f53e901 100644 --- a/build/src/org/aspectj/internal/tools/build/Builder.java +++ b/build/src/org/aspectj/internal/tools/build/Builder.java @@ -149,7 +149,7 @@ public abstract class Builder { if ((null == text) || (0 == text.length())) { return Collections.EMPTY_LIST; } - List<String> strings = new ArrayList<>(); + List<String> strings = new ArrayList<String>(); StringTokenizer tok = new StringTokenizer(text, ","); while (tok.hasMoreTokens()) { String token = tok.nextToken().trim(); @@ -275,7 +275,7 @@ public abstract class Builder { return buildProduct(buildSpec); } Result result = specifyResultFor(buildSpec); - ArrayList<String> errors = new ArrayList<>(); + ArrayList<String> errors = new ArrayList<String>(); try { return buildAll(result, errors); } finally { @@ -340,7 +340,7 @@ public abstract class Builder { */ protected final boolean buildAll(Result result, List errors) { Result[] buildList = skipUptodate(getAntecedantResults(result)); - ArrayList<String> doneList = new ArrayList<>(); + ArrayList<String> doneList = new ArrayList<String>(); if ((null != buildList) && (0 < buildList.length)) { if (isLogging()) { handler.log("modules to build: " + Arrays.asList(buildList)); @@ -545,7 +545,7 @@ public abstract class Builder { * deliverables. */ protected ProductModule[] discoverModules(File productDir, Modules modules) { - final ArrayList<File> found = new ArrayList<>(); + final ArrayList<File> found = new ArrayList<File>(); FileFilter filter = new FileFilter() {// empty jar files public boolean accept(File file) { if ((null != file) && file.canRead() @@ -557,7 +557,7 @@ public abstract class Builder { } }; Util.visitFiles(productDir, filter); - ArrayList<ProductModule> results = new ArrayList<>(); + ArrayList<ProductModule> results = new ArrayList<ProductModule>(); for (File file: found) { String jarName = moduleAliasFor(file.getName().toLowerCase()); if (jarName.endsWith(".jar") || jarName.endsWith(".zip")) { // XXXFileLiteral diff --git a/build/src/org/aspectj/internal/tools/build/Module.java b/build/src/org/aspectj/internal/tools/build/Module.java index 8df660e2a..3f0afbfd9 100644 --- a/build/src/org/aspectj/internal/tools/build/Module.java +++ b/build/src/org/aspectj/internal/tools/build/Module.java @@ -69,7 +69,7 @@ public class Module { /** @return all source files under srcDir */ private static Iterator<File> sourceFiles(File srcDir) { - ArrayList<File> result = new ArrayList<>(); + ArrayList<File> result = new ArrayList<File>(); sourceFiles(srcDir, result); return result.iterator(); } @@ -199,11 +199,11 @@ public class Module { Util.iaxIfNull(name, "name"); Util.iaxIfNull(modules, "modules"); this.moduleDir = moduleDir; - this.libJars = new ArrayList<>(); - this.exportedLibJars = new ArrayList<>(); - this.requiredModules = new ArrayList<>(); - this.srcDirs = new ArrayList<>(); - this.classpathVariables = new ArrayList<>(); + this.libJars = new ArrayList<File>(); + this.exportedLibJars = new ArrayList<File>(); + this.requiredModules = new ArrayList<Module>(); + this.srcDirs = new ArrayList<File>(); + this.classpathVariables = new ArrayList<String>(); this.properties = new Properties(); this.name = name; this.modules = modules; @@ -613,7 +613,7 @@ public class Module { String[] tokenize(String line) { final String DELIM = " \n\t\\<>\"="; StringTokenizer st = new StringTokenizer(line, DELIM, true); - ArrayList<String> result = new ArrayList<>(); + ArrayList<String> result = new ArrayList<String>(); StringBuffer quote = new StringBuffer(); boolean inQuote = false; while (st.hasMoreTokens()) { diff --git a/build/src/org/aspectj/internal/tools/build/Modules.java b/build/src/org/aspectj/internal/tools/build/Modules.java index ca2b50aac..83686820e 100644 --- a/build/src/org/aspectj/internal/tools/build/Modules.java +++ b/build/src/org/aspectj/internal/tools/build/Modules.java @@ -24,7 +24,7 @@ import java.util.Hashtable; */ public class Modules { - private final Hashtable<String,Module> modules = new Hashtable<>(); + private final Hashtable<String,Module> modules = new Hashtable<String,Module>(); public final File baseDir; public final File jarDir; private final Messager handler; diff --git a/build/src/org/aspectj/internal/tools/build/Result.java b/build/src/org/aspectj/internal/tools/build/Result.java index 3b5a4e141..e12ba4e29 100644 --- a/build/src/org/aspectj/internal/tools/build/Result.java +++ b/build/src/org/aspectj/internal/tools/build/Result.java @@ -40,7 +40,7 @@ public class Result { private static final Kind[] KINDS = { RELEASE, TEST, RELEASE_ALL, TEST_ALL }; - private static final HashMap<String,Result> nameToResult = new HashMap<>(); + private static final HashMap<String,Result> nameToResult = new HashMap<String, Result>(); public static boolean isTestingJar(String name) { name = name.toLowerCase(); @@ -179,11 +179,11 @@ public class Result { Result(Kind kind, Module module, File jarDir) { this.kind = kind; this.module = module; - this.libJars = new ArrayList<>(); - this.exportedLibJars = new ArrayList<>(); - this.srcDirs = new ArrayList<>(); - this.classpathVariables = new ArrayList<>(); - this.requiredResults = new ArrayList<>(); + this.libJars = new ArrayList<File>(); + this.exportedLibJars = new ArrayList<File>(); + this.srcDirs = new ArrayList<File>(); + this.classpathVariables = new ArrayList<String>(); + this.requiredResults = new ArrayList<Result>(); String name = module.name; if (!kind.normal) { name += "-test"; @@ -219,7 +219,7 @@ public class Result { /** @return List (File) of jar's required */ public List<File> findJarRequirements() { - ArrayList<File> result = new ArrayList<>(); + ArrayList<File> result = new ArrayList<File>(); Module.doFindJarRequirements(this, result); return result; } diff --git a/build/src/org/aspectj/internal/tools/build/SampleGatherer.java b/build/src/org/aspectj/internal/tools/build/SampleGatherer.java index a9d29af6b..0b023e6c5 100644 --- a/build/src/org/aspectj/internal/tools/build/SampleGatherer.java +++ b/build/src/org/aspectj/internal/tools/build/SampleGatherer.java @@ -391,7 +391,7 @@ class Sample { * type-safe Collection of samples. */ class Samples { - private ArrayList<Sample> samples = new ArrayList<>(); + private ArrayList<Sample> samples = new ArrayList<Sample>(); int size() { return samples.size(); } @@ -406,7 +406,7 @@ class Samples { } List<Sample> getSortedSamples(Comparator<Sample> comparer) { - ArrayList<Sample> result = new ArrayList<>(); + ArrayList<Sample> result = new ArrayList<Sample>(); result.addAll(samples); Collections.sort(result, comparer); return result; @@ -957,7 +957,7 @@ class SampleUtil { } public static String[] splitAnchorName(String anchorName) { - ArrayList<String> result = new ArrayList<>(); + ArrayList<String> result = new ArrayList<String>(); int start = 0; int loc = anchorName.indexOf("-", start); String next; diff --git a/build/testsrc/org/aspectj/build/BuildModuleTests.java b/build/testsrc/org/aspectj/build/BuildModuleTests.java index 6c2e63dc4..52510c75f 100644 --- a/build/testsrc/org/aspectj/build/BuildModuleTests.java +++ b/build/testsrc/org/aspectj/build/BuildModuleTests.java @@ -69,7 +69,7 @@ public class BuildModuleTests extends TestCase { * @return */ private static File[] findSourceRoots(File moduleDir) { - ArrayList<File> result = new ArrayList<>(); + ArrayList<File> result = new ArrayList<File>(); for (String name: SOURCE_NAMES) { File srcDir = new File(moduleDir, name); if (srcDir.canRead() && srcDir.isDirectory()) { @@ -196,7 +196,7 @@ public class BuildModuleTests extends TestCase { // separate check to verify all file types (suffixes) are known if (!"testsrc".equals(srcDir.getName())) { - ArrayList<File> unknownFiles = new ArrayList<>(); + ArrayList<File> unknownFiles = new ArrayList<File>(); UnknownFileCheck.SINGLETON.unknownFiles(srcDir, unknownFiles); if (!unknownFiles.isEmpty()) { String s = "unknown files (see readme-build-module.html to " @@ -217,12 +217,12 @@ public class BuildModuleTests extends TestCase { */ static class UnknownFileCheck implements FileFilter { private static final UnknownFileCheck SINGLETON = new UnknownFileCheck(); - private static final ArrayList<String> STATIC_ERRORS = new ArrayList<>(); + private static final ArrayList<String> STATIC_ERRORS = new ArrayList<String>(); // Builder.BINARY_SOURCE_PATTERN and Builder.RESOURCE_PATTERN public static final List<String> KNOWN_SUFFIXES; static { - List<String> suffixes = new ArrayList<>(); + List<String> suffixes = new ArrayList<String>(); // sources from org.aspectj.util.FileUtil.SOURCE_SUFFIXES suffixes.add(".aj"); suffixes.add(".java"); diff --git a/build/testsrc/org/aspectj/internal/build/BuildModuleTest.java b/build/testsrc/org/aspectj/internal/build/BuildModuleTest.java index c06e678e2..bc96bef6a 100644 --- a/build/testsrc/org/aspectj/internal/build/BuildModuleTest.java +++ b/build/testsrc/org/aspectj/internal/build/BuildModuleTest.java @@ -80,7 +80,7 @@ public class BuildModuleTest extends TestCase { } } - ArrayList<File> tempFiles = new ArrayList<>(); + ArrayList<File> tempFiles = new ArrayList<File>(); private File jarDir; private boolean deleteJars; boolean building; // must be enabled for tests to run @@ -343,7 +343,7 @@ public class BuildModuleTest extends TestCase { try { zipFile = new ZipFile(weaverAllJar); Enumeration e = zipFile.entries(); - ArrayList<String> entryNames = new ArrayList<>(); + ArrayList<String> entryNames = new ArrayList<String>(); while (e.hasMoreElements()) { ZipEntry entry = (ZipEntry) e.nextElement(); String name = entry.getName(); diff --git a/build/testsrc/org/aspectj/internal/build/ModulesTest.java b/build/testsrc/org/aspectj/internal/build/ModulesTest.java index 51a58142a..16786404c 100644 --- a/build/testsrc/org/aspectj/internal/build/ModulesTest.java +++ b/build/testsrc/org/aspectj/internal/build/ModulesTest.java @@ -72,7 +72,7 @@ public class ModulesTest extends TestCase { } } - ArrayList<File> tempFiles = new ArrayList<>(); + ArrayList<File> tempFiles = new ArrayList<File>(); public ModulesTest(String name) { super(name); @@ -101,7 +101,7 @@ public class ModulesTest extends TestCase { } public void testAllModulesCreation() { - ArrayList<Module> badModules = new ArrayList<>(); + ArrayList<Module> badModules = new ArrayList<Module>(); for (String name: MODULE_NAMES) { File dir = new File(BASE_DIR, name); if (dir.isDirectory()) { diff --git a/build/usedForMavenUpload/aspectjrt.pom b/build/usedForMavenUpload/aspectjrt.pom index 5178898a6..f6648dc5d 100644 --- a/build/usedForMavenUpload/aspectjrt.pom +++ b/build/usedForMavenUpload/aspectjrt.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <packaging>jar</packaging> - <version>1.8.6.BUILD-SNAPSHOT</version> + <version>1.9.0.BUILD-SNAPSHOT</version> <name>AspectJ runtime</name> <description>The runtime needed to execute a program using AspectJ</description> <url>http://www.aspectj.org</url> diff --git a/build/usedForMavenUpload/aspectjtools.pom b/build/usedForMavenUpload/aspectjtools.pom index 2c536f4fc..7fac698ff 100644 --- a/build/usedForMavenUpload/aspectjtools.pom +++ b/build/usedForMavenUpload/aspectjtools.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <packaging>jar</packaging> - <version>1.8.6.BUILD-SNAPSHOT</version> + <version>1.9.0.BUILD-SNAPSHOT</version> <name>AspectJ tools</name> <description>Tools from the AspectJ project</description> <url>http://www.aspectj.org</url> diff --git a/build/usedForMavenUpload/aspectjweaver.pom b/build/usedForMavenUpload/aspectjweaver.pom index d681a3e73..bf649072c 100644 --- a/build/usedForMavenUpload/aspectjweaver.pom +++ b/build/usedForMavenUpload/aspectjweaver.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <packaging>jar</packaging> - <version>1.8.6.BUILD-SNAPSHOT</version> + <version>1.9.0.BUILD-SNAPSHOT</version> <name>AspectJ weaver</name> <description>The AspectJ weaver introduces advices to java classes</description> <url>http://www.aspectj.org</url> diff --git a/build/usedForMavenUpload_milestone/aspectjrt.pom b/build/usedForMavenUpload_milestone/aspectjrt.pom index 3294faa32..0ecddc2a1 100644 --- a/build/usedForMavenUpload_milestone/aspectjrt.pom +++ b/build/usedForMavenUpload_milestone/aspectjrt.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <packaging>jar</packaging> - <version>1.8.11.RC1</version> + <version>1.9.0.BETA-7</version> <name>AspectJ runtime</name> <description>The runtime needed to execute a program using AspectJ</description> <url>http://www.aspectj.org</url> diff --git a/build/usedForMavenUpload_milestone/aspectjtools.pom b/build/usedForMavenUpload_milestone/aspectjtools.pom index 37f29d136..3c8b62ef1 100644 --- a/build/usedForMavenUpload_milestone/aspectjtools.pom +++ b/build/usedForMavenUpload_milestone/aspectjtools.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <packaging>jar</packaging> - <version>1.8.11.RC1</version> + <version>1.9.0.BETA-7</version> <name>AspectJ tools</name> <description>Tools from the AspectJ project</description> <url>http://www.aspectj.org</url> diff --git a/build/usedForMavenUpload_milestone/aspectjweaver.pom b/build/usedForMavenUpload_milestone/aspectjweaver.pom index fd2dbc976..e44a95c8a 100644 --- a/build/usedForMavenUpload_milestone/aspectjweaver.pom +++ b/build/usedForMavenUpload_milestone/aspectjweaver.pom @@ -5,7 +5,7 @@ <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <packaging>jar</packaging> - <version>1.8.11.RC1</version> + <version>1.9.0.BETA-7</version> <name>AspectJ weaver</name> <description>The AspectJ weaver introduces advices to java classes</description> <url>http://www.aspectj.org</url> diff --git a/docs/adk15ProgGuideDB/joinpointsignatures.xml b/docs/adk15ProgGuideDB/joinpointsignatures.xml index d5b618e6d..013b9003b 100644 --- a/docs/adk15ProgGuideDB/joinpointsignatures.xml +++ b/docs/adk15ProgGuideDB/joinpointsignatures.xml @@ -185,7 +185,7 @@ </tgroup> </informaltable> - <para>Note that whilst an advice excetution join point has a + <para>Note that whilst an advice execution join point has a signature comprising the declaring type of the advice and the advice parameter types, the <literal>adviceexecution</literal> pointcut designator does not support matching based on this diff --git a/docs/dist/doc/README-190.html b/docs/dist/doc/README-190.html new file mode 100644 index 000000000..1ce1afe51 --- /dev/null +++ b/docs/dist/doc/README-190.html @@ -0,0 +1,262 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> <head> +<title>AspectJ 1.9.0.RC1 Readme</title> +<style type="text/css"> +<!-- + P { margin-left: 20px; } + PRE { margin-left: 20px; } + LI { margin-left: 20px; } + H4 { margin-left: 20px; } + H3 { margin-left: 10px; } +--> +</style> +</head> + +<body> +<div align="right"><small> +© Copyright 2017 Contributors. +All rights reserved. +</small></div> + +<h1>AspectJ 1.9.0.RC2 Readme</h1> + +<p>The full list of resolved issues in 1.9.0 is available +<a href="https://bugs.eclipse.org/bugs/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&bug_status=CLOSED&f0=OP&f1=OP&f3=CP&f4=CP&j1=OR&list_id=16866879&product=AspectJ&query_format=advanced&target_milestone=1.9.0">here</a></h2>.</p> + +<ul> +<li>1.9.0.RC2 available 9-Nov-2017 +</ul> + +<h3>1.9.0.RC2 changes</h3> + +<p>Key change in 1.9.0.RC2 is actually to be more tolerant of JDK10. The version handling has been somewhat overhauled so AspectJ 9 will +behave better on Java 10 and future JDKs. This should put AspectJ in a better place if new JDK versions are going +to arrive thick and fast. + +<ul> +<li>1.9.0.RC1 available 20-Oct-2017 +</ul> + +<h3>1.9.0.RC1 changes</h3> + +<p>This is the first release candidate of AspectJ 1.9.0 - the version of AspectJ to be based on Java9. It includes +a recent version of the Eclipse Java9 compiler (from jdt core, commit #062ac5d7a6bf9).</p> + + +<h4>Automatic Modules</h4> +<p>AspectJ can now be used with the new module system available in Java9. The key jars in AspectJ have been given automatic module names. + +The automatic module name is <tt>org.aspectj.runtime</tt> for the <tt>aspectjrt</tt> module:</p> +<pre><code> +$ java --module-path <pathto>/lib/aspectjrt.jar --list-modules | grep aspectj + +org.aspectj.runtime file:///<pathto>/lib/aspectjrt.jar automatic + +</code></pre> + +<p>And similarly <tt>org.aspectj.weaver</tt> and <tt>org.aspectj.tools</tt> for <tt>aspectjweaver</tt> and <tt>aspectjtools</tt> respectively:</p> + +<pre><code> +$ java --module-path <pathto>/lib/aspectjweaver.jar --describe-module org.aspectj.weaver + +org.aspectj.weaver file:///<pathto>/lib/aspectjweaver.jar automatic +requires java.base mandated +contains aj.org.objectweb.asm +contains aj.org.objectweb.asm.signature +contains org.aspectj.apache.bcel +contains org.aspectj.apache.bcel.classfile +contains org.aspectj.apache.bcel.classfile.annotation +contains org.aspectj.apache.bcel.generic +contains org.aspectj.apache.bcel.util +contains org.aspectj.asm +contains org.aspectj.asm.internal +... +</code></pre> +</p> +<br><br> +<h4>Building woven modules</h4> +<p>AspectJ understands module-info.java source files and building modules that include aspects. Here is an example:</p> + +<pre><code> +<b>module-info.java</b> + +module demo { + exports pkg; + requires org.aspectj.runtime; +} + + +<b>pkg/Demo.java</b> + +package pkg; + +public class Demo { + public static void main(String[] argv) { + System.out.println("Demo running"); + } +} + + +<b>otherpkg/Azpect.java</b> + +package otherpkg; + +public aspect Azpect { + before(): execution(* *(..)) && !within(Azpect) { + System.out.println("Azpect running"); + } +} + +</code></pre> + +<p>We can now build those into a module:</p> + +<pre><code> +$ ajc -1.9 module-info.java otherpkg/Azpect.java pkg/Demo.java -outjar demo.jar + +... +module-info.java:3 [error] org.aspectj.runtime cannot be resolved to a module +... +</code></pre> + +<p>Wait, that failed! Yes, <tt>aspectjrt.jar</tt> (which includes the required <tt>org.aspectj.weaver</tt> module) wasn't supplied. +We need to pass it on the module-path:</p> + +<pre><code> +$ ajc -1.9 --module-path <pathto>/aspectjrt.jar module-info.java otherpkg/Azpect.java pkg/Demo.java -outjar demo.jar + +</code></pre> + +<p>Now we have a demo module we can run:</p> + +<pre><code> +$ java --module-path <pathto>/aspectjrt.jar:demo.jar --module demo/pkg.Demo + +Azpect running +Demo running +</code></pre> + +<p>That's it!</p> + +<br><br> + +<h4>Binary weaving with modules</h4> + +<p>A module is really just a jar with a module-info descriptor. As such you can simply pass a module on the <tt>inpath</tt> +and binary weave it with other aspects. Take the module we built above, let's weave into it again:</p> + +<pre><code>extra/AnotherAzpect.java + +package extra; + +public aspect AnotherAzpect { + before(): execution(* *(..)) && !within(*Azpect) { + System.out.println("AnotherAzpect running"); + } +} +</code></pre> + +<pre><code> +$ ajc -inpath demo.jar AnotherAzpect.java -outjar newdemo.jar</code></pre> + +<p>Notice how there was no complaint here that the <tt>org.aspectj.runtime</tt> module hadn't been passed in. That is because <tt>inpath</tt> +was being used which doesn't treat specified jars as modules (and so does not check dependencies). There is no <tt>module-inpath</tt> right now. + +<p>Because the new jar produced includes the compiled aspect, the module-info specification inside is still correct, so we can run it +exactly as before:</p> + +<pre><code>$ java --module-path ~/installs/aspectj190rc1/lib/aspectjrt.jar:newdemo.jar --module demo/pkg.Demo + +Azpect running +AnotherAzpect running +Demo running +</code></pre> +<br><br> + +<h4>Faster Spring AOP</h4> +<p>Dave Syer recently created a series of benchmarks for checking the speed of Spring-AspectJ: +<tt><a href="https://github.com/dsyer/spring-boot-aspectj">https://github.com/dsyer/spring-boot-aspectj</a></tt> + +<p>Here we can see the numbers for AspectJ 1.8.11 (on an older Macbook Pro): + +<pre><code> +Benchmark (scale) Mode Cnt Score Error Units +StartupBenchmark.ltw N/A avgt 10 2.553 ~ 0.030 s/op +StartupBenchmark.ltw_100 N/A avgt 10 2.608 ~ 0.046 s/op +StartupBenchmark.spring v0_10 avgt 10 2.120 ~ 0.148 s/op +StartupBenchmark.spring v1_10 avgt 10 2.219 ~ 0.066 s/op +StartupBenchmark.spring v1_100 avgt 10 2.244 ~ 0.030 s/op +StartupBenchmark.spring v10_50 avgt 10 2.950 ~ 0.026 s/op +StartupBenchmark.spring v20_50 avgt 10 3.854 ~ 0.090 s/op +StartupBenchmark.spring v20_100 avgt 10 4.003 ~ 0.038 s/op +StartupBenchmark.spring a0_10 avgt 10 2.067 ~ 0.019 s/op +StartupBenchmark.spring a1_10 avgt 10 2.724 ~ 0.023 s/op +StartupBenchmark.spring a1_100 avgt 10 2.778 ~ 0.057 s/op +StartupBenchmark.spring a10_50 avgt 10 7.191 ~ 0.134 s/op +StartupBenchmark.spring a10_100 avgt 10 7.191 ~ 0.168 s/op +StartupBenchmark.spring a20_50 avgt 10 11.541 ~ 0.158 s/op +StartupBenchmark.spring a20_100 avgt 10 11.464 ~ 0.157 s/op +</code></pre> + +<p>So this is the average startup of an app affected by aspects applying to the beans involved. +Where numbers are referenced the first is the number of aspects/pointcuts and the second +is the number of beans. The 'a' indicates an annotation based pointcut vs a non-annotation +based pointcut ('v'). Notice things are much worse for annotation based pointcuts. At 20 +pointcuts and 50 beans the app is 9 seconds slower to startup. +<br> + +<p>In AspectJ 1.8.12 and 1.9.0.RC1 some work has been done here. The key change is to recognize that the use +of annotations with runtime retention is much more likely than annotations with class level +retention. Retrieving annotations with class retention is costly because we must open the +bytes for the class file and dig around in there (vs runtime retention which are immediately +accessible by reflection on the types). In 1.8.11 the actual type of the annotation involved +in the matching is ignored and the code will fetch *all* the annotations on the type/method/field +being matched against. So even if the match is looking for a runtime retention annotation, we +were doing the costly thing of fetching any class retention annotations. In 1.8.12/1.9.0.RC1 +we take the type of the match annotation into account - allowing us to skip opening the classfiles +in many cases. There is also some deeper work on activating caches that were not previously +being used correctly but the primary change is factoring in the annotation type. + +<p>What difference does that make? + +AspectJ 1.9.0.RC1: +<pre><code> +Benchmark (scale) Mode Cnt Score Error Units +StartupBenchmark.ltw N/A avgt 10 2.568 ~ 0.035 s/op +StartupBenchmark.ltw_100 N/A avgt 10 2.622 ~ 0.075 s/op +StartupBenchmark.spring v0_10 avgt 10 2.096 ~ 0.054 s/op +StartupBenchmark.spring v1_10 avgt 10 2.206 ~ 0.031 s/op +StartupBenchmark.spring v1_100 avgt 10 2.252 ~ 0.025 s/op +StartupBenchmark.spring v10_50 avgt 10 2.979 ~ 0.071 s/op +StartupBenchmark.spring v20_50 avgt 10 3.851 ~ 0.058 s/op +StartupBenchmark.spring v20_100 avgt 10 4.000 ~ 0.046 s/op +StartupBenchmark.spring a0_10 avgt 10 2.071 ~ 0.026 s/op +StartupBenchmark.spring a1_10 avgt 10 2.182 ~ 0.032 s/op +StartupBenchmark.spring a1_100 avgt 10 2.272 ~ 0.024 s/op +StartupBenchmark.spring a10_50 avgt 10 2.557 ~ 0.027 s/op +StartupBenchmark.spring a10_100 avgt 10 2.598 ~ 0.040 s/op +StartupBenchmark.spring a20_50 avgt 10 2.961 ~ 0.043 s/op +StartupBenchmark.spring a20_100 avgt 10 3.093 ~ 0.098 s/op +</code></pre> + +<p>Look at the a20_100 case - instead of impacting start time by 9 seconds, it impacts it by 1 second. + +<h3>More to come...</h3> + +<ul> +<li><p>Eclipse JDT Java 9 support is still being actively worked on and lots of fixes will be coming through over the next few months +and included in AspectJ 1.9.X revisions.</p> + +<li><p>AspectJ does not currently modify <tt>module-info.java</tt> files. An aspect from one module applying to code in +another module clearly introduces a dependency between those two modules. There is no reason - other than time! - that +this can't be done. (<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=526244">Issue 526244</a>)</p> + +<li><p>Related to that AspectJ, on detection of aspects should be able to automatically introduce the <tt>requires org.aspectj.runtime</tt> to +the <tt>module-info</tt>. (<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=526242">Issue 526242</a>)</p> + +<li><p>Module aware variants of AspectJ paths: <tt>--module-inpath</tt>, <tt>--module-aspectpath</tt>. (<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=526243">Issue 526243</a>)</p> +</ul> + +<!-- ============================== --> +</body> +</html> diff --git a/docs/dist/doc/index.html b/docs/dist/doc/index.html index d600c82b7..b06c50bc4 100644 --- a/docs/dist/doc/index.html +++ b/docs/dist/doc/index.html @@ -138,6 +138,7 @@ <tr> <td>README's </td> <td>Changes and porting guide for AspectJ + <a href="README-190.html">1.9.0</a>, <a href="README-1811.html">1.8.10</a>, <a href="README-1810.html">1.8.10</a>, <a href="README-189.html">1.8.9</a>, diff --git a/docs/install/intro.html b/docs/install/intro.html index acf054dac..36e7f3ad3 100644 --- a/docs/install/intro.html +++ b/docs/install/intro.html @@ -10,7 +10,7 @@ <body> -<h2 align="center">Installer for AspectJ(TM) 8 Development Kit</h2> +<h2 align="center">Installer for AspectJ(TM) 9 Development Kit</h2> <p align="center">Version ${build.version.long} built on ${build.date}</p> <p>${copyright.allRights.from1998}</p> diff --git a/lib/asm/asm-6.0_ALPHA.jar b/lib/asm/asm-6.0_ALPHA.jar Binary files differnew file mode 100644 index 000000000..72fd5036f --- /dev/null +++ b/lib/asm/asm-6.0_ALPHA.jar diff --git a/lib/asm/asm-6.0_ALPHA.renamed.jar b/lib/asm/asm-6.0_ALPHA.renamed.jar Binary files differnew file mode 100644 index 000000000..1ad8b789f --- /dev/null +++ b/lib/asm/asm-6.0_ALPHA.renamed.jar diff --git a/lib/asm/asm-6.0_BETA.jar b/lib/asm/asm-6.0_BETA.jar Binary files differnew file mode 100644 index 000000000..6b2994def --- /dev/null +++ b/lib/asm/asm-6.0_BETA.jar diff --git a/lib/asm/asm-6.0_BETA.renamed.jar b/lib/asm/asm-6.0_BETA.renamed.jar Binary files differnew file mode 100644 index 000000000..680ab7733 --- /dev/null +++ b/lib/asm/asm-6.0_BETA.renamed.jar diff --git a/lib/asm/build.xml b/lib/asm/build.xml index 44ee5e558..5f9693b56 100644 --- a/lib/asm/build.xml +++ b/lib/asm/build.xml @@ -4,8 +4,8 @@ <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"/> <target name="package" description="Jarjar asm-5.0.4.jar and prefix package name with aj"> - <jarjar destfile="asm-5.0.4.renamed.jar"> - <zipfileset src="asm-5.0.4.jar"/> + <jarjar destfile="asm-6.0_BETA.renamed.jar"> + <zipfileset src="asm-6.0_BETA.jar" excludes="module-info.class"/> <rule pattern="org.objectweb.asm.**" result="aj.org.objectweb.asm.@1"/> </jarjar> </target> diff --git a/lib/bcel/bcel-src.zip b/lib/bcel/bcel-src.zip Binary files differindex 58136055b..e620936d0 100644 --- a/lib/bcel/bcel-src.zip +++ b/lib/bcel/bcel-src.zip diff --git a/lib/bcel/bcel-verifier-src.zip b/lib/bcel/bcel-verifier-src.zip Binary files differindex c6a16a60b..ed37bdfa6 100644 --- a/lib/bcel/bcel-verifier-src.zip +++ b/lib/bcel/bcel-verifier-src.zip diff --git a/lib/bcel/bcel-verifier.jar b/lib/bcel/bcel-verifier.jar Binary files differindex 05c04d096..0153468a9 100644 --- a/lib/bcel/bcel-verifier.jar +++ b/lib/bcel/bcel-verifier.jar diff --git a/lib/bcel/bcel.jar b/lib/bcel/bcel.jar Binary files differindex fdfd8deda..acadafd3e 100644 --- a/lib/bcel/bcel.jar +++ b/lib/bcel/bcel.jar diff --git a/lib/build/build.jar b/lib/build/build.jar Binary files differindex 8a6f93714..a203ada4c 100644 --- a/lib/build/build.jar +++ b/lib/build/build.jar diff --git a/lib/test/aspectjrt.jar b/lib/test/aspectjrt.jar Binary files differindex ef06aa7fd..f0c7d5f7c 100644 --- a/lib/test/aspectjrt.jar +++ b/lib/test/aspectjrt.jar diff --git a/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java b/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java index 21a182157..24c5ba1bd 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java @@ -1,30 +1,38 @@ /******************************************************************************* - * Copyright (c) 2005 Contributors. + * Copyright (c) 2005, 2017 Contributors. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Vasseur initial implementation - * David Knibb weaving context enhancments - * John Kew (vmware) caching hook *******************************************************************************/ package org.aspectj.weaver.loadtime; -import java.io.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.security.ProtectionDomain; -import java.util.*; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.StringTokenizer; import org.aspectj.bridge.AbortException; import org.aspectj.bridge.Constants; import org.aspectj.bridge.MessageUtil; import org.aspectj.util.LangUtil; +import org.aspectj.weaver.IUnwovenClassFile; import org.aspectj.weaver.Lint; import org.aspectj.weaver.Lint.Kind; import org.aspectj.weaver.ResolvedType; @@ -39,13 +47,20 @@ import org.aspectj.weaver.loadtime.definition.DocumentParser; import org.aspectj.weaver.ltw.LTWWorld; import org.aspectj.weaver.patterns.PatternParser; import org.aspectj.weaver.patterns.TypePattern; -import org.aspectj.weaver.tools.*; +import org.aspectj.weaver.tools.GeneratedClassHandler; +import org.aspectj.weaver.tools.Trace; +import org.aspectj.weaver.tools.TraceFactory; +import org.aspectj.weaver.tools.WeavingAdaptor; import org.aspectj.weaver.tools.cache.WeavedClassCache; +import sun.misc.Unsafe; + /** * @author Alexandre Vasseur * @author Andy Clement * @author Abraham Nevado + * @author David Knibb + * @author John Kew */ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { @@ -53,8 +68,8 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { private boolean initialized; - private List<TypePattern> m_dumpTypePattern = new ArrayList<TypePattern>(); - private boolean m_dumpBefore = false; + private List<TypePattern> dumpTypePattern = new ArrayList<TypePattern>(); + private boolean dumpBefore = false; private boolean dumpDirPerClassloader = false; private boolean hasExcludes = false; @@ -67,14 +82,14 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { private boolean hasIncludes = false; private List<TypePattern> includeTypePattern = new ArrayList<TypePattern>(); - private List<String> m_includeStartsWith = new ArrayList<String>(); + private List<String> includeStartsWith = new ArrayList<String>(); private List<String> includeExactName = new ArrayList<String>(); private boolean includeStar = false; - private List<TypePattern> m_aspectExcludeTypePattern = new ArrayList<TypePattern>(); - private List<String> m_aspectExcludeStartsWith = new ArrayList<String>(); - private List<TypePattern> m_aspectIncludeTypePattern = new ArrayList<TypePattern>(); - private List<String> m_aspectIncludeStartsWith = new ArrayList<String>(); + private List<TypePattern> aspectExcludeTypePattern = new ArrayList<TypePattern>(); + private List<String> aspectExcludeStartsWith = new ArrayList<String>(); + private List<TypePattern> aspectIncludeTypePattern = new ArrayList<TypePattern>(); + private List<String> aspectIncludeStartsWith = new ArrayList<String>(); private StringBuffer namespace; private IWeavingContext weavingContext; @@ -153,7 +168,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { this.generatedClassHandler = new SimpleGeneratedClassHandler(classLoader); - List definitions = weavingContext.getDefinitions(classLoader, this); + List<Definition> definitions = weavingContext.getDefinitions(classLoader, this); if (definitions.isEmpty()) { disable(); // TODO maw Needed to ensure messages are flushed if (trace.isTraceEnabled()) { @@ -232,7 +247,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { String file = System.getProperty("aj5.def", null); if (file != null) { info("using (-Daj5.def) " + file); - definitions.add(DocumentParser.parse((new File(file)).toURL())); + definitions.add(DocumentParser.parse((new File(file)).toURI().toURL())); } } @@ -252,7 +267,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { if (!configFile.exists()) { warn("configuration does not exist: " + nextDefinition); } else { - definitions.add(DocumentParser.parse(configFile.toURL())); + definitions.add(DocumentParser.parse(configFile.toURI().toURL())); } } catch (MalformedURLException mue) { error("malformed definition url: " + nextDefinition); @@ -414,10 +429,10 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { for (Definition definition : definitions) { for (String exclude : definition.getAspectExcludePatterns()) { TypePattern excludePattern = new PatternParser(exclude).parseTypePattern(); - m_aspectExcludeTypePattern.add(excludePattern); + aspectExcludeTypePattern.add(excludePattern); fastMatchInfo = looksLikeStartsWith(exclude); if (fastMatchInfo != null) { - m_aspectExcludeStartsWith.add(fastMatchInfo); + aspectExcludeStartsWith.add(fastMatchInfo); } } } @@ -428,10 +443,10 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { for (Definition definition : definitions) { for (String include : definition.getAspectIncludePatterns()) { TypePattern includePattern = new PatternParser(include).parseTypePattern(); - m_aspectIncludeTypePattern.add(includePattern); + aspectIncludeTypePattern.add(includePattern); fastMatchInfo = looksLikeStartsWith(include); if (fastMatchInfo != null) { - m_aspectIncludeStartsWith.add(fastMatchInfo); + aspectIncludeStartsWith.add(fastMatchInfo); } } } @@ -586,7 +601,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { String include = iterator1.next(); fastMatchInfo = looksLikeStartsWith(include); if (fastMatchInfo != null) { - m_includeStartsWith.add(fastMatchInfo); + includeStartsWith.add(fastMatchInfo); } else if (include.equals("*")) { includeStar = true; } else if ((fastMatchInfo = looksLikeExactName(include)) != null) { @@ -723,10 +738,10 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { for (Iterator<String> iterator1 = definition.getDumpPatterns().iterator(); iterator1.hasNext();) { String dump = iterator1.next(); TypePattern pattern = new PatternParser(dump).parseTypePattern(); - m_dumpTypePattern.add(pattern); + dumpTypePattern.add(pattern); } if (definition.shouldDumpBefore()) { - m_dumpBefore = true; + dumpBefore = true; } if (definition.createDumpDirPerClassloader()) { dumpDirPerClassloader = true; @@ -811,9 +826,9 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { } } boolean fastAccept = false;// defaults to false if no fast include - for (int i = 0; i < m_includeStartsWith.size(); i++) { + for (int i = 0; i < includeStartsWith.size(); i++) { didSomeIncludeMatching = true; - fastAccept = fastClassName.startsWith(m_includeStartsWith.get(i)); + fastAccept = fastClassName.startsWith(includeStartsWith.get(i)); if (fastAccept) { return true; } @@ -849,9 +864,9 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { } } } - for (int i = 0; i < m_includeStartsWith.size(); i++) { + for (int i = 0; i < includeStartsWith.size(); i++) { didSomeIncludeMatching = true; - boolean fastaccept = fastClassName.startsWith(m_includeStartsWith.get(i)); + boolean fastaccept = fastClassName.startsWith(includeStartsWith.get(i)); if (fastaccept) { return true; } @@ -874,21 +889,21 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { // this can be nice but very dangerous as well to change that private boolean acceptAspect(String aspectClassName) { // avoid ResolvedType if not needed - if (m_aspectExcludeTypePattern.isEmpty() && m_aspectIncludeTypePattern.isEmpty()) { + if (aspectExcludeTypePattern.isEmpty() && aspectIncludeTypePattern.isEmpty()) { return true; } // still try to avoid ResolvedType if we have simple patterns // EXCLUDE: if one match then reject String fastClassName = aspectClassName.replace('/', '.').replace('.', '$'); - for (int i = 0; i < m_aspectExcludeStartsWith.size(); i++) { - if (fastClassName.startsWith(m_aspectExcludeStartsWith.get(i))) { + for (int i = 0; i < aspectExcludeStartsWith.size(); i++) { + if (fastClassName.startsWith(aspectExcludeStartsWith.get(i))) { return false; } } // INCLUDE: if one match then accept - for (int i = 0; i < m_aspectIncludeStartsWith.size(); i++) { - if (fastClassName.startsWith(m_aspectIncludeStartsWith.get(i))) { + for (int i = 0; i < aspectIncludeStartsWith.size(); i++) { + if (fastClassName.startsWith(aspectIncludeStartsWith.get(i))) { return true; } } @@ -896,8 +911,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { // needs further analysis ResolvedType classInfo = weaver.getWorld().resolve(UnresolvedType.forName(aspectClassName), true); // exclude are "AND"ed - for (Iterator iterator = m_aspectExcludeTypePattern.iterator(); iterator.hasNext();) { - TypePattern typePattern = (TypePattern) iterator.next(); + for (TypePattern typePattern: aspectExcludeTypePattern) { if (typePattern.matchesStatically(classInfo)) { // exclude match - skip return false; @@ -905,8 +919,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { } // include are "OR"ed boolean accept = true;// defaults to true if no include - for (Iterator iterator = m_aspectIncludeTypePattern.iterator(); iterator.hasNext();) { - TypePattern typePattern = (TypePattern) iterator.next(); + for (TypePattern typePattern: aspectIncludeTypePattern) { accept = typePattern.matchesStatically(classInfo); if (accept) { break; @@ -919,19 +932,19 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { @Override protected boolean shouldDump(String className, boolean before) { // Don't dump before weaving unless asked to - if (before && !m_dumpBefore) { + if (before && !dumpBefore) { return false; } // avoid ResolvedType if not needed - if (m_dumpTypePattern.isEmpty()) { + if (dumpTypePattern.isEmpty()) { return false; } // TODO AV - optimize for className.startWith only ResolvedType classInfo = weaver.getWorld().resolve(UnresolvedType.forName(className), true); // dump - for (Iterator<TypePattern> iterator = m_dumpTypePattern.iterator(); iterator.hasNext();) { + for (Iterator<TypePattern> iterator = dumpTypePattern.iterator(); iterator.hasNext();) { TypePattern typePattern = iterator.next(); if (typePattern.matchesStatically(classInfo)) { // dump match @@ -990,35 +1003,35 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { */ public void flushGeneratedClasses() { // System.err.println("? ClassLoaderWeavingAdaptor.flushGeneratedClasses() generatedClasses=" + generatedClasses); - generatedClasses = new HashMap(); + generatedClasses = new HashMap<String, IUnwovenClassFile>(); } - private Method defineClassMethod; - private Method defineClassWithProtectionDomainMethod; + private Unsafe unsafe; + private Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException { + if (unsafe == null) { + Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafeField.setAccessible(true); + return (Unsafe) theUnsafeField.get(null); + } + return unsafe; + } + private void defineClass(ClassLoader loader, String name, byte[] bytes) { if (trace.isTraceEnabled()) { trace.enter("defineClass", this, new Object[] { loader, name, bytes }); } Object clazz = null; debug("generating class '" + name + "'"); - try { - if (defineClassMethod == null) { - defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] { String.class, - bytes.getClass(), int.class, int.class }); - } - defineClassMethod.setAccessible(true); - clazz = defineClassMethod.invoke(loader, new Object[] { name, bytes, new Integer(0), new Integer(bytes.length) }); - } catch (InvocationTargetException e) { - if (e.getTargetException() instanceof LinkageError) { - warn("define generated class failed", e.getTargetException()); - // is already defined (happens for X$ajcMightHaveAspect interfaces since aspects are reweaved) - // TODO maw I don't think this is OK and - } else { - warn("define generated class failed", e.getTargetException()); - } + clazz = getUnsafe().defineClass(name, bytes, 0, bytes.length, loader, null); + } catch (LinkageError le) { + // likely thrown due to defining something that already exists? + // Old comments from before moving to Unsafe.defineClass(): + // is already defined (happens for X$ajcMightHaveAspect interfaces since aspects are reweaved) + // TODO maw I don't think this is OK and } catch (Exception e) { + e.printStackTrace(System.err); warn("define generated class failed", e); } @@ -1033,24 +1046,13 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { } Object clazz = null; debug("generating class '" + name + "'"); - try { - // System.out.println(">> Defining with protection domain " + name + " pd=" + protectionDomain); - if (defineClassWithProtectionDomainMethod == null) { - defineClassWithProtectionDomainMethod = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] { - String.class, bytes.getClass(), int.class, int.class, ProtectionDomain.class }); - } - defineClassWithProtectionDomainMethod.setAccessible(true); - clazz = defineClassWithProtectionDomainMethod.invoke(loader, new Object[] { name, bytes, Integer.valueOf(0), - new Integer(bytes.length), protectionDomain }); - } catch (InvocationTargetException e) { - if (e.getTargetException() instanceof LinkageError) { - warn("define generated class failed", e.getTargetException()); - // is already defined (happens for X$ajcMightHaveAspect interfaces since aspects are reweaved) - // TODO maw I don't think this is OK and - } else { - warn("define generated class failed", e.getTargetException()); - } + getUnsafe().defineClass(name, bytes, 0, bytes.length, loader, protectionDomain); + } catch (LinkageError le) { + // likely thrown due to defining something that already exists? + // Old comments from before moving to Unsafe.defineClass(): + // is already defined (happens for X$ajcMightHaveAspect interfaces since aspects are reweaved) + // TODO maw I don't think this is OK and } catch (Exception e) { warn("define generated class failed", e); } diff --git a/loadtime/src/org/aspectj/weaver/loadtime/DefaultWeavingContext.java b/loadtime/src/org/aspectj/weaver/loadtime/DefaultWeavingContext.java index 0af75265c..8e8d9df77 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/DefaultWeavingContext.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/DefaultWeavingContext.java @@ -47,7 +47,7 @@ public class DefaultWeavingContext implements IWeavingContext { /** * Same as ClassLoader.getResources() */ - public Enumeration getResources(String name) throws IOException { + public Enumeration<URL> getResources(String name) throws IOException { return getClassLoader().getResources(name); } diff --git a/loadtime/testsrc/org/aspectj/weaver/loadtime/WeavingURLClassLoaderTest.java b/loadtime/testsrc/org/aspectj/weaver/loadtime/WeavingURLClassLoaderTest.java index aa161cdc5..187de37ba 100644 --- a/loadtime/testsrc/org/aspectj/weaver/loadtime/WeavingURLClassLoaderTest.java +++ b/loadtime/testsrc/org/aspectj/weaver/loadtime/WeavingURLClassLoaderTest.java @@ -356,6 +356,7 @@ public class WeavingURLClassLoaderTest extends TestCase { invokeMain(clazz, new String[] { "LTWAspect" }); fail("Expecting java.lang.NoClassDefFoundError"); } catch (Exception ex) { + // Expecting: java.lang.NoClassDefFoundError: LTWAspect String m = ex.getMessage(); if (-1 == m.indexOf("java.lang.NoClassDefFoundError")) { fail("Expecting java.lang.NoClassDefFoundError but caught " + ex); diff --git a/loadtime5/.settings/org.eclipse.jdt.core.prefs b/loadtime5/.settings/org.eclipse.jdt.core.prefs index c4f19e636..7341ab168 100644 --- a/loadtime5/.settings/org.eclipse.jdt.core.prefs +++ b/loadtime5/.settings/org.eclipse.jdt.core.prefs @@ -1,12 +1,11 @@ -#Wed May 04 16:57:27 BST 2005 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.compliance=1.7 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=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/loadtime5/loadtime5.mf.txt b/loadtime5/loadtime5.mf.txt index 729cae693..cea0e5eda 100644 --- a/loadtime5/loadtime5.mf.txt +++ b/loadtime5/loadtime5.mf.txt @@ -1,4 +1,5 @@ Manifest-Version: 1.0 +Automatic-Module-Name: org.aspectj.weaver Name: org/aspectj/weaver/ Specification-Title: AspectJ Weaver Classes Specification-Version: @build.version.short@ diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java index f6316cd00..c061208f0 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java @@ -17,8 +17,10 @@ import org.aspectj.ajdt.internal.core.builder.AjBuildConfig; import org.aspectj.bridge.*; import org.aspectj.org.eclipse.jdt.core.compiler.CategorizedProblem; import org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.AptProblem; +import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem; import org.aspectj.org.eclipse.jdt.internal.compiler.batch.Main; import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule; import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.aspectj.util.FileUtil; import org.aspectj.util.LangUtil; @@ -157,11 +159,16 @@ public class BuildArgParser extends Main { // TODO fix org.eclipse.jdt.internal.compiler.batch.Main so this hack isn't needed javaArgList.add("-classpath"); javaArgList.add(parser.classpath == null ? System.getProperty("user.dir") : parser.classpath); - javaArgList.add("-bootclasspath"); - javaArgList.add(parser.bootclasspath == null ? System.getProperty("user.dir") : parser.bootclasspath); +// javaArgList.add("-bootclasspath"); +// javaArgList.add(parser.bootclasspath == null ? System.getProperty("user.dir") : parser.bootclasspath); javaArgList.addAll(parser.getUnparsedArgs()); super.configure(javaArgList.toArray(new String[javaArgList.size()])); + if (parser.getModuleInfoArgument() != null) { + IModule moduleDesc = super.getModuleDesc(parser.getModuleInfoArgument()); + buildConfig.setModuleDesc(moduleDesc); + } + if (!proceed) { buildConfig.doNotProceed(); return buildConfig; @@ -181,8 +188,14 @@ public class BuildArgParser extends Main { } if (setClasspath) { + // This computed classpaths will be missing aspectpaths, inpaths, add those first buildConfig.setClasspath(getClasspath(parser)); + buildConfig.setModulepath(getModulepath(parser)); + buildConfig.setModulepathClasspathEntries(handleModulepath(parser.modulepath)); + buildConfig.setModulesourcepath(getModulesourcepath(parser)); + buildConfig.setModulesourcepathClasspathEntries(handleModuleSourcepath(parser.modulesourcepath)); buildConfig.setBootclasspath(getBootclasspath(parser)); + // TODO other paths (module/module source) } if (incrementalMode && (0 == buildConfig.getSourceRoots().size())) { @@ -214,8 +227,7 @@ public class BuildArgParser extends Main { } /* Search aspectpath */ - for (Iterator i = buildConfig.getAspectpath().iterator(); i.hasNext();) { - File pathElement = (File) i.next(); + for (File pathElement: buildConfig.getAspectpath()) { if (!pathElement.isDirectory() && pathElement.equals(outjar)) { String message = WeaverMessages.format(WeaverMessages.OUTJAR_IN_INPUT_PATH); MessageUtil.error(handler, message); @@ -237,6 +249,28 @@ public class BuildArgParser extends Main { return buildConfig; } + private void augmentCheckedClasspaths(List<File> extraPathEntries, String encoding) { + if (extraPathEntries.size() == 0) { + return; + } + ArrayList<String> asList = toArrayList(extraPathEntries); + List<FileSystem.Classpath> newClasspathEntries = handleClasspath(asList, encoding); + FileSystem.Classpath[] newCheckedClasspaths = new FileSystem.Classpath[checkedClasspaths.length + newClasspathEntries.size()]; + System.arraycopy(checkedClasspaths, 0, newCheckedClasspaths, 0, checkedClasspaths.length); + for (int i = 0; i < newClasspathEntries.size();i++) { + newCheckedClasspaths[i + checkedClasspaths.length] = newClasspathEntries.get(i); + } + checkedClasspaths = newCheckedClasspaths; + } + + private ArrayList<String> toArrayList(java.util.List<File> files) { + ArrayList<String> arrayList = new ArrayList<String>(); + for (File file: files) { + arrayList.add(file.getAbsolutePath()); + } + return arrayList; + } + public void printVersion() { final String version = bind("misc.version", //$NON-NLS-1$ new String[] { bind("compiler.name"), //$NON-NLS-1$ @@ -315,13 +349,33 @@ public class BuildArgParser extends Main { List<String> ret = new ArrayList<String>(); if (parser.bootclasspath == null) { - addClasspath(System.getProperty("sun.boot.class.path", ""), ret); + if (LangUtil.is19VMOrGreater()) { + addClasspath(LangUtil.getJrtFsFilePath(),ret); + } else { + addClasspath(System.getProperty("sun.boot.class.path", ""), ret); + } } else { addClasspath(parser.bootclasspath, ret); } return ret; } + + public List<String> getModulepath(AjcConfigParser parser) { + List<String> ret = new ArrayList<String>(); + addClasspath(parser.modulepath, ret); + return ret; + } + + public List<String> getModulesourcepath(AjcConfigParser parser) { + List<String> ret = new ArrayList<String>(); + addClasspath(parser.modulesourcepath, ret); + return ret; + } + public ArrayList<FileSystem.Classpath> handleClasspath(ArrayList<String> classpaths, String customEncoding) { + return super.handleClasspath(classpaths, customEncoding); + } + /** * If the classpath is not set, we use the environment's java.class.path, but remove the aspectjtools.jar entry from that list * in order to prevent wierd bootstrap issues (refer to bug#39959). @@ -376,6 +430,9 @@ public class BuildArgParser extends Main { } private void addClasspath(String classpath, List<String> classpathCollector) { + if (classpath == null) { + return; + } StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator); while (tokenizer.hasMoreTokens()) { classpathCollector.add(tokenizer.nextToken()); @@ -385,10 +442,13 @@ public class BuildArgParser extends Main { private class AjcConfigParser extends ConfigParser { private String bootclasspath = null; private String classpath = null; + private String modulepath = null; + private String modulesourcepath = null; private String extdirs = null; private List unparsedArgs = new ArrayList(); private AjBuildConfig buildConfig; private IMessageHandler handler; + private String moduleInfoArgument; public AjcConfigParser(AjBuildConfig buildConfig, IMessageHandler handler) { this.buildConfig = buildConfig; @@ -398,38 +458,48 @@ public class BuildArgParser extends Main { public List getUnparsedArgs() { return unparsedArgs; } + + public String getModuleInfoArgument() { + return this.moduleInfoArgument; + } /** * Extract AspectJ-specific options (except for argfiles). Caller should warn when sourceroots is empty but in incremental * mode. Signals warnings or errors through handler set in constructor. */ - public void parseOption(String arg, LinkedList args) { // XXX use ListIterator.remove() + public void parseOption(String arg, LinkedList<Arg> args) { // XXX use ListIterator.remove() int nextArgIndex = args.indexOf(arg) + 1; // XXX assumes unique // trim arg? buildConfig.setXlazyTjp(true); // now default - MINOR could be pushed down and made default at a lower level if (LangUtil.isEmpty(arg)) { showWarning("empty arg found"); + } else if (arg.endsWith("module-info.java")) { + moduleInfoArgument = arg; } else if (arg.equals("-inpath")) { if (args.size() > nextArgIndex) { // buildConfig.getAjOptions().put(AjCompilerOptions.OPTION_Inpath, CompilerOptions.PRESERVE); - List<File> inPath = buildConfig.getInpath(); StringTokenizer st = new StringTokenizer(((ConfigParser.Arg) args.get(nextArgIndex)).getValue(), File.pathSeparator); + boolean inpathChange = false; while (st.hasMoreTokens()) { String filename = st.nextToken(); File file = makeFile(filename); if (FileUtil.isZipFile(file)) { - inPath.add(file); + buildConfig.addToInpath(file); + inpathChange = true; } else { if (file.isDirectory()) { - inPath.add(file); + buildConfig.addToInpath(file); + inpathChange = true; } else { showWarning("skipping missing, empty or corrupt inpath entry: " + filename); } } } - buildConfig.setInPath(inPath); + if (inpathChange) { + buildConfig.processInPath(); + } args.remove(args.get(nextArgIndex)); } } else if (arg.equals("-injars")) { @@ -463,7 +533,8 @@ public class BuildArgParser extends Main { String filename = st.nextToken(); File jarFile = makeFile(filename); if (FileUtil.isZipFile(jarFile) || jarFile.isDirectory()) { - buildConfig.getAspectpath().add(jarFile); +// buildConfig.getAspectpath().add(jarFile); + buildConfig.addToAspectpath(jarFile); } else { showWarning("skipping missing, empty or corrupt aspectpath entry: " + filename); } @@ -655,10 +726,47 @@ public class BuildArgParser extends Main { } } classpath = cp.toString(); - args.remove(args.get(nextArgIndex)); + Arg pathArg = args.get(nextArgIndex); + unparsedArgs.add("-classpath"); + unparsedArgs.add(pathArg.getValue()); + args.remove(pathArg); } else { showError("-classpath requires classpath entries"); } + } else if (arg.equals("--module-path") || arg.equals("-p")) { + if (args.size() > nextArgIndex) { + String mpArg = ((ConfigParser.Arg) args.get(nextArgIndex)).getValue(); + modulepath = mpArg; +// StringBuffer mp = new StringBuffer(); +// StringTokenizer strTok = new StringTokenizer(mpArg, File.pathSeparator); +// while (strTok.hasMoreTokens()) { +// mp.append(makeFile(strTok.nextToken())); +// if (strTok.hasMoreTokens()) { +// mp.append(File.pathSeparator); +// } +// } +// modulepath = mp.toString(); + args.remove(args.get(nextArgIndex)); + } else { + showError("--module-path requires modulepath entries"); + } + } else if (arg.equals("--module-source-path") || arg.equals("-p")) { + if (args.size() > nextArgIndex) { + String mspArg = ((ConfigParser.Arg) args.get(nextArgIndex)).getValue(); + modulesourcepath = mspArg; +// StringBuffer mp = new StringBuffer(); +// StringTokenizer strTok = new StringTokenizer(mpArg, File.pathSeparator); +// while (strTok.hasMoreTokens()) { +// mp.append(makeFile(strTok.nextToken())); +// if (strTok.hasMoreTokens()) { +// mp.append(File.pathSeparator); +// } +// } +// modulepath = mp.toString(); + args.remove(args.get(nextArgIndex)); + } else { + showError("--module-source-path requires modulepath entries"); + } } else if (arg.equals("-extdirs")) { if (args.size() > nextArgIndex) { String extdirsArg = ((ConfigParser.Arg) args.get(nextArgIndex)).getValue(); @@ -721,11 +829,14 @@ public class BuildArgParser extends Main { } else if (arg.equals("-1.8")) { buildConfig.setBehaveInJava5Way(true); unparsedArgs.add("-1.8"); + } else if (arg.equals("-1.9")) { + buildConfig.setBehaveInJava5Way(true); + unparsedArgs.add("-1.9"); } else if (arg.equals("-source")) { if (args.size() > nextArgIndex) { String level = ((ConfigParser.Arg) args.get(nextArgIndex)).getValue(); if (level.equals("1.5") || level.equals("5") || level.equals("1.6") || level.equals("6") || level.equals("1.7") - || level.equals("7") || level.equals("8") || level.equals("1.8")) { + || level.equals("7") || level.equals("8") || level.equals("1.8") || level.equals("9") || level.equals("1.9")) { buildConfig.setBehaveInJava5Way(true); } unparsedArgs.add("-source"); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java index afa936db3..b92a4b439 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java @@ -176,7 +176,7 @@ public class ConfigParser { } } - protected void parseOption(String arg, LinkedList args) { + protected void parseOption(String arg, LinkedList<Arg> args) { showWarning("unrecognized option: " + arg); } @@ -191,22 +191,22 @@ public class ConfigParser { throw new ParseException(CONFIG_MSG + message, location); } - void parseArgs(LinkedList args) { + void parseArgs(LinkedList<Arg> args) { while (args.size() > 0) { parseOneArg(args); } } - protected Arg removeArg(LinkedList args) { + protected Arg removeArg(LinkedList<Arg> args) { if (args.size() == 0) { showError("value missing"); return null; } else { - return (Arg) args.removeFirst(); + return args.removeFirst(); } } - protected String removeStringArg(LinkedList args) { + protected String removeStringArg(LinkedList<Arg> args) { Arg arg = removeArg(args); if (arg == null) { return null; @@ -235,7 +235,7 @@ public class ConfigParser { return false; } - void parseOneArg(LinkedList args) { + void parseOneArg(LinkedList<Arg> args) { Arg arg = removeArg(args); String v = arg.getValue(); location = arg.getLocation(); @@ -245,6 +245,9 @@ public class ConfigParser { parseConfigFileHelper(makeFile(removeArg(args).getValue())); } else if (isSourceFileName(v)) { addFileOrPattern(makeFile(v)); + if (v.endsWith("module-info.java")) { + parseOption(arg.getValue(), args); + } } else if (isXml(v)) { addXmlFile(makeFile(v)); } else { @@ -284,6 +287,10 @@ public class ConfigParser { private Location location; private String value; + public String toString() { + return "Arg[location="+location+" value="+value+"]"; + } + public Arg(String value, Location location) { this.value = value; this.location = location; diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties index 836cc9a1b..2ee1fcb74 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties @@ -4,15 +4,142 @@ The -Xlintfile:lint.properties allows fine-grained control. In tools.jar, see org/aspectj/weaver/XlintDefault.properties for the default behavior and a template to copy. ### AspectJ-specific messages -compiler.name = AspectJ Compiler 1.8.11 -compiler.version = Eclipse Compiler Neon.2 #75dbfad0, 3.12 +compiler.name = AspectJ Compiler 1.9.0.RC2 +compiler.version = Eclipse Compiler BETA_JAVA9_062ac5d7a6bf9(Sep2017), 3.13 compiler.copyright = + ## this next one superceded by above... ## configure.version = AspectJ Compiler 1.1 configure.directoryNotExist = invalid option: {0} -## 3456789012345678901234567890123456789012345678901234567890123456789012345 + +### compile +compile.repetition = [repetition {0}/{1}] +compile.instantTime = [compiled {0} lines in {1} ms: {2} lines/s] +compile.detailedTime = [parse: {0} ms ({1}%), resolve: {2} ms ({3}%), analyze: {4} ms ({5}%), generate: {6} ms ({7}%) ] +compile.ioTime = [i/o: read: {0} ms ({1}%), write: {2} ms ({3}%)] +compile.averageTime = [average, excluding min-max {0} lines in {1} ms: {2} lines/s] +compile.totalTime = [total compilation time: {0}] +compile.oneProblem = 1 problem ({0}) +compile.severalProblemsErrorsOrWarnings = {0} problems ({1}) +compile.severalProblemsErrorsAndWarnings = {0} problems ({1}, {2}) +compile.severalProblems = {0} problems ({1}, {2}, {3}) +compile.oneError = 1 error +compile.severalErrors = {0} errors +compile.oneWarning = 1 warning +compile.severalWarnings = {0} warnings +compile.oneInfo = 1 info +compile.severalInfos = {0} info +compile.oneClassFileGenerated = [1 .class file generated] +compile.severalClassFilesGenerated = [{0} .class files generated] + +### configure +configure.requiresJDK1.2orAbove = Need to use a JVM >= 1.2 +configure.duplicateLog = duplicate log specification: {0} +configure.duplicateRepeat = duplicate repeat specification: {0} +configure.duplicateMaxProblems = duplicate max problems specification: {0} +configure.duplicateCompliance = duplicate compliance setting specification: {0} +configure.duplicateSource = duplicate source compliance setting specification: {0} +configure.duplicateTarget = duplicate target compliance setting specification: {0} +configure.source = source level should be comprised in between ''1.3'' and ''1.9'' (or ''5'', ''5.0'', ..., ''9'' or ''9.0''): {0} +configure.invalidSystem = invalid location for system libraries +configure.unsupportedOption = option {0} not supported at compliance level 9 and above +configure.duplicateOutputPath = duplicate output path specification: {0} +configure.duplicateModulePath = duplicate module path specification: {0} +configure.duplicateModuleSourcepath = duplicate source module path specification: {0} +configure.invalidModuleDescriptor = cannot open the module descriptor from {0} +configure.invalidModuleOption = incorrectly formatted option: {0} +configure.duplicateExport = can specify a package in a module only once with --add-export +configure.duplicateBootClasspath = duplicate bootclasspath specification: {0} +configure.duplicateExtDirs = duplicate extdirs specification: {0} +configure.duplicateSourcepath = duplicate sourcepath specification: {0} +configure.invalidDebugOption = invalid debug option: {0} +configure.invalidWarningConfiguration = invalid warning configuration: ''{0}'' +configure.invalidWarning = invalid warning token: ''{0}''. Ignoring warning and compiling +configure.invalidWarningOption = invalid warning option: ''{0}''. Must specify a warning token +configure.targetJDK = target JDK should be comprised in between ''1.1'' and ''1.4'': {0} +configure.incompatibleTargetForSource14 = ''1.4'' source mode requires ''-target 1.4'' : {0} +configure.incompatibleComplianceForSource14 = ''1.4'' source mode requires ''-1.4'' compliance mode: {0} +configure.incompatibleComplianceForTarget14 = ''1.4'' target mode requires ''-1.4'' compliance mode: {0} +configure.incompatibleComplianceForTarget11 = ''1.1'' target mode requires ''-1.3'' compliance mode: {0} +configure.incompatibleComplianceForTarget = Compliance level ''{0}'' is incompatible with target level ''{1}''. A compliance level ''{1}'' or better is required +configure.repetition = repetition must be a positive integer: {0} +configure.maxProblems = max problems must be a positive integer: {0} +configure.invalidNowarnOption = invalid syntax for nowarn option: {0} + +configure.invalidErrorConfiguration = invalid error configuration: ''{0}'' +configure.invalidError = invalid error token: ''{0}''. Ignoring this error token and compiling +configure.invalidErrorOption = invalid error option: ''{0}''. Must specify an error token + +configure.invalidInfoConfiguration = invalid info configuration: ''{0}'' +configure.invalidInfo = invalid info token: ''{0}''. Ignoring this info token and compiling +configure.invalidInfoOption = invalid info option: ''{0}''. Must specify an info token + +configure.directoryNotExist = directory does not exist: {0} +configure.IOError = i/o error : unable to retrieve .JAVA files in directory: {0} +configure.unrecognizedOption = Unrecognized option : {0} +configure.noClasspath = no classpath defined, using default directory instead +configure.incorrectClasspath = incorrect classpath: {0} +configure.invalidexpansionargumentname = expansion argument file {0} does not exist or cannot be read +configure.cannotOpenLog = cannot open .log file: {0} +configure.cannotOpenLogInvalidEncoding = cannot open .log file: {0}; because UTF-8 is not supported +configure.unexpectedCustomEncoding = unexpected custom encoding specification: {0}[{1}] +configure.unsupportedEncoding = unsupported encoding format: {0} +configure.duplicateDefaultEncoding = duplicate default encoding format specification: {0} +configure.invalidTaskTag ={0} is an invalid task tag +configure.incorrectExtDirsEntry = incorrect ext dir entry; {0} must be a directory +configure.incorrectEndorsedDirsEntry = incorrect endorsed dir entry; {0} must be a directory +configure.duplicateEndorsedDirs = duplicate endorseddirs specification: {0} +configure.missingDestinationPath = destination path must be provided with module source path +configure.incorrectDestinationPathEntry = incorrect destination path entry: {0} +configure.unexpectedBracket = unexpected bracket: {0} +configure.unexpectedDestinationPathEntry = unexpected destination path entry in {0} option +configure.unexpectedDestinationPathEntryFile = unexpected destination path entry for file: {0} +configure.accessRuleAfterDestinationPath = access rules cannot follow destination path entries: {0} +configure.duplicateDestinationPathEntry = duplicate destination path entry in {0} option +configure.invalidClassName = invalid class name: {0} +configure.unavailableAPT = Unable to load annotation processing manager {0} from classpath. +configure.incorrectVMVersionforAPT = Annotation processing got disabled, since it requires a 1.6 compliant JVM +configure.incompatibleSourceForCldcTarget=Target level ''{0}'' is incompatible with source level ''{1}''. A source level ''1.3'' or lower is required +configure.incompatibleComplianceForCldcTarget=Target level ''{0}'' is incompatible with compliance level ''{1}''. A compliance level ''1.4''or lower is required +configure.invalidClasspathSection = invalid Class-Path header in manifest of jar file: {0} +configure.multipleClasspathSections = multiple Class-Path headers in manifest of jar file: {0} +configure.missingwarningspropertiesfile=properties file {0} does not exist +configure.ioexceptionwarningspropertiesfile=An IOException occurred while reading the properties file {0} +configure.multipleencodings=Multiple encoding specified: {1}. The default encoding has been set to {0} +configure.differentencodings=Found encoding {0}. Different encodings were specified: {1} +configure.differentencoding=Found encoding {0}. A different encoding was specified: {1} + +### null annotations +configure.invalidNullAnnot = Token {0} is not in the expected format "nullAnnot(<non null annotation name> | <nullable annotation name> | <non-null by default annotation name>)" +configure.missingAnnotationPath = Missing argument to -annotationpath at ''{0}'' + +### requestor +requestor.error = {0}. ERROR in {1} +requestor.warning = {0}. WARNING in {1} +requestor.info = {0}. INFO in {1} +requestor.extraerror = {0}. ERROR: +requestor.extrawarning = {0}. WARNING: +requestor.extrainfo = {0}. INFO: +requestor.notRetrieveErrorMessage = Cannot retrieve the error message for {0} +requestor.noFileNameSpecified = (original file name is not available) + +### EMACS STYLE +output.emacs.error=error +output.emacs.warning=warning +output.emacs.info=info + +### unit +unit.more = File {0} is specified more than once +unit.missing = File {0} is missing + +### output +output.noClassFileCreated = No .class file created for file {1} in {0} because of an IOException: {2} + +### miscellaneous +misc.version = {0} {1}, {2} + ### miscellaneous misc.usage = {0}\n\ \n\ @@ -48,7 +175,7 @@ Standard Eclipse compiler options:\n\ \ Options enabled by default are prefixed with ''+''\n\ \ \n\ \ Classpath options:\n\ -\ -cp -classpath <directories and zip/jar files separated by ;>\n\ +\ -cp -classpath <directories and ZIP archives separated by ;>\n\ \ specify location for application classes and sources\n\ \ -bootclasspath <directories and zip/jar files separated by ;>\n\ \ specify location for system classes\n\ @@ -58,17 +185,21 @@ Standard Eclipse compiler options:\n\ \ when suffixed with ''[''<enc>'']'' (e.g. X.java[utf8])\n\ \ \n\ \ Compliance options:\n\ -\ -1.3 use 1.3 compliance level (implicit -source 1.3 -target 1.1)\n\ -\ -1.4 + use 1.4 compliance level\n\ +\ -1.3 use 1.3 compliance (-source 1.3 -target 1.1)\n\ +\ -1.4 + use 1.4 compliance (-source 1.3 -target 1.2)\n\ \ -1.5 -5 -5.0 use 1.5 compliance (-source 1.5 -target 1.5)\n\ \ -1.6 -6 -6.0 use 1.6 compliance (-source 1.6 -target 1.6)\n\ \ -1.7 -7 -7.0 use 1.7 compliance (-source 1.7 -target 1.7)\n\ \ -1.8 -8 -8.0 use 1.8 compliance (-source 1.8 -target 1.8)\n\ -\ -source <version> set source level: 1.3 to 1.8 (or 5, 5.0, etc)\n\ -\ -target <version> set classfile target: 1.1 to 1.8 (or 5, 5.0, etc)\n\ +\ -1.9 -9 -9.0 use 1.9 compliance (-source 1.9 -target 1.9)\n\ +\ -source <version> set source level: 1.3 to 1.9 (or 6, 6.0, etc)\n\ +\ -target <version> set classfile target: 1.1 to 1.9 (or 6, 6.0, etc)\n\ +\ cldc1.1 can also be used to generate the StackMap\n\ +\ attribute\n\ \ \n\ \ Warning options:\n\ -\ -deprecation + deprecation outside deprecated code\n\ +\ -deprecation + deprecation outside deprecated code (equivalent to\n\ +\ -warn:+deprecation)\n\ \ -nowarn -warn:none disable all warnings\n\ \ -warn:<warnings separated by ,> enable exactly the listed warnings\n\ \ -warn:+<warnings separated by ,> enable additional warnings\n\ @@ -91,6 +222,8 @@ Standard Eclipse compiler options:\n\ \ emptyBlock undocumented empty block\n\ \ enumIdentifier ''enum'' used as identifier\n\ \ enumSwitch incomplete enum switch\n\ +\ enumSwitchPedantic + report missing enum switch cases even\n\ +\ in the presence of a default case\n\ \ fallthrough possible fall-through case\n\ \ fieldHiding field hiding another variable\n\ \ finalBound type parameter with final bound\n\ @@ -102,20 +235,53 @@ Standard Eclipse compiler options:\n\ \ includeAssertNull raise null warnings for variables\n\ \ that got tainted in an assert expression\n\ \ indirectStatic indirect reference to static member\n\ +\ inheritNullAnnot inherit null annotations\n\ \ intfAnnotation + annotation type used as super interface\n\ \ intfNonInherited + interface non-inherited method compatibility\n\ \ intfRedundant find redundant superinterfaces\n\ +\ invalidJavadoc all warnings for malformed javadoc tags\n\ +\ invalidJavadocTag validate javadoc tag arguments\n\ +\ invalidJavadocTagDep validate deprecated references in javadoc tag args\n\ +\ invalidJavadocTagNotVisible validate non-visible references in javadoc\n\ +\ tag args\n\ +\ invalidJavadocVisibility(<visibility>) specify visibility modifier\n\ +\ for malformed javadoc tag warnings\n\ \ javadoc invalid javadoc\n\ \ localHiding local variable hiding another variable\n\ \ maskedCatchBlock + hidden catch block\n\ +\ missingJavadocTags missing Javadoc tags\n\ +\ missingJavadocTagsOverriding missing Javadoc tags in overriding methods\n\ +\ missingJavadocTagsMethod missing Javadoc tags for method type parameter\n\ +\ missingJavadocTagsVisibility(<visibility>) specify visibility modifier\n\ +\ for missing javadoc tags warnings\n\ +\ missingJavadocComments missing Javadoc comments\n\ +\ missingJavadocCommentsOverriding missing Javadoc tags in overriding\n\ +\ methods\n\ +\ missingJavadocCommentsVisibility(<visibility>) specify visibility\n\ +\ modifier for missing javadoc comments warnings\n\ \ nls string literal lacking non-nls tag //$NON-NLS-<n>$\n\ \ noEffectAssign + assignment without effect\n\ \ null potential missing or redundant null check\n\ +\ nullAnnot(<annot. names separated by |>) annotation based null analysis,\n\ +\ nullable|nonnull|nonnullbydefault annotation types\n\ +\ optionally specified using fully qualified names.\n\ +\ Enabling this option enables all null-annotation\n\ +\ related sub-options. These can be individually\n\ +\ controlled using options listed below.\n\ +\ nullAnnotConflict conflict between null annotation specified\n\ +\ and nullness inferred. Is effective only with\n\ +\ nullAnnot option enabled.\n\ +\ nullAnnotRedundant redundant specification of null annotation. Is\n\ +\ effective only with nullAnnot option enabled.\n\ \ nullDereference + missing null check\n\ +\ nullUncheckedConversion unchecked conversion from non-annotated type\n\ +\ to @NonNull type. Is effective only with\n\ +\ nullAnnot option enabled.\n\ \ over-ann missing @Override annotation (superclass)\n\ \ paramAssign assignment to a parameter\n\ \ pkgDefaultMethod + attempt to override package-default method\n\ \ raw + usage of raw type\n\ +\ resource + (pot.) unsafe usage of resource of type Closeable\n\ \ semicolon unnecessary semicolon, empty statement\n\ \ serial + missing serialVersionUID\n\ \ specialParamHiding constructor or setter parameter hiding a field\n\ @@ -124,27 +290,45 @@ Standard Eclipse compiler options:\n\ \ staticReceiver + non-static reference to static member\n\ \ super overriding a method without making a super invocation\n\ \ suppress + enable @SuppressWarnings\n\ -\ When used with -err:, it can also silent optional\n\ +\ When used with -err:, it can also silence optional\n\ \ errors and warnings\n\ +\ switchDefault switch statement lacking a default case\n\ \ syncOverride missing synchronized in synchr. method override\n\ +\ syntacticAnalysis perform syntax-based null analysis for fields\n\ \ syntheticAccess synthetic access for innerclass\n\ \ tasks(<tags separated by |>) tasks identified by tags inside comments\n\ \ typeHiding + type parameter hiding another type\n\ \ unavoidableGenericProblems + ignore unavoidable type safety problems\n\ \ due to raw APIs\n\ \ unchecked + unchecked type operation\n\ +\ unlikelyCollectionMethodArgumentType\n\ +\ + unlikely argument type for collection method\n\ +\ declaring an Object parameter\n\ +\ unlikelyEqualsArgumentType unlikely argument type for method equals()\n\ \ unnecessaryElse unnecessary else clause\n\ \ unqualifiedField unqualified reference to field\n\ \ unused macro for unusedAllocation, unusedArgument,\n\ \ unusedImport, unusedLabel, unusedLocal,\n\ -\ unusedPrivate, unusedThrown, and unusedTypeArgs\n\ +\ unusedPrivate, unusedThrown, and unusedTypeArgs,\n\ +\ unusedExceptionParam\n\ \ unusedAllocation allocating an object that is not used\n\ \ unusedArgument unread method parameter\n\ +\ unusedExceptionParam unread exception parameter\n\ \ unusedImport + unused import declaration\n\ \ unusedLabel + unused label\n\ \ unusedLocal + unread local variable\n\ +\ unusedParam unused parameter\n\ +\ unusedParamOverriding unused parameter for overriding method\n\ +\ unusedParamImplementing unused parameter for implementing method\n\ +\ unusedParamIncludeDoc unused parameter documented in comment tag\n\ \ unusedPrivate + unused private member declaration\n\ \ unusedThrown unused declared thrown exception\n\ +\ unusedThrownWhenOverriding unused declared thrown exception in \n\ +\ overriding method\n\ +\ unusedThrownIncludeDocComment unused declared thrown exception,\n\ +\ documented in a comment tag\n\ +\ unusedThrownExemptExceptionThrowable unused declared thrown exception,\n\ +\ exempt Exception and Throwable\n\ \ unusedTypeArgs + unused type arguments for method and constructor\n\ \ uselessTypeCheck unnecessary cast/instanceof operation\n\ \ varargsCast + varargs argument need explicit cast\n\ diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AccessForInlineVisitor.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AccessForInlineVisitor.java index ad50e430c..5bf9946da 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AccessForInlineVisitor.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AccessForInlineVisitor.java @@ -23,6 +23,7 @@ import org.aspectj.ajdt.internal.compiler.lookup.InterTypeFieldBinding; import org.aspectj.ajdt.internal.compiler.lookup.InterTypeMethodBinding; import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedFieldBinding; import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedHandler; +import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; import org.aspectj.org.eclipse.jdt.internal.compiler.ASTVisitor; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AssertStatement; @@ -44,6 +45,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBin import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.VariableBinding; import org.aspectj.weaver.AjcMemberMaker; import org.aspectj.weaver.ResolvedMember; @@ -123,11 +125,16 @@ public class AccessForInlineVisitor extends ASTVisitor { // send.arguments = AstUtil.insert(new ThisReference(send.sourceStart, send.sourceEnd), send.arguments); MethodBinding superAccessBinding = getSuperAccessMethod(send.binding); AstUtil.replaceMethodBinding(send, superAccessBinding); - } else if (!isPublic(send.binding)) { + } else if (!isPublic(send.binding) && !isCloneMethod(send.binding)) { send.syntheticAccessor = getAccessibleMethod(send.binding, send.actualReceiverType); } } + + private boolean isCloneMethod(MethodBinding binding) { + return (CharOperation.equals(binding.selector, TypeConstants.CLONE)) && + (CharOperation.equals(binding.declaringClass.compoundName, TypeConstants.JAVA_LANG_OBJECT)); + } public void endVisit(AllocationExpression send, BlockScope scope) { if (send.binding == null || !send.binding.isValidBinding()) @@ -181,7 +188,6 @@ public class AccessForInlineVisitor extends ASTVisitor { } FieldBinding ret = new InlineAccessFieldBinding(inAspect, binding, m); inAspect.accessForInline.put(m, ret); - System.out.println(">>"+m); return ret; } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java index f833c0007..8db8e6076 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java @@ -80,10 +80,9 @@ public class AdviceDeclaration extends AjMethodDeclaration { // override protected int generateInfoAttributes(ClassFile classFile) { - List l = new ArrayList(1); + List<EclipseAttributeAdapter> l = new ArrayList<EclipseAttributeAdapter>(1); l.add(new EclipseAttributeAdapter(makeAttribute())); addDeclarationStartLineAttribute(l, classFile); - return classFile.generateMethodInfoAttributes(binding, l); } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java index 364bbe377..bd8e4db35 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java @@ -157,13 +157,15 @@ public class Proceed extends MessageSend { // checkInvocationArguments(scope, this.receiver, this.actualReceiverType, this.binding, this.arguments, argumentTypes, argsContainCast, this); - for (int i=0, len=arguments.length; i < len; i++) { + int len = arguments.length; + this.argumentTypes = (len == 0? TypeBinding.NO_TYPES:new TypeBinding[len]); + for (int i=0; i < len; i++) { Expression arg = arguments[i]; - TypeBinding argType = arg.resolveType(scope); - if (argType != null) { + argumentTypes[i] = arg.resolveType(scope); + if (argumentTypes[i] != null) { TypeBinding paramType = binding.parameters[i]; - if (!argType.isCompatibleWith(paramType)) { - scope.problemReporter().typeMismatchError(argType, paramType, arg,null); + if (!argumentTypes[i].isCompatibleWith(paramType)) { + scope.problemReporter().typeMismatchError(argumentTypes[i], paramType, arg, null); } } } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ValidateAtAspectJAnnotationsVisitor.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ValidateAtAspectJAnnotationsVisitor.java index fa63a3393..90ca34c45 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ValidateAtAspectJAnnotationsVisitor.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ValidateAtAspectJAnnotationsVisitor.java @@ -476,7 +476,7 @@ public class ValidateAtAspectJAnnotationsVisitor extends ASTVisitor { } else if (sma.memberValue instanceof NameReference && (((NameReference) sma.memberValue).binding instanceof FieldBinding)) { Binding b = ((NameReference) sma.memberValue).binding; - Constant c = ((FieldBinding) b).constant; + Constant c = ((FieldBinding) b).constant(); return c.stringValue(); } } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java index 52ad76f5b..935eb3cee 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java @@ -107,6 +107,10 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC INameEnvironment nameEnvironment) { super(typeRequestor, options, problemReporter, nameEnvironment); } + + public AjLookupEnvironment(LookupEnvironment env, ModuleBinding moduleBinding) { + super(env, moduleBinding); + } // ??? duplicates some of super's code public void completeTypeBindings() { @@ -1474,6 +1478,13 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC this.factory.cleanup(); super.reset(); } + + @Override + public LookupEnvironment wrapInModuleEnvironment(ModuleBinding moduleBinding) { + AjLookupEnvironment newAjLookupEnvironment = new AjLookupEnvironment(this, moduleBinding); + newAjLookupEnvironment.factory = this.factory; + return newAjLookupEnvironment; + } } // commented out, supplied as info on how to manipulate annotations in an diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java index 174f27215..5d7d337a9 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java @@ -204,7 +204,7 @@ public class EclipseSourceType extends AbstractReferenceTypeDelegate { return new String(sLit.source()); } else if (expr instanceof NameReference && (((NameReference) expr).binding instanceof FieldBinding)) { Binding b = ((NameReference) expr).binding; - Constant c = ((FieldBinding) b).constant; + Constant c = ((FieldBinding) b).constant(); return c.stringValue(); } else { throw new BCException("Do not know how to recover pointcut definition from " + expr + " (type " diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeScope.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeScope.java index 11dbebee2..bcb2a4c97 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeScope.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeScope.java @@ -113,4 +113,8 @@ public class InterTypeScope extends ClassScope { return usedAliases; } + @Override + public boolean isInterTypeScope() { + return true; + } } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java index 98bd0484e..0587c4462 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java @@ -20,14 +20,29 @@ import java.io.File; import java.io.FileFilter; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.StringTokenizer; import org.aspectj.ajdt.ajc.BuildArgParser; import org.aspectj.ajdt.internal.compiler.CompilationResultDestinationManager; +import org.aspectj.org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; +import org.aspectj.org.eclipse.jdt.internal.compiler.batch.ClasspathJar; +import org.aspectj.org.eclipse.jdt.internal.compiler.batch.ClasspathJrt; +import org.aspectj.org.eclipse.jdt.internal.compiler.batch.ClasspathLocation; +import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem; +import org.aspectj.org.eclipse.jdt.internal.compiler.batch.Main; +import org.aspectj.org.eclipse.jdt.internal.compiler.batch.ModuleFinder; +import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath; +import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule; +import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser; +import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter; import org.aspectj.util.FileUtil; /** @@ -35,7 +50,9 @@ import org.aspectj.util.FileUtil; * an AjCompilerOptions instance */ public class AjBuildConfig implements CompilerConfigurationChangeFlags { - + + public static final Classpath[] NO_CHECKED_CLASSPATHS = new Classpath[0]; + private boolean shouldProceed = true; public static final String AJLINT_IGNORE = "ignore"; @@ -59,8 +76,16 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags { private Map<String, File> sourcePathResources = new HashMap<String, File>(); private List<File> aspectpath = new ArrayList<File>(); private List<String> classpath = new ArrayList<String>(); + private List<String> modulepath = new ArrayList<String>(); + // Expensive to compute (searching modules, parsing module-info) + private ArrayList<Classpath> modulepathClasspathEntries = null; + private List<String> modulesourcepath = new ArrayList<String>(); + // Expensive to compute (searching modules, parsing module-info) + private ArrayList<Classpath> modulesourcepathClasspathEntries = null; + private Classpath[] checkedClasspaths = null; private List<String> bootclasspath = new ArrayList<String>(); private List<String> cpElementsWithModifiedContents = new ArrayList<String>(); + private IModule moduleDesc; private File configFile; private String lintMode = AJLINT_DEFAULT; @@ -205,6 +230,53 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags { public void setClasspath(List<String> classpath) { this.classpath = classpath; + checkedClasspaths = null; + } + + public List<String> getModulepath() { + return modulepath; + } + + public List<String> getModulesourcepath() { + return modulesourcepath; + } + + public void setModulepath(List<String> modulepath) { + this.modulepath = modulepath; + checkedClasspaths = null; + } + + public void setModulesourcepath(List<String> modulesourcepath) { + this.modulesourcepath = modulesourcepath; + checkedClasspaths = null; + } + + public void setCheckedClasspaths(Classpath[] checkedClasspaths) { + this.checkedClasspaths = checkedClasspaths; + checkedClasspaths = null; + } + + private List<Classpath> processFilePath(List<File> path, java.lang.String encoding) { + List<Classpath> entries = new ArrayList<Classpath>(); + for (File file: path) { + entries.add(FileSystem.getClasspath(file.getAbsolutePath(), encoding, null, ClasspathLocation.BINARY)); + } + return entries; + } + + private List<Classpath> processStringPath(List<String> path, java.lang.String encoding) { + List<Classpath> entries = new ArrayList<Classpath>(); + for (String file: path) { + entries.add(FileSystem.getClasspath(file, encoding, null, ClasspathLocation.BINARY)); + } + return entries; + } + + public Classpath[] getCheckedClasspaths() { + if (checkedClasspaths == null) { + computeCheckedClasspath(); + } + return checkedClasspaths; } public List<String> getBootclasspath() { @@ -225,7 +297,7 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags { public List<File> getInpath() { // Elements of the list are either archives (jars/zips) or directories - return inPath; + return Collections.unmodifiableList(inPath); } public List<File> getInJars() { @@ -246,11 +318,10 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags { public void setInJars(List<File> sourceJars) { this.inJars = sourceJars; + checkedClasspaths = null; } - public void setInPath(List<File> dirsOrJars) { - inPath = dirsOrJars; - + public void processInPath() { // remember all the class files in directories on the inpath binaryFiles = new ArrayList<BinarySourceFile>(); FileFilter filter = new FileFilter() { @@ -258,7 +329,7 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags { return pathname.getPath().endsWith(".class"); } }; - for (Iterator<File> iter = dirsOrJars.iterator(); iter.hasNext();) { + for (Iterator<File> iter = inPath.iterator(); iter.hasNext();) { File inpathElement = iter.next(); if (inpathElement.isDirectory()) { File[] files = FileUtil.listFiles(inpathElement, filter); @@ -269,6 +340,12 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags { } } + public void setInPath(List<File> dirsOrJars) { + inPath = dirsOrJars; + checkedClasspaths = null; + processInPath(); + } + public List<File> getSourceRoots() { return sourceRoots; } @@ -308,16 +385,18 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags { public List<String> getFullClasspath() { List<String> full = new ArrayList<String>(); full.addAll(getBootclasspath()); // XXX Is it OK that boot classpath overrides inpath/injars/aspectpath? - for (Iterator<File> i = inJars.iterator(); i.hasNext();) { - full.add((i.next()).getAbsolutePath()); + for (File file: inJars) { + full.add(file.getAbsolutePath()); } - for (Iterator<File> i = inPath.iterator(); i.hasNext();) { - full.add((i.next()).getAbsolutePath()); + for (File file: inPath) { + full.add(file.getAbsolutePath()); } - for (Iterator<File> i = aspectpath.iterator(); i.hasNext();) { - full.add((i.next()).getAbsolutePath()); + for (File file: aspectpath) { + full.add(file.getAbsolutePath()); } full.addAll(getClasspath()); + full.addAll(getModulepath()); + full.addAll(getModulesourcepath()); // if (null != outputDir) { // full.add(outputDir.getAbsolutePath()); // } else if (null != outputJar) { @@ -335,11 +414,22 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags { } public List<File> getAspectpath() { - return aspectpath; + return Collections.unmodifiableList(aspectpath); } public void setAspectpath(List<File> aspectpath) { this.aspectpath = aspectpath; + checkedClasspaths = null; + } + + public void addToAspectpath(File file) { + this.aspectpath.add(file); + checkedClasspaths = null; + } + + public void addToInjars(File file) { + this.inJars.add(file); + checkedClasspaths = null; } /** @return true if any config file, sourceroots, sourcefiles, injars or inpath */ @@ -765,4 +855,116 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags { public void setProjectEncoding(String projectEncoding) { options.defaultEncoding = projectEncoding; } + + public String getProjectEncoding() { + return options.defaultEncoding; + } + + public void setModuleDesc(IModule moduleDesc) { + this.moduleDesc = moduleDesc; + } + + public IModule getModuleDesc() { + return moduleDesc; + } + + public void addToInpath(Set<File> newInpathEntries) { + if (newInpathEntries != null && newInpathEntries.size() != 0) { + for (File newInpathEntry: newInpathEntries) { + if (!inPath.contains(newInpathEntry)) { + inPath.add(newInpathEntry); + } + } + checkedClasspaths = null; + } + } + + public void addToInpath(File newInpathEntry) { +// if (!inPath.contains(newInpathEntry)) { + inPath.add(newInpathEntry); +// } + checkedClasspaths = null; + } + + public void addToAspectpath(Set<File> newAspectpathEntries) { + if (newAspectpathEntries != null && newAspectpathEntries.size() != 0) { + for (File newAspectpathEntry: newAspectpathEntries) { + if (!aspectpath.contains(newAspectpathEntry)) { + aspectpath.add(newAspectpathEntry); + } + } + checkedClasspaths = null; + } + } + + public void setModulepathClasspathEntries(ArrayList<Classpath> modulepathClasspathEntries) { + this.modulepathClasspathEntries = modulepathClasspathEntries; + } + + public void setModulesourcepathClasspathEntries(ArrayList<Classpath> modulesourcepathClasspathEntries) { + this.modulesourcepathClasspathEntries = modulesourcepathClasspathEntries; + } + + public File removeAspectPathEntry(int i) { + checkedClasspaths = null; + return aspectpath.remove(i); + } + + public String removeClasspathEntry(int i) { + checkedClasspaths = null; + return classpath.remove(i); + } + + public File removeInpathEntry(int i) { + checkedClasspaths = null; + return inPath.remove(i); + } + + public File removeInjarsEntry(int i) { + checkedClasspaths = null; + return inJars.remove(0); + } + + + // This is similar to the calculation done in Main.setPaths() but it isn't as sophisticated + // as that one (doesn't need to be) and it also considers the additional paths for an + // AspectJ project (aspectpath/inpath/injars) + private void computeCheckedClasspath() { + // Follow what we do in getFullClasspath(): + // bootclasspath, injars, inpath, aspectpath, classpath, modulepath + + String encoding = getProjectEncoding(); + // What to do about bootclasspath on java 9? + + // ArrayList<Classpath> allPaths = handleBootclasspath(bootclasspaths, customEncoding); + ArrayList<FileSystem.Classpath> allPaths = new ArrayList<FileSystem.Classpath>(); + allPaths.addAll(processStringPath(bootclasspath, encoding)); + allPaths.addAll(processFilePath(inJars, encoding)); + allPaths.addAll(processFilePath(inPath, encoding)); + allPaths.addAll(processFilePath(aspectpath, encoding)); + if (modulepathClasspathEntries != null) { + allPaths.addAll(modulepathClasspathEntries); + } + if (modulesourcepathClasspathEntries != null) { + allPaths.addAll(modulesourcepathClasspathEntries); + } + // The classpath is done after modules to give precedence to modules that share the + // same paths as classpath elements (the upcoming normalize will remove later dups) + allPaths.addAll(processStringPath(classpath, encoding)); + for (Iterator<FileSystem.Classpath> iter = allPaths.iterator();iter.hasNext();) { + Classpath next = iter.next(); + if (next == null) { + iter.remove(); + } + } + allPaths = FileSystem.ClasspathNormalizer.normalize(allPaths); + this.checkedClasspaths = new FileSystem.Classpath[allPaths.size()]; + allPaths.toArray(this.checkedClasspaths); + for (int i=0;i<checkedClasspaths.length;i++) { + if (checkedClasspaths[i] == null) { + throw new IllegalStateException(); + } + } + } + } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java index 164af6629..85b665dcd 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java @@ -79,6 +79,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.batch.ClasspathLocation; import org.aspectj.org.eclipse.jdt.internal.compiler.batch.CompilationUnit; import org.aspectj.org.eclipse.jdt.internal.compiler.batch.FileSystem; import org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit; +import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule; import org.aspectj.org.eclipse.jdt.internal.compiler.env.INameEnvironment; import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser; @@ -865,8 +866,7 @@ public class AjBuildManager implements IOutputClassFileNameProvider, IBinarySour bcelWorld.getLint().setFromProperties(buildConfig.getLintSpecFile()); } - for (Iterator i = buildConfig.getAspectpath().iterator(); i.hasNext();) { - File f = (File) i.next(); + for (File f: buildConfig.getAspectpath()) { if (!f.exists()) { IMessage message = new Message("invalid aspectpath entry: " + f.getName(), null, true); handler.handleMessage(message); @@ -943,7 +943,19 @@ public class AjBuildManager implements IOutputClassFileNameProvider, IBinarySour // a classpathDirectory object that will attempt to look for source when it can't find binary. // int[] classpathModes = new int[classpaths.length]; // for (int i =0 ;i<classpaths.length;i++) classpathModes[i]=ClasspathDirectory.BINARY; - return new FileSystem(classpaths, filenames, defaultEncoding, ClasspathLocation.BINARY); + + FileSystem nameEnvironment = null; + // TODO J9 The compiler likes to work in terms of checked classpath objects - these will be different + // depending on where the code came from (classpath, modulepath). If working with just the raw + // 'classpaths' object it isn't recording where the code came from. This will be an issue later for + // weaving, the distinction will need to be maintained for proper 'module aware/respecting' weaving. + if (buildConfig.getCheckedClasspaths() == null) { + nameEnvironment = new FileSystem(classpaths, filenames, defaultEncoding, ClasspathLocation.BINARY); + } else { + nameEnvironment = new FileSystem(buildConfig.getCheckedClasspaths(), filenames, false); + } + nameEnvironment.module = buildConfig.getModuleDesc(); + return nameEnvironment; } public IProblemFactory getProblemFactory() { @@ -962,9 +974,30 @@ public class AjBuildManager implements IOutputClassFileNameProvider, IBinarySour if ("".equals(defaultEncoding)) {//$NON-NLS-1$ defaultEncoding = null; } - + CompilationUnit moduleCU = null; + + // TODO building with multiple module-infos? + int moduleIndex = -1; + IModule moduleDesc = buildConfig.getModuleDesc(); + String moduleName = moduleDesc == null? null: new String(moduleDesc.name()); + for (int i=0;i<fileCount;i++) { + if (filenames[i].endsWith("module-info.java")) { + moduleIndex = i; + moduleCU = new CompilationUnit(null, filenames[i], defaultEncoding, null, false, moduleName); + } + } + for (int i = 0; i < fileCount; i++) { - units[i] = new CompilationUnit(null, filenames[i], defaultEncoding); +// units[i] = new CompilationUnit(null, filenames[i], defaultEncoding); + if (i == moduleIndex) { + units[i] = moduleCU; + } else { + units[i] = new CompilationUnit(null, filenames[i], defaultEncoding, null, false, moduleName); + units[i].setModule(moduleCU); + } +// new CompilationUnit(null, fileName, encoding, this.destinationPaths[i], +// shouldIgnoreOptionalProblems(this.ignoreOptionalProblemsFromFolders, fileName.toCharArray()), +// this.modNames[i]); } return units; } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java index ffe2f4761..a7be9ec6e 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java @@ -9,7 +9,6 @@ * Contributors: * PARC initial implementation * ******************************************************************/ - package org.aspectj.ajdt.internal.core.builder; import java.util.Map; @@ -52,15 +51,15 @@ public class AjCompilerOptions extends CompilerOptions { // constants for irritant levels - public static final int InvalidAbsoluteTypeName = IrritantSet.GROUP2 | ASTNode.Bit20; - public static final int InvalidWildCardTypeName = IrritantSet.GROUP2 | ASTNode.Bit21; - public static final int UnresolvableMember = IrritantSet.GROUP2 | ASTNode.Bit22; - public static final int TypeNotExposedToWeaver = IrritantSet.GROUP2 | ASTNode.Bit23; - public static final int ShadowNotInStructure = IrritantSet.GROUP2 | ASTNode.Bit24; - public static final int UnmatchedSuperTypeInCall = IrritantSet.GROUP2 | ASTNode.Bit25; - public static final int CannotImplementLazyTJP = IrritantSet.GROUP2 | ASTNode.Bit26; - public static final int NeedSerialVersionUIDField = IrritantSet.GROUP2 | ASTNode.Bit27; - public static final int IncompatibleSerialVersion = IrritantSet.GROUP2 | ASTNode.Bit28; + public static final int InvalidAbsoluteTypeName = IrritantSet.GROUP3 | ASTNode.Bit1; + public static final int InvalidWildCardTypeName = IrritantSet.GROUP3 | ASTNode.Bit2; + public static final int UnresolvableMember = IrritantSet.GROUP3 | ASTNode.Bit3; + public static final int TypeNotExposedToWeaver = IrritantSet.GROUP3 | ASTNode.Bit4; + public static final int ShadowNotInStructure = IrritantSet.GROUP3 | ASTNode.Bit5; + public static final int UnmatchedSuperTypeInCall = IrritantSet.GROUP3 | ASTNode.Bit6; + public static final int CannotImplementLazyTJP = IrritantSet.GROUP3 | ASTNode.Bit7; + public static final int NeedSerialVersionUIDField = IrritantSet.GROUP3 | ASTNode.Bit8; + public static final int IncompatibleSerialVersion = IrritantSet.GROUP3 | ASTNode.Bit9; public boolean terminateAfterCompilation = false; public boolean xSerializableAspects = false; @@ -110,12 +109,7 @@ public class AjCompilerOptions extends CompilerOptions { setAspectJWarningDefaults(); } - /** - * Initializing the compiler options with external settings - * - * @param settings - */ - public AjCompilerOptions(Map settings) { + public AjCompilerOptions(Map<String,String> settings) { setAspectJWarningDefaults(); if (settings == null) { return; @@ -123,11 +117,6 @@ public class AjCompilerOptions extends CompilerOptions { set(settings); } - /* - * (non-Javadoc) - * - * @see org.eclipse.jdt.internal.compiler.impl.CompilerOptions#getMap() - */ public Map<String,String> getMap() { Map<String,String> map = super.getMap(); // now add AspectJ additional options @@ -159,12 +148,7 @@ public class AjCompilerOptions extends CompilerOptions { return map; } - /* - * (non-Javadoc) - * - * @see org.eclipse.jdt.internal.compiler.impl.CompilerOptions#set(java.util.Map) - */ - public void set(Map optionsMap) { + public void set(Map<String,String> optionsMap) { super.set(optionsMap); Object optionValue; if ((optionValue = optionsMap.get(OPTION_ReportUnusedPrivateMember)) != null) { @@ -294,14 +278,10 @@ public class AjCompilerOptions extends CompilerOptions { private void setAspectJWarningDefaults() { super.warningThreshold = new IrritantSet(super.warningThreshold); super.warningThreshold.set(InvalidAbsoluteTypeName | UnresolvableMember | TypeNotExposedToWeaver - | UnmatchedSuperTypeInCall | CannotImplementLazyTJP | CompilerOptions.SwallowedExceptionInCatchBlock); + | UnmatchedSuperTypeInCall | CannotImplementLazyTJP); + super.warningThreshold.set(CompilerOptions.SwallowedExceptionInCatchBlock); } - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ public String toString() { StringBuffer buf = new StringBuffer(super.toString()); // now add AspectJ additional options @@ -327,8 +307,7 @@ public class AjCompilerOptions extends CompilerOptions { buf.append("\n\t- cannot implement lazy thisJoinPoint (XLint): ").append(getSeverityString(CannotImplementLazyTJP)); //$NON-NLS-1$ buf.append("\n\t- need serialVersionUID field (XLint): ").append(getSeverityString(NeedSerialVersionUIDField)); //$NON-NLS-1$ buf.append("\n\t- incompatible serial version (XLint): ").append(getSeverityString(IncompatibleSerialVersion)); //$NON-NLS-1$ - buf - .append("\n\t- swallowed exception in catch block (XLint): ").append(getSeverityString(CompilerOptions.SwallowedExceptionInCatchBlock)); //$NON-NLS-1$ + buf.append("\n\t- swallowed exception in catch block (XLint): ").append(getSeverityString(CompilerOptions.SwallowedExceptionInCatchBlock)); //$NON-NLS-1$ return buf.toString(); } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompactTypeStructureRepresentation.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompactTypeStructureRepresentation.java index e9d367abd..e48c6cd0f 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompactTypeStructureRepresentation.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompactTypeStructureRepresentation.java @@ -190,7 +190,13 @@ public class CompactTypeStructureRepresentation implements IBinaryType { return walker; } + public char[] getModule() { + // TODO Auto-generated method stub + return null; + } + public ExternalAnnotationStatus getExternalAnnotationStatus() { return ExternalAnnotationStatus.NOT_EEA_CONFIGURED; } + }
\ No newline at end of file diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseClassPathManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseClassPathManager.java index 4ffb009a8..fa7e531c4 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseClassPathManager.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseClassPathManager.java @@ -61,6 +61,7 @@ public class EclipseClassPathManager extends ClassPathManager { name = name.substring(0,name.length() - ".class".length()); } char[][] cname = CharOperation.splitOn('.',name.toCharArray()); + // TODO [j9] passing null client/module here... NameEnvironmentAnswer answer = nameEnv.findType(cname); if (answer == null || !answer.isBinaryType()) { return null; diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/StatefulNameEnvironment.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/StatefulNameEnvironment.java index 6167e7aaf..b3cb0e2d1 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/StatefulNameEnvironment.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/StatefulNameEnvironment.java @@ -1,5 +1,5 @@ /* ******************************************************************* - * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * Copyright (c) 2002 IBM and other contributors * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 @@ -7,18 +7,17 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * PARC initial implementation + * Palo Alto Research Center, Incorporated (PARC) + * Andy Clement * ******************************************************************/ package org.aspectj.ajdt.internal.core.builder; -//import java.util.HashMap; import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -26,29 +25,27 @@ import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryType; -import org.aspectj.org.eclipse.jdt.internal.compiler.env.INameEnvironment; +import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule; +import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModuleAwareNameEnvironment; import org.aspectj.org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; import org.aspectj.util.FileUtil; -public class StatefulNameEnvironment implements INameEnvironment { - private Map classesFromName; - private Map inflatedClassFilesCache; - private Set packageNames; +public class StatefulNameEnvironment implements IModuleAwareNameEnvironment { + private Map<String,File> classesFromName; + private Map<String,NameEnvironmentAnswer> inflatedClassFilesCache; + private Set<String> packageNames; private AjState state; - private INameEnvironment baseEnvironment; + private IModuleAwareNameEnvironment baseEnvironment; - public StatefulNameEnvironment(INameEnvironment baseEnvironment, Map classesFromName, AjState state) { + public StatefulNameEnvironment(IModuleAwareNameEnvironment baseEnvironment, Map<String,File> classesFromName, AjState state) { this.classesFromName = classesFromName; - this.inflatedClassFilesCache = new HashMap(); + this.inflatedClassFilesCache = new HashMap<String,NameEnvironmentAnswer>(); this.baseEnvironment = baseEnvironment; this.state = state; - - packageNames = new HashSet(); - for (Iterator i = classesFromName.keySet().iterator(); i.hasNext();) { - String className = (String) i.next(); + packageNames = new HashSet<String>(); + for (String className: classesFromName.keySet()) { addAllPackageNames(className); } - // System.err.println(packageNames); } private void addAllPackageNames(String className) { @@ -59,12 +56,6 @@ public class StatefulNameEnvironment implements INameEnvironment { } } - public void cleanup() { - baseEnvironment.cleanup(); - this.classesFromName = Collections.EMPTY_MAP; - this.packageNames.clear();// = Collections.EMPTY_SET; - } - private NameEnvironmentAnswer findType(String name) { // pr133532 - ask the state for the type first IBinaryType seenOnPreviousBuild = state.checkPreviousBuild(name); @@ -76,10 +67,9 @@ public class StatefulNameEnvironment implements INameEnvironment { } else { File fileOnDisk = (File) classesFromName.get(name); // System.err.println("find: " + name + " found: " + cf); - - if (fileOnDisk == null) + if (fileOnDisk == null) { return null; - + } try { // System.out.println("from cache: " + name); byte[] bytes = FileUtil.readAsByteArray(fileOnDisk); @@ -95,24 +85,36 @@ public class StatefulNameEnvironment implements INameEnvironment { } } + @Override + public void cleanup() { + baseEnvironment.cleanup(); + this.classesFromName = Collections.emptyMap(); + this.packageNames.clear(); + } + + @Override public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) { NameEnvironmentAnswer ret = findType(new String(CharOperation.concatWith(packageName, typeName, '.'))); - if (ret != null) + if (ret != null) { return ret; + } return baseEnvironment.findType(typeName, packageName); } + @Override public NameEnvironmentAnswer findType(char[][] compoundName) { NameEnvironmentAnswer ret = findType(new String(CharOperation.concatWith(compoundName, '.'))); - if (ret != null) + if (ret != null) { return ret; + } return baseEnvironment.findType(compoundName); } + @Override public boolean isPackage(char[][] parentPackageName, char[] packageName) { - if (baseEnvironment.isPackage(parentPackageName, packageName)) + if (baseEnvironment.isPackage(parentPackageName, packageName)) { return true; - + } String fullPackageName = new String(CharOperation.concatWith(parentPackageName, packageName, '.')); return packageNames.contains(fullPackageName); } @@ -121,12 +123,41 @@ public class StatefulNameEnvironment implements INameEnvironment { * Needs to be told about changes. The 'added' set is a subset of classNameToFileMap consisting of just those names added during * this build - to reduce any impact on incremental compilation times. */ - public void update(Map classNameToFileMap, Set added) { - for (Iterator i = added.iterator(); i.hasNext();) { - String className = (String) i.next(); + public void update(Map<String,File> classNameToFileMap, Set<String> added) { + for (String className: added) { addAllPackageNames(className); } this.classesFromName = classNameToFileMap; } + @Override + public NameEnvironmentAnswer findType(char[][] compoundName, char[] moduleName) { + return baseEnvironment.findType(compoundName, moduleName); + } + + @Override + public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, char[] moduleName) { + return baseEnvironment.findType(typeName, packageName, moduleName); + } + + @Override + public char[][] getModulesDeclaringPackage(char[][] parentPackageName, char[] name, char[] moduleName) { + return baseEnvironment.getModulesDeclaringPackage(parentPackageName, name, moduleName); + } + + @Override + public boolean hasCompilationUnit(char[][] qualifiedPackageName, char[] moduleName, boolean checkCUs) { + return baseEnvironment.hasCompilationUnit(qualifiedPackageName, moduleName, checkCUs); + } + + @Override + public IModule getModule(char[] moduleName) { + return baseEnvironment.getModule(moduleName); + } + + @Override + public char[][] getAllAutomaticModules() { + return baseEnvironment.getAllAutomaticModules(); + } + } diff --git a/org.aspectj.ajdt.core/testdata/src1/LazyTjp.aj b/org.aspectj.ajdt.core/testdata/src1/LazyTjp.aj index f3662738c..02226a8af 100644 --- a/org.aspectj.ajdt.core/testdata/src1/LazyTjp.aj +++ b/org.aspectj.ajdt.core/testdata/src1/LazyTjp.aj @@ -3,7 +3,7 @@ public class LazyTjp { private static final int N = 10000000;
// if lazy tjp is working, then calling the advice that uses thisJoinPoint should
// take at least this much longer than using an if pcd to bypass the advice
- private static final double minimumRatio = 8.0;
+ private static final double minimumRatio = 1.8; // was 8 but jvm seems to be improving all the time!!
public static void main(String[] args) {
Trace.enabled = false;
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BasicCommandTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BasicCommandTestCase.java index 7a8bfa48f..62b1ef67e 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BasicCommandTestCase.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BasicCommandTestCase.java @@ -22,6 +22,7 @@ import org.aspectj.ajdt.ajc.AjdtCommand; import org.aspectj.bridge.ICommand; //import org.aspectj.bridge.IMessage; import org.aspectj.bridge.MessageHandler; +import org.aspectj.util.LangUtil; /** * @author hugunin @@ -71,6 +72,7 @@ public class BasicCommandTestCase extends CommandTestCase { public void testThisAndModifiers() { checkCompile("src1/ThisAndModifiers.java", NO_ERRORS); } + public void testDeclares() { checkCompile("src1/Declares.java", new int[] {2}); } @@ -92,20 +94,23 @@ public class BasicCommandTestCase extends CommandTestCase { checkCompile("src1/Xlint.java", NO_ERRORS); } public void testXlintError() { - List args = new ArrayList(); + List<String> args = new ArrayList<>(); args.add("-d"); args.add(getSandboxName()); args.add("-classpath"); - args.add(getRuntimeClasspath() + File.pathSeparator +
"../lib/junit/junit.jar;../testing-client/bin"); + StringBuilder classpath = new StringBuilder(); + classpath.append(getRuntimeClasspath()); + classpath.append(File.pathSeparator).append("../lib/junit/junit.jar;../testing-client/bin"); + args.add(classpath.toString()); args.add("-Xlint:error"); args.add(AjdtAjcTests.TESTDATA_PATH + "/src1/Xlint.java"); runCompiler(args, new int[] {2}); } public void testMissingJarError() { - List args = new ArrayList(); + List<String> args = new ArrayList<>(); args.add("-d"); args.add(getSandboxName()); @@ -125,7 +130,7 @@ public class BasicCommandTestCase extends CommandTestCase { } public void testMissingRuntimeError() { - List args = new ArrayList(); + List<String> args = new ArrayList<>(); args.add("-d"); args.add(getSandboxName()); @@ -176,7 +181,7 @@ public class BasicCommandTestCase extends CommandTestCase { public void testSizeChanges() { File f1 = new File(getSandboxName(),"SizeIssues.class"); - List args = new ArrayList(); + List<String> args = new ArrayList<>(); args.add("-d"); args.add(getSandboxName()); diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java index 9d4cc3cec..83513071a 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java @@ -170,7 +170,7 @@ public class BcweaverJarMaker { CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS); - args = new ArrayList(); + args = new ArrayList<>(); args.add("-classpath"); args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar" + @@ -183,7 +183,7 @@ public class BcweaverJarMaker { CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS); // For PR55341 - args = new ArrayList(); + args = new ArrayList<>(); args.add("-classpath"); args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar" + File.pathSeparator + System.getProperty("aspectjrt.path")); @@ -213,7 +213,7 @@ public class BcweaverJarMaker { /* * Woven classes */ - args = new ArrayList(); + args = new ArrayList<>(); args.add("-classpath"); args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar;../weaver/testdata/ltw-classes.jar" + File.pathSeparator + System.getProperty("aspectjrt.path")); @@ -227,7 +227,7 @@ public class BcweaverJarMaker { /* * Advice */ - args = new ArrayList(); + args = new ArrayList<>(); args.add("-classpath"); args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar;../weaver/testdata/ltw-classes.jar" + File.pathSeparator + System.getProperty("aspectjrt.path")); @@ -239,7 +239,7 @@ public class BcweaverJarMaker { /* * Declare warning advice */ - args = new ArrayList(); + args = new ArrayList<>(); args.add("-classpath"); args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar;../weaver/testdata/ltw-classes.jar" + File.pathSeparator + System.getProperty("aspectjrt.path")); @@ -263,7 +263,7 @@ public class BcweaverJarMaker { /* * Around closure advice */ - args = new ArrayList(); + args = new ArrayList<>(); args.add("-classpath"); args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar;../weaver/testdata/ltw-classes.jar" + File.pathSeparator + System.getProperty("aspectjrt.path")); @@ -373,7 +373,6 @@ public class BcweaverJarMaker { public static void makeAjc11TestJars() throws IOException { List<String> args = new ArrayList<>(); - args.clear(); args.add("-classpath"); args.add(cp); @@ -386,9 +385,7 @@ public class BcweaverJarMaker { public static void makeOutjarTestJars() throws IOException { List<String> args = new ArrayList<>(); - /* - * parent - */ + // parent args.clear(); args.add("-classpath"); args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar" + diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java index d43a3f340..7da775d70 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java @@ -48,7 +48,7 @@ public class BinaryFormsTestCase extends CommandTestCase { CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS); - args = new ArrayList(); + args = new ArrayList<>(); args.add("-aspectpath"); args.add(library); diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java index a586f8c7d..23e589080 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java @@ -31,6 +31,7 @@ import org.aspectj.bridge.MessageHandler; import org.aspectj.testing.util.TestUtil; import org.aspectj.tools.ajc.Ajc; import org.aspectj.tools.ajc.AjcTests; +import org.aspectj.util.LangUtil; import org.aspectj.weaver.bcel.LazyClassGen; public abstract class CommandTestCase extends TestCase { @@ -175,7 +176,12 @@ public abstract class CommandTestCase extends TestCase { /** get the location of the org.aspectj.lang & runtime classes */ protected static String getRuntimeClasspath() { - return AjcTests.aspectjrtClasspath(); + StringBuilder classpath = new StringBuilder(); + if (LangUtil.is19VMOrGreater()) { + classpath.append(LangUtil.getJrtFsFilePath()).append(File.pathSeparator); + } + classpath.append(AjcTests.aspectjrtClasspath()); + return classpath.toString(); } protected String getSandboxName() { diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java index 3799b4cda..c4be26936 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java @@ -57,10 +57,10 @@ public class AjBuildManagerTest extends TestCase { } public void testSimpleStructure() throws IOException /* , CoreException */{ - AjBuildManager manager = new AjBuildManager(messageWriter); BuildArgParser parser = new BuildArgParser(messageWriter); String javaClassPath = System.getProperty("java.class.path"); + System.out.println(javaClassPath); String sandboxName = Ajc.createEmptySandbox().getAbsolutePath(); AjBuildConfig buildConfig = parser.genBuildConfig(new String[] { "-d", sandboxName, "-classpath", javaClassPath, AjdtAjcTests.TESTDATA_PATH + "/src1/A.java", diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjCompilerOptionsTest.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjCompilerOptionsTest.java index 1e94e300a..21050fc95 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjCompilerOptionsTest.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjCompilerOptionsTest.java @@ -18,18 +18,13 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import junit.framework.TestCase; /** - * @author colyer - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Generation - Code and Comments + * @author Adrian Colyer + * @uahtor Andy Clement */ public class AjCompilerOptionsTest extends TestCase { private AjCompilerOptions options; - /* - * @see TestCase#setUp() - */ protected void setUp() throws Exception { super.setUp(); options = new AjCompilerOptions(); @@ -48,7 +43,7 @@ public class AjCompilerOptionsTest extends TestCase { Map<String,String> map = options.getMap(); assertEquals(CompilerOptions.WARNING,map.get(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName)); - assertEquals(CompilerOptions.WARNING,map.get(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName)); + assertEquals(CompilerOptions.IGNORE,map.get(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName)); assertEquals(CompilerOptions.WARNING,map.get(AjCompilerOptions.OPTION_ReportUnresolvableMember)); assertEquals(CompilerOptions.WARNING,map.get(AjCompilerOptions.OPTION_ReportTypeNotExposedToWeaver)); assertEquals(CompilerOptions.IGNORE,map.get(AjCompilerOptions.OPTION_ReportShadowNotInStructure)); @@ -69,7 +64,7 @@ public class AjCompilerOptionsTest extends TestCase { options.generateEmacsSymFiles = true; options.noAtAspectJProcessing = true; - Map map = options.getMap(); + Map<String,String> map = options.getMap(); assertEquals(CompilerOptions.ENABLED,map.get(AjCompilerOptions.OPTION_TerminateAfterCompilation)); assertEquals(CompilerOptions.ENABLED,map.get(AjCompilerOptions.OPTION_XSerializableAspects)); assertEquals(CompilerOptions.ENABLED,map.get(AjCompilerOptions.OPTION_XLazyThisJoinPoint)); @@ -83,7 +78,7 @@ public class AjCompilerOptionsTest extends TestCase { public void testMapSet() { - Map map = new HashMap(); + Map<String,String> map = new HashMap<>(); map.put(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName,CompilerOptions.ERROR); map.put(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName,CompilerOptions.ERROR); map.put(AjCompilerOptions.OPTION_ReportUnresolvableMember,CompilerOptions.IGNORE); @@ -116,8 +111,7 @@ public class AjCompilerOptionsTest extends TestCase { assertTrue(options.generateEmacsSymFiles); assertTrue(options.noAtAspectJProcessing); - Map newMap = options.getMap(); - + Map<String,String> newMap = options.getMap(); assertEquals(CompilerOptions.ERROR,newMap.get(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName)); assertEquals(CompilerOptions.ERROR,newMap.get(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName)); assertEquals(CompilerOptions.IGNORE,newMap.get(AjCompilerOptions.OPTION_ReportUnresolvableMember)); @@ -129,9 +123,6 @@ public class AjCompilerOptionsTest extends TestCase { assertEquals(CompilerOptions.ERROR,newMap.get(AjCompilerOptions.OPTION_ReportIncompatibleSerialVersion)); } - /* - * Class to test for String toString() - */ public void testToString() { String s = options.toString(); assertTrue("Should have info on AspectJ options",s.indexOf("AspectJ Specific Options:") > 0); diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjStateTest.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjStateTest.java index 1693178e3..101fdade1 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjStateTest.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjStateTest.java @@ -48,44 +48,48 @@ public class AjStateTest extends TestCase { } public void testAddEntryToAspectpath() { - newConfig.getAspectpath().add(new File("anotherEntry.jar")); + newConfig.addToAspectpath(new File("anotherEntry.jar")); +// newConfig.getAspectpath().add(new File("anotherEntry.jar")); assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig)); } public void testRemoveEntryFromAspectpath() { - newConfig.getAspectpath().remove(0); + newConfig.removeAspectPathEntry(0); assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig)); } public void testReorderAspectpath() { - String o = newConfig.getClasspath().remove(0); - newConfig.getAspectpath().add(new File(o)); + String o = newConfig.removeClasspathEntry(0); + newConfig.addToAspectpath(new File(o)); +// newConfig.getAspectpath().add(new File(o)); assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig)); } public void testAddEntryToInpath() { - newConfig.getInpath().add(new File("anotherEntry")); + newConfig.addToInpath(new File("anotherEntry")); assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig)); } public void testRemoveEntryFromInpath() { - newConfig.getInpath().remove(0); + newConfig.removeInpathEntry(0);//getInpath().remove(0); assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig)); } public void testReorderInpath() { - String o = newConfig.getClasspath().remove(0); - newConfig.getInpath().add(new File(o)); + String o = newConfig.removeClasspathEntry(0);//getClasspath().remove(0); + newConfig.addToInpath(new File(o));//getInpath().add(new File(o)); assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig)); } public void testAddEntryToInjars() { - newConfig.getInJars().add(new File("anotherEntry.jar")); + newConfig.addToInjars(new File("anotherEntry.jar")); +// newConfig.getInJars().add(new File("anotherEntry.jar")); assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig)); } public void testRemoveEntryFromInjars() { - newConfig.getInJars().remove(0); + newConfig.removeInjarsEntry(0); +// newConfig.getInJars().remove(0); assertFalse("Can do incremental", aRightState.prepareForNextBuild(newConfig)); } diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/Ajc.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/Ajc.java index 53b89e3d8..eeb6136a5 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/Ajc.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/Ajc.java @@ -366,14 +366,14 @@ public class Ajc { if (FileUtil.hasSourceSuffix(args[i])) { File f = new File(args[i]); // newArgs[i] = new File(baseDir,args[i]).getAbsolutePath(); // might be quicker? - newArgs[i] = adjustFileOrDir(f, doCopy).getAbsolutePath(); + newArgs[i] = adjustFileOrDir(f, doCopy, false).getAbsolutePath(); } else if (args[i].endsWith(".xml") && !args[i].startsWith("-")) { if (i > 0 && args[i - 1].equals("-outxmlfile")) { // dont adjust it } else { File f = new File(args[i]); // newArgs[i] = new File(baseDir,args[i]).getAbsolutePath(); // might be quicker? - newArgs[i] = adjustFileOrDir(f, doCopy).getAbsolutePath(); + newArgs[i] = adjustFileOrDir(f, doCopy, false).getAbsolutePath(); } } else { if ((args[i].equals("-aspectpath") || args[i].equals("-inpath") || args[i].equals("-injars") @@ -387,10 +387,11 @@ public class Ajc { copyThisTime = false; hasOutdir = true; } + boolean isOutjar = args[i].equals("-outjar"); StringTokenizer strTok = new StringTokenizer(args[++i], File.pathSeparator); while (strTok.hasMoreTokens()) { File f = new File(strTok.nextToken()); - buff.append(adjustFileOrDir(f, copyThisTime).getAbsolutePath()); + buff.append(adjustFileOrDir(f, copyThisTime, isOutjar).getAbsolutePath()); if (strTok.hasMoreTokens()) buff.append(File.pathSeparator); } @@ -404,7 +405,7 @@ public class Ajc { // could be resource file File f = new File(args[i]); if (f.exists()) { - newArgs[i] = adjustFileOrDir(f, doCopy).getAbsolutePath(); + newArgs[i] = adjustFileOrDir(f, doCopy, false).getAbsolutePath(); } } } @@ -426,7 +427,7 @@ public class Ajc { return newArgs; } - private File adjustFileOrDir(File from, boolean doCopy) throws IOException { + private File adjustFileOrDir(File from, boolean doCopy, boolean ensureDirsExist) throws IOException { File to = from; File ret = from; if (!from.isAbsolute()) { @@ -435,6 +436,10 @@ public class Ajc { String relativeToPath = (fromParent != null) ? (fromParent.getPath() + File.separator) : ""; if (baseDir != null) { from = new File(baseDir, from.getPath()); +// if (ensureDirsExist) { +// File toMkdir = (ret.getPath().endsWith(".jar") || ret.getPath().endsWith(".zip"))?ret.getParentFile():ret; +// toMkdir.mkdirs(); +// } } if (!from.exists()) return ret; diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/AjcTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/AjcTestCase.java index 5954c40b4..b665afeba 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/AjcTestCase.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/AjcTestCase.java @@ -35,6 +35,7 @@ import junit.framework.TestCase; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; import org.aspectj.testing.util.TestUtil; +import org.aspectj.util.LangUtil; /** * A TestCase class that acts as the superclass for all test cases wishing to drive the ajc compiler. @@ -89,6 +90,8 @@ public class AjcTestCase extends TestCase { + "bcel" + File.separator + "bcel-verifier.jar" + + + File.pathSeparator + ".." + File.separator + "lib" + File.separator + "asm" + File.separator + "asm-6.0_BETA.renamed.jar" // When the build machine executes the tests, it is using code built into jars rather than code build into // bin directories. This means for the necessary types to be found we have to put these jars on the classpath: @@ -107,7 +110,6 @@ public class AjcTestCase extends TestCase { public static final String JAVA5_CLASSPATH_ENTRIES = File.pathSeparator + ".." + File.separator + "aspectj5rt" + File.separator + "bin" + File.pathSeparator + ".." + File.separator + "loadtime5" + File.separator + "bin" + File.pathSeparator + ".." + File.separator + "weaver5" + File.separator + "bin" - + File.pathSeparator + ".." + File.separator + "aj-build" + File.separator + "jars" + File.separator + "aspectj5rt.jar" + File.pathSeparator + ".." + File.separator + "aj-build" + File.separator + "jars" + File.separator + "loadtime5.jar" + File.pathSeparator + ".." + File.separator + "aj-build" + File.separator + "jars" + File.separator + "weaver5.jar"; @@ -579,7 +581,7 @@ public class AjcTestCase extends TestCase { } public RunResult run(String className, String[] args, String classpath) { - return run(className, args, "", null, false,false); + return run(className, null, args, "", "", null, false,false); } /** @@ -591,7 +593,7 @@ public class AjcTestCase extends TestCase { * be appended to the classpath, as will any jars in the sandbox. * @param runSpec */ - public RunResult run(String className, String[] args, String vmargs, final String classpath, boolean useLTW, boolean useFullLTW) { + public RunResult run(String className, String moduleName, String[] args, String vmargs, final String classpath, String modulepath, boolean useLTW, boolean useFullLTW) { if (args != null) { for (int i = 0; i < args.length; i++) { @@ -605,22 +607,29 @@ public class AjcTestCase extends TestCase { cp.append(substituteSandbox(classpath)); cp.append(File.pathSeparator); } - cp.append(ajc.getSandboxDirectory().getAbsolutePath()); - getAnyJars(ajc.getSandboxDirectory(), cp); + if (moduleName == null) { + // When running modules, we want more control so don't try to be helpful by adding all jars + cp.append(ajc.getSandboxDirectory().getAbsolutePath()); + getAnyJars(ajc.getSandboxDirectory(), cp); + } + StringBuffer mp = new StringBuffer(); + if (modulepath != null) { + mp.append(substituteSandbox(modulepath)); + mp.append(File.pathSeparator); + } URLClassLoader sandboxLoader; - URLClassLoader testLoader = (URLClassLoader) getClass().getClassLoader(); - ClassLoader parentLoader = testLoader.getParent(); - - + ClassLoader parentLoader = getClass().getClassLoader().getParent(); /* Sandbox -> AspectJ -> Extension -> Bootstrap */ if ( !useFullLTW && useLTW) { +// URLClassLoader testLoader = (URLClassLoader) getClass().getClassLoader(); /* * Create a new AspectJ class loader using the existing test CLASSPATH and any missing Java 5 projects */ - URL[] testUrls = testLoader.getURLs(); - URL[] java5Urls = getURLs(JAVA5_CLASSPATH_ENTRIES); + URL[] testUrls = new URL[0];//testLoader.getURLs(); + // What are the URLs on java 8? + URL[] java5Urls = getURLs(DEFAULT_CLASSPATH_ENTRIES);//getURLs(JAVA5_CLASSPATH_ENTRIES); URL[] urls = new URL[testUrls.length + java5Urls.length]; System.arraycopy(testUrls, 0, urls, 0, testUrls.length); System.arraycopy(java5Urls, 0, urls, testUrls.length, java5Urls.length); @@ -629,7 +638,7 @@ public class AjcTestCase extends TestCase { URL[] sandboxUrls = getURLs(cp.toString()); sandboxLoader = createWeavingClassLoader(sandboxUrls, aspectjLoader); // sandboxLoader = createWeavingClassLoader(sandboxUrls,testLoader); - }else if(useFullLTW && useLTW) { + } else if(useFullLTW && useLTW) { if(vmargs == null){ vmargs =""; } @@ -638,7 +647,6 @@ public class AjcTestCase extends TestCase { String absPath = directory.getAbsolutePath(); String javaagent= absPath+File.separator+".."+File.separator+"aj-build"+File.separator+"dist"+File.separator+"tools"+File.separator+"lib"+File.separator+"aspectjweaver.jar"; try { - String command ="java " +vmargs+ " -classpath " + cp +" -javaagent:"+javaagent + " " + className ; // Command is executed using ProcessBuilder to allow setting CWD for ajc sandbox compliance @@ -653,10 +661,35 @@ public class AjcTestCase extends TestCase { System.out.println("Error executing full LTW test: " + e); e.printStackTrace(); } - return lastRunResult; - - }else{ + } else if (moduleName != null) { + // CODE FOR RUNNING MODULES + if(vmargs == null){ + vmargs =""; + } + try { + if (mp.indexOf("$runtime") != -1) { + mp = mp.replace(mp.indexOf("$runtime"),"$runtime".length(),TestUtil.aspectjrtPath().toString()); + } + if (cp.indexOf("aspectjrt")==-1) { + cp.append(TestUtil.aspectjrtPath().getPath()).append(File.pathSeparator); + } + String command = LangUtil.getJavaExecutable().getAbsolutePath() + " " +vmargs+ (cp.length()==0?"":" -classpath " + cp) + " -p "+mp+" --module "+moduleName ; + System.out.println("Command is "+command); + // Command is executed using ProcessBuilder to allow setting CWD for ajc sandbox compliance + ProcessBuilder pb = new ProcessBuilder(tokenizeCommand(command)); + pb.directory( new File(ajc.getSandboxDirectory().getAbsolutePath())); + exec = pb.start(); + BufferedReader stdInput = new BufferedReader(new InputStreamReader(exec.getInputStream())); + BufferedReader stdError = new BufferedReader(new InputStreamReader(exec.getErrorStream())); + exec.waitFor(); + lastRunResult = createResultFromBufferReaders(command,stdInput, stdError); + } catch (Exception e) { + System.out.println("Error executing module test: " + e); + e.printStackTrace(); + } + return lastRunResult; + } else { cp.append(DEFAULT_CLASSPATH_ENTRIES); URL[] urls = getURLs(cp.toString()); sandboxLoader = new URLClassLoader(urls, parentLoader); @@ -665,7 +698,8 @@ public class AjcTestCase extends TestCase { ByteArrayOutputStream baosErr = new ByteArrayOutputStream(); - StringBuffer command = new StringBuffer("java -classpath "); + StringBuffer command = new StringBuffer(); + command.append("java -classpath "); command.append(cp.toString()); command.append(" "); command.append(className); @@ -833,15 +867,15 @@ public class AjcTestCase extends TestCase { return urls; } - private String substituteSandbox(String classpath) { - // the longhand form of the non 1.3 API: classpath.replace("$sandbox", ajc.getSandboxDirectory().getAbsolutePath()); - while (classpath.indexOf("$sandbox") != -1) { - int pos = classpath.indexOf("$sandbox"); - String firstbit = classpath.substring(0, pos); - String endbit = classpath.substring(pos + 8); - classpath = firstbit + ajc.getSandboxDirectory().getAbsolutePath() + endbit; + private String substituteSandbox(String path) { + // the longhand form of the non 1.3 API: path.replace("$sandbox", ajc.getSandboxDirectory().getAbsolutePath()); + while (path.indexOf("$sandbox") != -1) { + int pos = path.indexOf("$sandbox"); + String firstbit = path.substring(0, pos); + String endbit = path.substring(pos + 8); + path = firstbit + ajc.getSandboxDirectory().getAbsolutePath() + endbit; } - return classpath; + return path; } /** @@ -850,38 +884,48 @@ public class AjcTestCase extends TestCase { * @param args the String[] args to fix up * @return the String[] args to use */ - protected String[] fixupArgs(String[] args) { - if (null == args) { - return null; - } - int cpIndex = -1; - boolean hasruntime = false; - for (int i = 0; i < args.length - 1; i++) { - args[i] = adaptToPlatform(args[i]); - if ("-classpath".equals(args[i])) { - cpIndex = i; - args[i + 1] = substituteSandbox(args[i + 1]); - String next = args[i + 1]; - hasruntime = ((null != next) && (-1 != next.indexOf("aspectjrt.jar"))); - } - } - if (-1 == cpIndex) { - String[] newargs = new String[args.length + 2]; - newargs[0] = "-classpath"; - newargs[1] = TestUtil.aspectjrtPath().getPath(); - System.arraycopy(args, 0, newargs, 2, args.length); - args = newargs; - } else { - if (!hasruntime) { - cpIndex++; - String[] newargs = new String[args.length]; - System.arraycopy(args, 0, newargs, 0, args.length); - newargs[cpIndex] = args[cpIndex] + File.pathSeparator + TestUtil.aspectjrtPath().getPath(); - args = newargs; - } - } - return args; - } + protected String[] fixupArgs(String[] args) { + if (null == args) { + return null; + } + int cpIndex = -1; + boolean hasruntime = false; + for (int i = 0; i < args.length - 1; i++) { + args[i] = adaptToPlatform(args[i]); + if ("-classpath".equals(args[i])) { + cpIndex = i; + args[i + 1] = substituteSandbox(args[i + 1]); + String next = args[i + 1]; + hasruntime = ((null != next) && (-1 != next.indexOf("aspectjrt.jar"))); + } else if ("-p".equals(args[i]) || "--module-path".equals(args[i])) { + args[i + 1] = substituteSandbox(args[i + 1]); + } + } + if (-1 == cpIndex) { + String[] newargs = new String[args.length + 2]; + newargs[0] = "-classpath"; + newargs[1] = TestUtil.aspectjrtPath().getPath(); + System.arraycopy(args, 0, newargs, 2, args.length); + args = newargs; + cpIndex = 1; + } else { + if (!hasruntime) { + cpIndex++; + String[] newargs = new String[args.length]; + System.arraycopy(args, 0, newargs, 0, args.length); + newargs[cpIndex] = args[cpIndex] + File.pathSeparator + TestUtil.aspectjrtPath().getPath(); + args = newargs; + } + } + boolean needsJRTFS = LangUtil.is19VMOrGreater(); + if (needsJRTFS) { + if (args[cpIndex].indexOf(LangUtil.JRT_FS) == -1) { + String jrtfsPath = LangUtil.getJrtFsFilePath(); + args[cpIndex] = jrtfsPath + File.pathSeparator + args[cpIndex]; + } + } + return args; +} private String adaptToPlatform(String s) { String ret = s.replace(';', File.pathSeparatorChar); diff --git a/org.aspectj.matcher/org.aspectj.matcher.mf.txt b/org.aspectj.matcher/org.aspectj.matcher.mf.txt index f3fe07179..ae8d8d8d0 100644 --- a/org.aspectj.matcher/org.aspectj.matcher.mf.txt +++ b/org.aspectj.matcher/org.aspectj.matcher.mf.txt @@ -1,4 +1,5 @@ Manifest-Version: 1.0 +Automatic-Module-Name: org.aspectj.matcher Name: org/aspectj/matcher/ Specification-Title: AspectJ Matcher Classes diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/AjcMemberMaker.java b/org.aspectj.matcher/src/org/aspectj/weaver/AjcMemberMaker.java index 62459bdb8..1870eb501 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/AjcMemberMaker.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/AjcMemberMaker.java @@ -74,7 +74,7 @@ public class AjcMemberMaker { } public static ResolvedMember perSingletonField(UnresolvedType declaringType) { - return new ResolvedMemberImpl(Member.FIELD, declaringType, PUBLIC_STATIC_FINAL, NameMangler.PERSINGLETON_FIELD_NAME, + return new ResolvedMemberImpl(Member.FIELD, declaringType, PUBLIC_STATIC, NameMangler.PERSINGLETON_FIELD_NAME, declaringType.getSignature()); } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/Lint.java b/org.aspectj.matcher/src/org/aspectj/weaver/Lint.java index 36d647512..aab34b8f6 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/Lint.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/Lint.java @@ -114,7 +114,7 @@ public class Lint { "calculated SerialVersionUID for type {0} to be {1}"); public final Kind nonReweavableTypeEncountered = new Kind("nonReweavableTypeEncountered", - "class '{0}' is already woven and has not been built in reweavable mode"); + "class {0} is already woven and has not been built in reweavable mode"); // there are a lot of messages in the cant find type family - I'm defining an umbrella lint warning that // allows a user to control their severity (for e.g. ltw or binary weaving) diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java b/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java index 65fdf3a95..7dc162a16 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java @@ -376,10 +376,16 @@ public class ReferenceType extends ResolvedType { if (this.isFinal() || other.isFinal()) { return false; } + + // 20170927: What is the block of code for? It mentions jls5.5 which isn't on this topic (old version of jls?) + // Some possible references: http://docs.oracle.com/javase/specs/jls/se9/jls9.pdf 5.1.6 (narrowing reference conversion) + // On Java 9 the test GenericsTests.testAfterReturningWithWildcardVar will fail because this code below + // used to find Set and List were the same, but now finds they are not. (so it doesn't put out the unchecked + // conversion message). However the code "List l = (List)someSet;" still compiles on 9 - so is this code bogus? + // ??? needs to be Methods, not just declared methods? JLS 5.5 unclear ResolvedMember[] a = getDeclaredMethods(); - ResolvedMember[] b = other.getDeclaredMethods(); // ??? is this cast - // always safe + ResolvedMember[] b = other.getDeclaredMethods(); for (int ai = 0, alen = a.length; ai < alen; ai++) { for (int bi = 0, blen = b.length; bi < blen; bi++) { if (!b[bi].isCompatibleWith(a[ai])) { diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java index 5985e4b6d..daccec105 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java @@ -966,12 +966,38 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } TypeVariable[] tvs = getGenericType().getTypeVariables(); Map<String, UnresolvedType> parameterizationMap = new HashMap<String, UnresolvedType>(); - for (int i = 0; i < tvs.length; i++) { - parameterizationMap.put(tvs[i].getName(), typeParameters[i]); + if (tvs.length != typeParameters.length) { + world.getMessageHandler() + .handleMessage( + new Message("Mismatch when building parameterization map. For type '" + this.signature + + "' expecting "+tvs.length+":["+toString(tvs)+"] type parameters but found "+typeParameters.length+ + ":["+toString(typeParameters)+"]", "", + IMessage.ERROR, getSourceLocation(), null, + new ISourceLocation[] { getSourceLocation() })); + } else { + for (int i = 0; i < tvs.length; i++) { + parameterizationMap.put(tvs[i].getName(), typeParameters[i]); + } } return parameterizationMap; } + private String toString(UnresolvedType[] typeParameters) { + StringBuilder s = new StringBuilder(); + for (UnresolvedType tv: typeParameters) { + s.append(tv.getSignature()).append(" "); + } + return s.toString().trim(); + } + + private String toString(TypeVariable[] tvs) { + StringBuilder s = new StringBuilder(); + for (TypeVariable tv: tvs) { + s.append(tv.getName()).append(" "); + } + return s.toString().trim(); + } + public List<ShadowMunger> getDeclaredAdvice() { List<ShadowMunger> l = new ArrayList<ShadowMunger>(); ResolvedMember[] methods = getDeclaredMethods(); diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/World.java b/org.aspectj.matcher/src/org/aspectj/weaver/World.java index 6bba2d551..19d61f5be 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/World.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/World.java @@ -462,6 +462,9 @@ public abstract class World implements Dump.INode { } else if (ty.isGenericType()) { // ======= generic types ====================== ResolvedType rt = resolveGenericTypeFor(ty, false); + if (rt.isMissing()) { + return rt; + } ReferenceType genericType = (ReferenceType) rt; if (rt.isMissing()) { return rt; diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java index 6aa55a45a..2b1f28fd4 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java @@ -87,11 +87,18 @@ public class HasMemberTypePattern extends TypePattern { continue; } if (signaturePattern.matches(method, type.getWorld(), false)) { - if (method.getDeclaringType().resolve(world) != type) { + ResolvedType declaringType = method.getDeclaringType().resolve(world); + if (declaringType != type) { if (Modifier.isPrivate(method.getModifiers())) { continue; } } + // J9: Object.finalize() is marked Deprecated it seems... triggers unhelpful messages + if (method.getName().equals("finalize") && declaringType.equals(ResolvedType.OBJECT) + && (signaturePattern.getAnnotationPattern() instanceof ExactAnnotationTypePattern) + && ((ExactAnnotationTypePattern)signaturePattern.getAnnotationPattern()).getAnnotationType().getSignature().equals("Ljava/lang/Deprecated;")) { + continue; + } return true; } } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/AnnotationFinder.java b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/AnnotationFinder.java index 7efeac9ae..90ce368d9 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/AnnotationFinder.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/AnnotationFinder.java @@ -1,18 +1,16 @@ /* ******************************************************************* - * Copyright (c) 2005 Contributors. + * Copyright (c) 2005, 2017 Contributors. + * * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://eclipse.org/legal/epl-v10.html * - * Contributors: - * Adrian Colyer Initial implementation * ******************************************************************/ package org.aspectj.weaver.reflect; import java.lang.reflect.Member; -import java.util.Set; import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.ResolvedType; @@ -20,7 +18,8 @@ import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.World; /** - * @author colyer Used in 1.4 code to access annotations safely + * @author Adrian Colyer + * @author Andy Clement */ public interface AnnotationFinder { @@ -32,14 +31,13 @@ public interface AnnotationFinder { Object getAnnotationFromMember(ResolvedType annotationType, Member aMember); - public AnnotationAJ getAnnotationOfType(UnresolvedType ofType, - Member onMember); + public AnnotationAJ getAnnotationOfType(UnresolvedType ofType, Member onMember); public String getAnnotationDefaultValue(Member onMember); - Object getAnnotationFromClass(ResolvedType annotationType, Class aClass); + Object getAnnotationFromClass(ResolvedType annotationType, Class<?> aClass); - Set/* ResolvedType */getAnnotations(Member onMember); + ResolvedType[] getAnnotations(Member onMember, boolean runtimeAnnotationsOnly); ResolvedType[][] getParameterAnnotationTypes(Member onMember); } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java index 28c8aacf6..ba8f1330e 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java @@ -1,18 +1,15 @@ /* ******************************************************************* - * Copyright (c) 2005 Contributors. + * Copyright (c) 2005, 2017 Contributors. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://eclipse.org/legal/epl-v10.html * - * Contributors: - * Adrian Colyer Initial implementation * ******************************************************************/ package org.aspectj.weaver.reflect; import java.lang.reflect.Member; -import java.util.Set; import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.MemberKind; @@ -24,37 +21,29 @@ import org.aspectj.weaver.UnresolvedType; /** * Subtype of ResolvedMemberImpl used in reflection world. Knows how to get annotations from a java.lang.reflect.Member * + * @author Adrian Colyer + * @author Andy Clement */ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { private AnnotationFinder annotationFinder = null; private GenericSignatureInformationProvider gsigInfoProvider = new Java14GenericSignatureInformationProvider(); + + /** + * If true then only runtime visible annotations have been resolved via reflection. If class retention + * annotations are also required (later) then the cache will have to be rebuilt using a more detailed + * dig into the class file. + */ + private boolean onlyRuntimeAnnotationsCached; private Member reflectMember; - /** - * @param kind - * @param declaringType - * @param modifiers - * @param returnType - * @param name - * @param parameterTypes - */ public ReflectionBasedResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name, UnresolvedType[] parameterTypes, Member reflectMember) { super(kind, declaringType, modifiers, returnType, name, parameterTypes); this.reflectMember = reflectMember; } - /** - * @param kind - * @param declaringType - * @param modifiers - * @param returnType - * @param name - * @param parameterTypes - * @param checkedExceptions - */ public ReflectionBasedResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name, UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions, Member reflectMember) { @@ -62,16 +51,6 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { this.reflectMember = reflectMember; } - /** - * @param kind - * @param declaringType - * @param modifiers - * @param returnType - * @param name - * @param parameterTypes - * @param checkedExceptions - * @param backingGenericMember - */ public ReflectionBasedResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name, UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions, ResolvedMember backingGenericMember, Member reflectMember) { @@ -79,13 +58,6 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { this.reflectMember = reflectMember; } - /** - * @param kind - * @param declaringType - * @param modifiers - * @param name - * @param signature - */ public ReflectionBasedResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, String name, String signature, Member reflectMember) { super(kind, declaringType, modifiers, name, signature); @@ -96,89 +68,64 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { return this.reflectMember; } - // generic signature support - public void setGenericSignatureInformationProvider(GenericSignatureInformationProvider gsigProvider) { this.gsigInfoProvider = gsigProvider; } - /* - * (non-Javadoc) - * - * @see org.aspectj.weaver.ResolvedMemberImpl#getGenericParameterTypes() - */ @Override public UnresolvedType[] getGenericParameterTypes() { return this.gsigInfoProvider.getGenericParameterTypes(this); } - /* - * (non-Javadoc) - * - * @see org.aspectj.weaver.ResolvedMemberImpl#getGenericReturnType() - */ @Override public UnresolvedType getGenericReturnType() { return this.gsigInfoProvider.getGenericReturnType(this); } - /* - * (non-Javadoc) - * - * @see org.aspectj.weaver.ResolvedMemberImpl#isSynthetic() - */ @Override public boolean isSynthetic() { return this.gsigInfoProvider.isSynthetic(this); } - /* - * (non-Javadoc) - * - * @see org.aspectj.weaver.ResolvedMemberImpl#isVarargsMethod() - */ @Override public boolean isVarargsMethod() { return this.gsigInfoProvider.isVarArgs(this); } - /* - * (non-Javadoc) - * - * @see org.aspectj.weaver.ResolvedMemberImpl#isBridgeMethod() - */ @Override public boolean isBridgeMethod() { return this.gsigInfoProvider.isBridge(this); } - // annotation support - public void setAnnotationFinder(AnnotationFinder finder) { this.annotationFinder = finder; } @Override public boolean hasAnnotation(UnresolvedType ofType) { - unpackAnnotations(); + boolean areRuntimeRetentionAnnotationsSufficient = false; + if (ofType instanceof ResolvedType) { + areRuntimeRetentionAnnotationsSufficient = ((ResolvedType)ofType).isAnnotationWithRuntimeRetention(); + } + unpackAnnotations(areRuntimeRetentionAnnotationsSufficient); return super.hasAnnotation(ofType); } @Override public boolean hasAnnotations() { - unpackAnnotations(); + unpackAnnotations(false); return super.hasAnnotations(); } @Override public ResolvedType[] getAnnotationTypes() { - unpackAnnotations(); + unpackAnnotations(false); return super.getAnnotationTypes(); } @Override public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) { - unpackAnnotations(); + unpackAnnotations(false); if (annotationFinder == null || annotationTypes == null) { return null; } @@ -206,18 +153,10 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { return parameterAnnotationTypes; } - private void unpackAnnotations() { - if (annotationTypes == null && annotationFinder != null) { - Set<?> s = annotationFinder.getAnnotations(reflectMember); - if (s.size() == 0) { - annotationTypes = ResolvedType.EMPTY_ARRAY; - } else { - annotationTypes = new ResolvedType[s.size()]; - int i = 0; - for (Object o : s) { - annotationTypes[i++] = (ResolvedType) o; - } - } + private void unpackAnnotations(boolean areRuntimeRetentionAnnotationsSufficient) { + if (annotationFinder != null && (annotationTypes == null || (!areRuntimeRetentionAnnotationsSufficient && onlyRuntimeAnnotationsCached))) { + annotationTypes = annotationFinder.getAnnotations(reflectMember, areRuntimeRetentionAnnotationsSufficient); + onlyRuntimeAnnotationsCached = areRuntimeRetentionAnnotationsSufficient; } } } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionWorld.java b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionWorld.java index 98e800222..c784ff288 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionWorld.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionWorld.java @@ -1,17 +1,16 @@ /* ******************************************************************* - * Copyright (c) 2005 Contributors. + * Copyright (c) 2005-2017 Contributors. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer Initial implementation * ******************************************************************/ package org.aspectj.weaver.reflect; +import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import org.aspectj.bridge.AbortException; @@ -31,14 +30,55 @@ import org.aspectj.weaver.World; * A ReflectionWorld is used solely for purposes of type resolution based on the runtime classpath (java.lang.reflect). It does not * support weaving operations (creation of mungers etc..). * + * @author Adrian Colyer + * @author Andy Clement */ public class ReflectionWorld extends World implements IReflectionWorld { + private static Map<WeakClassLoaderReference, ReflectionWorld> rworlds = Collections.synchronizedMap(new HashMap<WeakClassLoaderReference, ReflectionWorld>()); + private WeakClassLoaderReference classLoaderReference; private AnnotationFinder annotationFinder; private boolean mustUseOneFourDelegates = false; // for testing private Map<String,Class<?>> inProgressResolutionClasses = new HashMap<String,Class<?>>(); - + + public static ReflectionWorld getReflectionWorldFor(WeakClassLoaderReference classLoaderReference) { + + // Temporarily do as before. Although the cache makes things faster it needs a bit more thought because + // if the world has pointcutdesignators registered then someone may inadvertently register additional + // ones on reusing a world (when they would be expecting a clean world). We can't automatically + // clear them because we don't know when they are finished with. + return new ReflectionWorld(classLoaderReference); + + /* + synchronized (rworlds) { + // Tidyup any no longer relevant entries... + for (Iterator<Map.Entry<WeakClassLoaderReference, ReflectionWorld>> it = rworlds.entrySet().iterator(); + it.hasNext();) { + Map.Entry<WeakClassLoaderReference, ReflectionWorld> entry = it.next(); + if (entry.getKey().getClassLoader() == null) { + it.remove(); + } + } + ReflectionWorld rworld = null; + if (classLoaderReference.getClassLoader() != null) { + rworld = rworlds.get(classLoaderReference); + if (rworld == null) { + rworld = new ReflectionWorld(classLoaderReference); + rworlds.put(classLoaderReference, rworld); + } + } + return rworld; + } + */ + } + + public static void cleanUpWorlds() { + synchronized (rworlds) { + rworlds.clear(); + } + } + private ReflectionWorld() { // super(); // this.setMessageHandler(new ExceptionBasedMessageHandler()); @@ -49,6 +89,13 @@ public class ReflectionWorld extends World implements IReflectionWorld { // makeAnnotationFinderIfAny(classLoaderReference.getClassLoader(), // this); } + + public ReflectionWorld(WeakClassLoaderReference classloaderRef) { + this.setMessageHandler(new ExceptionBasedMessageHandler()); + setBehaveInJava5Way(LangUtil.is15VMOrGreater()); + classLoaderReference = classloaderRef; + annotationFinder = makeAnnotationFinderIfAny(classLoaderReference.getClassLoader(), this); + } public ReflectionWorld(ClassLoader aClassLoader) { super(); @@ -71,7 +118,7 @@ public class ReflectionWorld extends World implements IReflectionWorld { AnnotationFinder annotationFinder = null; try { if (LangUtil.is15VMOrGreater()) { - Class java15AnnotationFinder = Class.forName("org.aspectj.weaver.reflect.Java15AnnotationFinder"); + Class<?> java15AnnotationFinder = Class.forName("org.aspectj.weaver.reflect.Java15AnnotationFinder"); annotationFinder = (AnnotationFinder) java15AnnotationFinder.newInstance(); annotationFinder.setClassLoader(loader); annotationFinder.setWorld(world); @@ -99,7 +146,7 @@ public class ReflectionWorld extends World implements IReflectionWorld { return resolve(this, aClass); } - public static ResolvedType resolve(World world, Class aClass) { + public static ResolvedType resolve(World world, Class<?> aClass) { // classes that represent arrays return a class name that is the // signature of the array type, ho-hum... String className = aClass.getName(); diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/tools/PointcutParser.java b/org.aspectj.matcher/src/org/aspectj/weaver/tools/PointcutParser.java index 649aa0ba9..4e3b2bd59 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/tools/PointcutParser.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/tools/PointcutParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 2017 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 @@ -51,6 +51,9 @@ import org.aspectj.weaver.reflect.ReflectionWorld; /** * A PointcutParser can be used to build PointcutExpressions for a user-defined subset of AspectJ's pointcut language + * + * @author Adrian Colyer + * @author Andy Clement */ public class PointcutParser { @@ -123,7 +126,7 @@ public class PointcutParser { * @throws UnsupportedOperationException if the set contains if, cflow, or cflow below */ public static PointcutParser getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution( - Set supportedPointcutKinds) { + Set<PointcutPrimitive> supportedPointcutKinds) { PointcutParser p = new PointcutParser(supportedPointcutKinds); p.setClassLoader(Thread.currentThread().getContextClassLoader()); return p; @@ -163,7 +166,7 @@ public class PointcutParser { * @throws UnsupportedOperationException if the set contains if, cflow, or cflow below */ public static PointcutParser getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution( - Set supportedPointcutKinds, ClassLoader classLoader) { + Set<PointcutPrimitive> supportedPointcutKinds, ClassLoader classLoader) { PointcutParser p = new PointcutParser(supportedPointcutKinds); p.setClassLoader(classLoader); return p; @@ -216,7 +219,22 @@ public class PointcutParser { */ protected void setClassLoader(ClassLoader aLoader) { this.classLoaderReference = new WeakClassLoaderReference(aLoader); - world = new ReflectionWorld(this.classLoaderReference.getClassLoader()); + world = ReflectionWorld.getReflectionWorldFor(this.classLoaderReference); + } + + /** + * Set the classloader that this parser should use for type resolution. + * + * @param aLoader + * @param shareWorlds if true then two PointcutParsers operating using the same classloader will share a ReflectionWorld + */ + protected void setClassLoader(ClassLoader aLoader, boolean shareWorlds) { + this.classLoaderReference = new WeakClassLoaderReference(aLoader); + if (shareWorlds) { + world = ReflectionWorld.getReflectionWorldFor(this.classLoaderReference); + } else { + world = new ReflectionWorld(classLoaderReference); + } } /** @@ -261,7 +279,7 @@ public class PointcutParser { * @param type * @return */ - public PointcutParameter createPointcutParameter(String name, Class type) { + public PointcutParameter createPointcutParameter(String name, Class<?> type) { return new PointcutParameterImpl(name, type); } @@ -287,7 +305,7 @@ public class PointcutParser { * supported by this PointcutParser. * @throws IllegalArgumentException if the expression is not a well-formed pointcut expression */ - public PointcutExpression parsePointcutExpression(String expression, Class inScope, PointcutParameter[] formalParameters) + public PointcutExpression parsePointcutExpression(String expression, Class<?> inScope, PointcutParameter[] formalParameters) throws UnsupportedPointcutPrimitiveException, IllegalArgumentException { PointcutExpressionImpl pcExpr = null; try { @@ -303,7 +321,7 @@ public class PointcutParser { return pcExpr; } - protected Pointcut resolvePointcutExpression(String expression, Class inScope, PointcutParameter[] formalParameters) { + protected Pointcut resolvePointcutExpression(String expression, Class<?> inScope, PointcutParameter[] formalParameters) { try { PatternParser parser = new PatternParser(expression); parser.setPointcutDesignatorHandlers(pointcutDesignators, world); @@ -317,7 +335,7 @@ public class PointcutParser { } } - protected Pointcut concretizePointcutExpression(Pointcut pc, Class inScope, PointcutParameter[] formalParameters) { + protected Pointcut concretizePointcutExpression(Pointcut pc, Class<?> inScope, PointcutParameter[] formalParameters) { ResolvedType declaringTypeForResolution = null; if (inScope != null) { declaringTypeForResolution = getWorld().resolve(inScope.getName()); @@ -355,7 +373,7 @@ public class PointcutParser { } /* for testing */ - Set getSupportedPrimitives() { + Set<PointcutPrimitive> getSupportedPrimitives() { return supportedPrimitives; } @@ -366,7 +384,7 @@ public class PointcutParser { return current; } - private IScope buildResolutionScope(Class inScope, PointcutParameter[] formalParameters) { + private IScope buildResolutionScope(Class<?> inScope, PointcutParameter[] formalParameters) { if (formalParameters == null) { formalParameters = new PointcutParameter[0]; } @@ -398,7 +416,7 @@ public class PointcutParser { } } - private UnresolvedType toUnresolvedType(Class clazz) { + private UnresolvedType toUnresolvedType(Class<?> clazz) { if (clazz.isArray()) { return UnresolvedType.forSignature(clazz.getName().replace('.', '/')); } else { @@ -560,4 +578,5 @@ public class PointcutParser { msg.append("\n"); return msg.toString(); } + } diff --git a/org.eclipse.jdt.core/jdtcore-for-aspectj-src.zip b/org.eclipse.jdt.core/jdtcore-for-aspectj-src.zip Binary files differindex 89aedd312..9c4639cf0 100644 --- a/org.eclipse.jdt.core/jdtcore-for-aspectj-src.zip +++ b/org.eclipse.jdt.core/jdtcore-for-aspectj-src.zip diff --git a/org.eclipse.jdt.core/jdtcore-for-aspectj.jar b/org.eclipse.jdt.core/jdtcore-for-aspectj.jar Binary files differindex 7714061a6..270bc8560 100644 --- a/org.eclipse.jdt.core/jdtcore-for-aspectj.jar +++ b/org.eclipse.jdt.core/jdtcore-for-aspectj.jar diff --git a/org.eclipse.jdt.core/src/org/aspectj/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/src/org/aspectj/org/eclipse/jdt/internal/compiler/ClassFile.java new file mode 100644 index 000000000..e3d1c415c --- /dev/null +++ b/org.eclipse.jdt.core/src/org/aspectj/org/eclipse/jdt/internal/compiler/ClassFile.java @@ -0,0 +1,6784 @@ +/******************************************************************************* + * Copyright (c) 2000, 2014 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Jesper S Moller - Contributions for + * Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335 + * Bug 406982 - [1.8][compiler] Generation of MethodParameters Attribute in classfile + * Bug 416885 - [1.8][compiler]IncompatibleClassChange error (edit) + * Bug 412149 - [1.8][compiler] Emit repeated annotations into the designated container + * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for + * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work) + * Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator + * Bug 409246 - [1.8][compiler] Type annotations on catch parameters not handled properly + * Bug 415541 - [1.8][compiler] Type annotations in the body of static initializer get dropped + * Bug 415399 - [1.8][compiler] Type annotations on constructor results dropped by the code generator + * Bug 415470 - [1.8][compiler] Type annotations on class declaration go vanishing + * Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas + * Bug 434556 - Broken class file generated for incorrect annotation usage + * Stephan Herrmann - Contribution for + * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables + *******************************************************************************/ +package org.aspectj.org.eclipse.jdt.internal.compiler; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.aspectj.org.eclipse.jdt.core.compiler.CategorizedProblem; +import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; +import org.aspectj.org.eclipse.jdt.core.compiler.IProblem; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ArrayInitializer; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FunctionalExpression; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.LambdaExpression; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MemberValuePair; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NormalAnnotation; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Receiver; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleNameReference; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeParameter; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference; +import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.AnnotationContext; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.CodeStream; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.ConstantPool; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.Opcodes; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.StackMapFrame; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.TypeAnnotationCodeStream; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.ExceptionMarker; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.StackDepthMarker; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.StackMarker; +import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.VerificationTypeInfo; +import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.aspectj.org.eclipse.jdt.internal.compiler.impl.Constant; +import org.aspectj.org.eclipse.jdt.internal.compiler.impl.StringConstant; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Binding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeConstants; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeIds; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; +import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement; +import org.aspectj.org.eclipse.jdt.internal.compiler.util.Messages; +import org.aspectj.org.eclipse.jdt.internal.compiler.util.Util; + +/** + * Represents a class file wrapper on bytes, it is aware of its actual + * type name. + * + * Public APIs are listed below: + * + * byte[] getBytes(); + * Answer the actual bytes of the class file + * + * char[][] getCompoundName(); + * Answer the compound name of the class file. + * For example, {{java}, {util}, {Hashtable}}. + * + * byte[] getReducedBytes(); + * Answer a smaller byte format, which is only contains some structural + * information. Those bytes are decodable with a regular class file reader, + * such as DietClassFileReader + */ +@SuppressWarnings({"rawtypes", "unchecked"}) +public class ClassFile implements TypeConstants, TypeIds { + + private byte[] bytes; + public CodeStream codeStream; + public ConstantPool constantPool; + + public int constantPoolOffset; + + // the header contains all the bytes till the end of the constant pool + public byte[] contents; + + public int contentsOffset; + + protected boolean creatingProblemType; + + public ClassFile enclosingClassFile; + public byte[] header; + // that collection contains all the remaining bytes of the .class file + public int headerOffset; + public Set innerClassesBindings; + public List bootstrapMethods = null; + public int methodCount; + public int methodCountOffset; + // pool managment + boolean isShared = false; + // used to generate private access methods + // debug and stack map attributes + public int produceAttributes; + public SourceTypeBinding referenceBinding; + public boolean isNestedType; + public long targetJDK; + + public List missingTypes = null; + + public Set visitedTypes; + + public static final int INITIAL_CONTENTS_SIZE = 400; + public static final int INITIAL_HEADER_SIZE = 1500; + public static final int INNER_CLASSES_SIZE = 5; + + /** + * INTERNAL USE-ONLY + * Request the creation of a ClassFile compatible representation of a problematic type + * + * @param typeDeclaration org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration + * @param unitResult org.aspectj.org.eclipse.jdt.internal.compiler.CompilationUnitResult + */ + public static void createProblemType(TypeDeclaration typeDeclaration, CompilationResult unitResult) { + SourceTypeBinding typeBinding = typeDeclaration.binding; + ClassFile classFile = ClassFile.getNewInstance(typeBinding); + classFile.initialize(typeBinding, null, true); + + if (typeBinding.hasMemberTypes()) { + // see bug 180109 + ReferenceBinding[] members = typeBinding.memberTypes; + for (int i = 0, l = members.length; i < l; i++) + classFile.recordInnerClasses(members[i]); + } + // TODO (olivier) handle cases where a field cannot be generated (name too long) + // TODO (olivier) handle too many methods + // inner attributes + if (typeBinding.isNestedType()) { + classFile.recordInnerClasses(typeBinding); + } + TypeVariableBinding[] typeVariables = typeBinding.typeVariables(); + for (int i = 0, max = typeVariables.length; i < max; i++) { + TypeVariableBinding typeVariableBinding = typeVariables[i]; + if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(classFile, typeVariableBinding); + } + } + // add its fields + FieldBinding[] fields = typeBinding.fields(); + if ((fields != null) && (fields != Binding.NO_FIELDS)) { + classFile.addFieldInfos(); + } else { + // we have to set the number of fields to be equals to 0 + classFile.contents[classFile.contentsOffset++] = 0; + classFile.contents[classFile.contentsOffset++] = 0; + } + // leave some space for the methodCount + classFile.setForMethodInfos(); + // add its user defined methods + int problemsLength; + CategorizedProblem[] problems = unitResult.getErrors(); + if (problems == null) { + problems = new CategorizedProblem[0]; + } + CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length]; + System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); + + AbstractMethodDeclaration[] methodDecls = typeDeclaration.methods; + boolean abstractMethodsOnly = false; + if (methodDecls != null) { + if (typeBinding.isInterface()) { + if (typeBinding.scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8) + abstractMethodsOnly = true; + // We generate a clinit which contains all the problems, since we may not be able to generate problem methods (< 1.8) and problem constructors (all levels). + classFile.addProblemClinit(problemsCopy); + } + for (int i = 0, length = methodDecls.length; i < length; i++) { + AbstractMethodDeclaration methodDecl = methodDecls[i]; + MethodBinding method = methodDecl.binding; + if (method == null) continue; + if (abstractMethodsOnly) { + method.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract; + } + if (method.isConstructor()) { + if (typeBinding.isInterface()) continue; + classFile.addProblemConstructor(methodDecl, method, problemsCopy); + } else if (method.isAbstract()) { + classFile.addAbstractMethod(methodDecl, method); + } else { + classFile.addProblemMethod(methodDecl, method, problemsCopy); + } + } + // add abstract methods + classFile.addDefaultAbstractMethods(); + } + + // propagate generation of (problem) member types + if (typeDeclaration.memberTypes != null) { + for (int i = 0, max = typeDeclaration.memberTypes.length; i < max; i++) { + TypeDeclaration memberType = typeDeclaration.memberTypes[i]; + if (memberType.binding != null) { + ClassFile.createProblemType(memberType, unitResult); + } + } + } + classFile.addAttributes(); + unitResult.record(typeBinding.constantPoolName(), classFile); + } + public static ClassFile getNewInstance(SourceTypeBinding typeBinding) { + LookupEnvironment env = typeBinding.scope.environment(); + return env.classFilePool.acquire(typeBinding); + } + /** + * INTERNAL USE-ONLY + * This methods creates a new instance of the receiver. + */ + protected ClassFile() { + // default constructor for subclasses + } + + public ClassFile(SourceTypeBinding typeBinding) { + // default constructor for subclasses + this.constantPool = new ConstantPool(this); + final CompilerOptions options = typeBinding.scope.compilerOptions(); + this.targetJDK = options.targetJDK; + this.produceAttributes = options.produceDebugAttributes; + this.referenceBinding = typeBinding; + this.isNestedType = typeBinding.isNestedType(); + if (this.targetJDK >= ClassFileConstants.JDK1_6) { + this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE; + if (this.targetJDK >= ClassFileConstants.JDK1_8) { + this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION; + this.codeStream = new TypeAnnotationCodeStream(this); + if (options.produceMethodParameters) { + this.produceAttributes |= ClassFileConstants.ATTR_METHOD_PARAMETERS; + } + } else { + this.codeStream = new StackMapFrameCodeStream(this); + } + } else if (this.targetJDK == ClassFileConstants.CLDC_1_1) { + this.targetJDK = ClassFileConstants.JDK1_1; // put back 45.3 + this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP; + this.codeStream = new StackMapFrameCodeStream(this); + } else { + this.codeStream = new CodeStream(this); + } + initByteArrays(); + } + + /** + * INTERNAL USE-ONLY + * Generate the byte for a problem method info that correspond to a bogus method. + * + * @param method org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding + */ + public void addAbstractMethod( + AbstractMethodDeclaration method, + MethodBinding methodBinding) { + + this.generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + int attributeNumber = this.generateMethodInfoAttributes(methodBinding); + completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber); + } + + /** + * INTERNAL USE-ONLY + * This methods generate all the attributes for the receiver. + * For a class they could be: + * - source file attribute + * - inner classes attribute + * - deprecated attribute + */ + public void addAttributes() { + // update the method count + this.contents[this.methodCountOffset++] = (byte) (this.methodCount >> 8); + this.contents[this.methodCountOffset] = (byte) this.methodCount; + + int attributesNumber = 0; + // leave two bytes for the number of attributes and store the current offset + int attributeOffset = this.contentsOffset; + this.contentsOffset += 2; + + // source attribute + if ((this.produceAttributes & ClassFileConstants.ATTR_SOURCE) != 0) { + String fullFileName = + new String(this.referenceBinding.scope.referenceCompilationUnit().getFileName()); + fullFileName = fullFileName.replace('\\', '/'); + int lastIndex = fullFileName.lastIndexOf('/'); + if (lastIndex != -1) { + fullFileName = fullFileName.substring(lastIndex + 1, fullFileName.length()); + } + attributesNumber += generateSourceAttribute(fullFileName); + } + // Deprecated attribute + if (this.referenceBinding.isDeprecated()) { + // check that there is enough space to write all the bytes for the field info corresponding + // to the @fieldBinding + attributesNumber += generateDeprecatedAttribute(); + } + // add signature attribute + char[] genericSignature = this.referenceBinding.genericSignature(); + if (genericSignature != null) { + attributesNumber += generateSignatureAttribute(genericSignature); + } + if (this.targetJDK >= ClassFileConstants.JDK1_5 + && this.referenceBinding.isNestedType() + && !this.referenceBinding.isMemberType()) { + // add enclosing method attribute (1.5 mode only) + attributesNumber += generateEnclosingMethodAttribute(); + } + if (this.targetJDK >= ClassFileConstants.JDK1_4) { + TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext; + if (typeDeclaration != null) { + // AspectJ Extension - use the original array if its set + // original code: + // final Annotation[] annotations = typeDeclaration.annotations; + // new code: + Annotation[] annotations = typeDeclaration.originalAnnotations; + if (annotations == null) annotations = typeDeclaration.annotations; + // End AspectJ Extension + if (annotations != null) { + long targetMask; + if (typeDeclaration.isPackageInfo()) + targetMask = TagBits.AnnotationForPackage; + else if (this.referenceBinding.isAnnotationType()) + targetMask = TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType; + else + targetMask = TagBits.AnnotationForType | TagBits.AnnotationForTypeUse; + attributesNumber += generateRuntimeAnnotations(annotations, targetMask); + } + } + } + + if (this.referenceBinding.isHierarchyInconsistent()) { + ReferenceBinding superclass = this.referenceBinding.superclass; + if (superclass != null) { + this.missingTypes = superclass.collectMissingTypes(this.missingTypes); + } + ReferenceBinding[] superInterfaces = this.referenceBinding.superInterfaces(); + for (int i = 0, max = superInterfaces.length; i < max; i++) { + this.missingTypes = superInterfaces[i].collectMissingTypes(this.missingTypes); + } + attributesNumber += generateHierarchyInconsistentAttribute(); + } + // Functional expression and lambda bootstrap methods + if (this.bootstrapMethods != null && !this.bootstrapMethods.isEmpty()) { + attributesNumber += generateBootstrapMethods(this.bootstrapMethods); + } + // Inner class attribute + int numberOfInnerClasses = this.innerClassesBindings == null ? 0 : this.innerClassesBindings.size(); + if (numberOfInnerClasses != 0) { + ReferenceBinding[] innerClasses = new ReferenceBinding[numberOfInnerClasses]; + this.innerClassesBindings.toArray(innerClasses); + Arrays.sort(innerClasses, new Comparator() { + public int compare(Object o1, Object o2) { + TypeBinding binding1 = (TypeBinding) o1; + TypeBinding binding2 = (TypeBinding) o2; + return CharOperation.compareTo(binding1.constantPoolName(), binding2.constantPoolName()); + } + }); + attributesNumber += generateInnerClassAttribute(numberOfInnerClasses, innerClasses); + } + if (this.missingTypes != null) { + generateMissingTypesAttribute(); + attributesNumber++; + } + + attributesNumber += generateTypeAnnotationAttributeForTypeDeclaration(); + + // AspectJ Extension + // write any "extraAttributes" + if (extraAttributes != null) { + for (int i=0, len=extraAttributes.size(); i < len; i++) { + IAttribute attribute = (IAttribute)extraAttributes.get(i); + short nameIndex = (short)constantPool.literalIndex(attribute.getNameChars()); + writeToContents(attribute.getAllBytes(nameIndex,constantPool)); + attributesNumber++; + } + } + // End AspectJ Extension + + // update the number of attributes + if (attributeOffset + 2 >= this.contents.length) { + resizeContents(2); + } + this.contents[attributeOffset++] = (byte) (attributesNumber >> 8); + this.contents[attributeOffset] = (byte) attributesNumber; + + // resynchronize all offsets of the classfile + this.header = this.constantPool.poolContent; + this.headerOffset = this.constantPool.currentOffset; + int constantPoolCount = this.constantPool.currentIndex; + this.header[this.constantPoolOffset++] = (byte) (constantPoolCount >> 8); + this.header[this.constantPoolOffset] = (byte) constantPoolCount; + } + /** + * INTERNAL USE-ONLY + * This methods generate all the default abstract method infos that correpond to + * the abstract methods inherited from superinterfaces. + */ + public void addDefaultAbstractMethods() { // default abstract methods + MethodBinding[] defaultAbstractMethods = + this.referenceBinding.getDefaultAbstractMethods(); + for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) { + MethodBinding methodBinding = defaultAbstractMethods[i]; + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + int attributeNumber = generateMethodInfoAttributes(methodBinding); + completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber); + } + } + + private int addFieldAttributes(FieldBinding fieldBinding, int fieldAttributeOffset) { + int attributesNumber = 0; + // 4.7.2 only static constant fields get a ConstantAttribute + // Generate the constantValueAttribute + Constant fieldConstant = fieldBinding.constant(); + if (fieldConstant != Constant.NotAConstant){ + attributesNumber += generateConstantValueAttribute(fieldConstant, fieldBinding, fieldAttributeOffset); + } + if (this.targetJDK < ClassFileConstants.JDK1_5 && fieldBinding.isSynthetic()) { + attributesNumber += generateSyntheticAttribute(); + } + if (fieldBinding.isDeprecated()) { + attributesNumber += generateDeprecatedAttribute(); + } + // add signature attribute + char[] genericSignature = fieldBinding.genericSignature(); + if (genericSignature != null) { + attributesNumber += generateSignatureAttribute(genericSignature); + } + if (this.targetJDK >= ClassFileConstants.JDK1_4) { + FieldDeclaration fieldDeclaration = fieldBinding.sourceField(); + if (fieldDeclaration != null) { + Annotation[] annotations = fieldDeclaration.annotations; + if (annotations != null) { + attributesNumber += generateRuntimeAnnotations(annotations, TagBits.AnnotationForField); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) { + List allTypeAnnotationContexts = new ArrayList(); + if (annotations != null && (fieldDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) { + fieldDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts); + } + int invisibleTypeAnnotationsCounter = 0; + int visibleTypeAnnotationsCounter = 0; + TypeReference fieldType = fieldDeclaration.type; + if (fieldType != null && ((fieldType.bits & ASTNode.HasTypeAnnotations) != 0)) { + fieldType.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts); + } + int size = allTypeAnnotationContexts.size(); + if (size != 0) { + AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size]; + allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray); + for (int i = 0, max = allTypeAnnotationContextsArray.length; i < max; i++) { + AnnotationContext annotationContext = allTypeAnnotationContextsArray[i]; + if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) { + invisibleTypeAnnotationsCounter++; + allTypeAnnotationContexts.add(annotationContext); + } else { + visibleTypeAnnotationsCounter++; + allTypeAnnotationContexts.add(annotationContext); + } + } + attributesNumber += generateRuntimeTypeAnnotations( + allTypeAnnotationContextsArray, + visibleTypeAnnotationsCounter, + invisibleTypeAnnotationsCounter); + } + } + } + } + if ((fieldBinding.tagBits & TagBits.HasMissingType) != 0) { + this.missingTypes = fieldBinding.type.collectMissingTypes(this.missingTypes); + } + return attributesNumber; + } + + // AspectJ Extension + public List/*<IAttribute>*/ extraAttributes = new ArrayList(1); + // End AspectJ Extension + + /** + * INTERNAL USE-ONLY + * This methods generates the bytes for the given field binding + * @param fieldBinding the given field binding + */ + private void addFieldInfo(FieldBinding fieldBinding) { + // check that there is enough space to write all the bytes for the field info corresponding + // to the @fieldBinding + if (this.contentsOffset + 8 >= this.contents.length) { + resizeContents(8); + } + // Now we can generate all entries into the byte array + // First the accessFlags + int accessFlags = fieldBinding.getAccessFlags(); + if (this.targetJDK < ClassFileConstants.JDK1_5) { + // pre 1.5, synthetic was an attribute, not a modifier + accessFlags &= ~ClassFileConstants.AccSynthetic; + } + this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8); + this.contents[this.contentsOffset++] = (byte) accessFlags; + // Then the nameIndex + int nameIndex = this.constantPool.literalIndex(fieldBinding.name); + this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) nameIndex; + // Then the descriptorIndex + int descriptorIndex = this.constantPool.literalIndex(fieldBinding.type); + this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8); + this.contents[this.contentsOffset++] = (byte) descriptorIndex; + int fieldAttributeOffset = this.contentsOffset; + int attributeNumber = 0; + // leave some space for the number of attributes + this.contentsOffset += 2; + attributeNumber += addFieldAttributes(fieldBinding, fieldAttributeOffset); + if (this.contentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + this.contents[fieldAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[fieldAttributeOffset] = (byte) attributeNumber; + } + + /** + * INTERNAL USE-ONLY + * This methods generate all the fields infos for the receiver. + * This includes: + * - a field info for each defined field of that class + * - a field info for each synthetic field (e.g. this$0) + */ + /** + * INTERNAL USE-ONLY + * This methods generate all the fields infos for the receiver. + * This includes: + * - a field info for each defined field of that class + * - a field info for each synthetic field (e.g. this$0) + */ + public void addFieldInfos() { + SourceTypeBinding currentBinding = this.referenceBinding; + FieldBinding[] syntheticFields = currentBinding.syntheticFields(); + int fieldCount = currentBinding.fieldCount() + (syntheticFields == null ? 0 : syntheticFields.length); + + // write the number of fields + if (fieldCount > 0xFFFF) { + this.referenceBinding.scope.problemReporter().tooManyFields(this.referenceBinding.scope.referenceType()); + } + this.contents[this.contentsOffset++] = (byte) (fieldCount >> 8); + this.contents[this.contentsOffset++] = (byte) fieldCount; + + FieldDeclaration[] fieldDecls = currentBinding.scope.referenceContext.fields; + for (int i = 0, max = fieldDecls == null ? 0 : fieldDecls.length; i < max; i++) { + FieldDeclaration fieldDecl = fieldDecls[i]; + if (fieldDecl.binding != null) { + addFieldInfo(fieldDecl.binding); + } + } + + if (syntheticFields != null) { + for (int i = 0, max = syntheticFields.length; i < max; i++) { + addFieldInfo(syntheticFields[i]); + } + } + } + + private void addMissingAbstractProblemMethod(MethodDeclaration methodDeclaration, MethodBinding methodBinding, CategorizedProblem problem, CompilationResult compilationResult) { + // always clear the strictfp/native/abstract bit for a problem method + generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract)); + int methodAttributeOffset = this.contentsOffset; + int attributeNumber = generateMethodInfoAttributes(methodBinding); + + // Code attribute + attributeNumber++; + + int codeAttributeOffset = this.contentsOffset; + generateCodeAttributeHeader(); + StringBuffer buffer = new StringBuffer(25); + buffer.append("\t" + problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$ + buffer.insert(0, Messages.compilation_unresolvedProblem); + String problemString = buffer.toString(); + + this.codeStream.init(this); + this.codeStream.preserveUnusedLocals = true; + this.codeStream.initializeMaxLocals(methodBinding); + + // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "") + this.codeStream.generateCodeAttributeForProblemMethod(problemString); + + completeCodeAttributeForMissingAbstractProblemMethod( + methodBinding, + codeAttributeOffset, + compilationResult.getLineSeparatorPositions(), + problem.getSourceLineNumber()); + + completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber); + } + + /** + * INTERNAL USE-ONLY + * Generate the byte for a problem clinit method info that correspond to a boggus method. + * + * @param problems org.aspectj.org.eclipse.jdt.internal.compiler.problem.Problem[] + */ + public void addProblemClinit(CategorizedProblem[] problems) { + generateMethodInfoHeaderForClinit(); + // leave two spaces for the number of attributes + this.contentsOffset -= 2; + int attributeOffset = this.contentsOffset; + this.contentsOffset += 2; + int attributeNumber = 0; + + int codeAttributeOffset = this.contentsOffset; + generateCodeAttributeHeader(); + this.codeStream.resetForProblemClinit(this); + String problemString = "" ; //$NON-NLS-1$ + int problemLine = 0; + if (problems != null) { + int max = problems.length; + StringBuffer buffer = new StringBuffer(25); + int count = 0; + for (int i = 0; i < max; i++) { + CategorizedProblem problem = problems[i]; + if ((problem != null) && (problem.isError())) { + buffer.append("\t" +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$ + count++; + if (problemLine == 0) { + problemLine = problem.getSourceLineNumber(); + } + problems[i] = null; + } + } // insert the top line afterwards, once knowing how many problems we have to consider + if (count > 1) { + buffer.insert(0, Messages.compilation_unresolvedProblems); + } else { + buffer.insert(0, Messages.compilation_unresolvedProblem); + } + problemString = buffer.toString(); + } + + // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "") + this.codeStream.generateCodeAttributeForProblemMethod(problemString); + attributeNumber++; // code attribute + completeCodeAttributeForClinit( + codeAttributeOffset, + problemLine); + if (this.contentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + this.contents[attributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[attributeOffset] = (byte) attributeNumber; + } + + /** + * INTERNAL USE-ONLY + * Generate the byte for a problem method info that correspond to a boggus constructor. + * + * @param method org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding + * @param problems org.aspectj.org.eclipse.jdt.internal.compiler.problem.Problem[] + */ + public void addProblemConstructor( + AbstractMethodDeclaration method, + MethodBinding methodBinding, + CategorizedProblem[] problems) { + + if (methodBinding.declaringClass.isInterface()) { + method.abort(ProblemSeverities.AbortType, null); + } + + // always clear the strictfp/native/abstract bit for a problem method + generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract)); + int methodAttributeOffset = this.contentsOffset; + int attributesNumber = generateMethodInfoAttributes(methodBinding); + + // Code attribute + attributesNumber++; + int codeAttributeOffset = this.contentsOffset; + generateCodeAttributeHeader(); + this.codeStream.reset(method, this); + String problemString = "" ; //$NON-NLS-1$ + int problemLine = 0; + if (problems != null) { + int max = problems.length; + StringBuffer buffer = new StringBuffer(25); + int count = 0; + for (int i = 0; i < max; i++) { + CategorizedProblem problem = problems[i]; + if ((problem != null) && (problem.isError())) { + buffer.append("\t" +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$ + count++; + if (problemLine == 0) { + problemLine = problem.getSourceLineNumber(); + } + } + } // insert the top line afterwards, once knowing how many problems we have to consider + if (count > 1) { + buffer.insert(0, Messages.compilation_unresolvedProblems); + } else { + buffer.insert(0, Messages.compilation_unresolvedProblem); + } + problemString = buffer.toString(); + } + + // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "") + this.codeStream.generateCodeAttributeForProblemMethod(problemString); + completeCodeAttributeForProblemMethod( + method, + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions(), + problemLine); + completeMethodInfo(methodBinding, methodAttributeOffset, attributesNumber); + } + /** + * INTERNAL USE-ONLY + * Generate the byte for a problem method info that correspond to a boggus constructor. + * Reset the position inside the contents byte array to the savedOffset. + * + * @param method org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding + * @param problems org.aspectj.org.eclipse.jdt.internal.compiler.problem.Problem[] + * @param savedOffset <CODE>int</CODE> + */ + public void addProblemConstructor( + AbstractMethodDeclaration method, + MethodBinding methodBinding, + CategorizedProblem[] problems, + int savedOffset) { + // we need to move back the contentsOffset to the value at the beginning of the method + this.contentsOffset = savedOffset; + this.methodCount--; // we need to remove the method that causes the problem + addProblemConstructor(method, methodBinding, problems); + } + /** + * INTERNAL USE-ONLY + * Generate the byte for a problem method info that correspond to a boggus method. + * + * @param method org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding + * @param problems org.aspectj.org.eclipse.jdt.internal.compiler.problem.Problem[] + */ + public void addProblemMethod( + AbstractMethodDeclaration method, + MethodBinding methodBinding, + CategorizedProblem[] problems) { + if (methodBinding.isAbstract() && methodBinding.declaringClass.isInterface()) { + method.abort(ProblemSeverities.AbortType, null); + } + // always clear the strictfp/native/abstract bit for a problem method + generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract)); + int methodAttributeOffset = this.contentsOffset; + int attributesNumber = generateMethodInfoAttributes(methodBinding); + + // Code attribute + attributesNumber++; + + int codeAttributeOffset = this.contentsOffset; + generateCodeAttributeHeader(); + this.codeStream.reset(method, this); + String problemString = "" ; //$NON-NLS-1$ + int problemLine = 0; + if (problems != null) { + int max = problems.length; + StringBuffer buffer = new StringBuffer(25); + int count = 0; + for (int i = 0; i < max; i++) { + CategorizedProblem problem = problems[i]; + if ((problem != null) + && (problem.isError()) + && (problem.getSourceStart() >= method.declarationSourceStart) + && (problem.getSourceEnd() <= method.declarationSourceEnd)) { + buffer.append("\t" +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$ + count++; + if (problemLine == 0) { + problemLine = problem.getSourceLineNumber(); + } + problems[i] = null; + } + } // insert the top line afterwards, once knowing how many problems we have to consider + if (count > 1) { + buffer.insert(0, Messages.compilation_unresolvedProblems); + } else { + buffer.insert(0, Messages.compilation_unresolvedProblem); + } + problemString = buffer.toString(); + } + + // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "") + this.codeStream.generateCodeAttributeForProblemMethod(problemString); + completeCodeAttributeForProblemMethod( + method, + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions(), + problemLine); + completeMethodInfo(methodBinding, methodAttributeOffset, attributesNumber); + } + + /** + * INTERNAL USE-ONLY + * Generate the byte for a problem method info that correspond to a boggus method. + * Reset the position inside the contents byte array to the savedOffset. + * + * @param method org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding + * @param problems org.aspectj.org.eclipse.jdt.internal.compiler.problem.Problem[] + * @param savedOffset <CODE>int</CODE> + */ + public void addProblemMethod( + AbstractMethodDeclaration method, + MethodBinding methodBinding, + CategorizedProblem[] problems, + int savedOffset) { + // we need to move back the contentsOffset to the value at the beginning of the method + this.contentsOffset = savedOffset; + this.methodCount--; // we need to remove the method that causes the problem + addProblemMethod(method, methodBinding, problems); + } + + /** + * INTERNAL USE-ONLY + * Generate the byte for all the special method infos. + * They are: + * - synthetic access methods + * - default abstract methods + * - lambda methods. + */ + public void addSpecialMethods() { + + // add all methods (default abstract methods and synthetic) + + // default abstract methods + generateMissingAbstractMethods(this.referenceBinding.scope.referenceType().missingAbstractMethods, this.referenceBinding.scope.referenceCompilationUnit().compilationResult); + + MethodBinding[] defaultAbstractMethods = this.referenceBinding.getDefaultAbstractMethods(); + for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) { + MethodBinding methodBinding = defaultAbstractMethods[i]; + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + int attributeNumber = generateMethodInfoAttributes(methodBinding); + completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber); + } + + // add synthetic methods infos + int emittedSyntheticsCount = 0; + boolean continueScanningSynthetics = true; + while (continueScanningSynthetics) { + continueScanningSynthetics = false; + SyntheticMethodBinding[] syntheticMethods = this.referenceBinding.syntheticMethods(); + int currentSyntheticsCount = syntheticMethods == null ? 0: syntheticMethods.length; + if (emittedSyntheticsCount != currentSyntheticsCount) { + for (int i = emittedSyntheticsCount, max = currentSyntheticsCount; i < max; i++) { + SyntheticMethodBinding syntheticMethod = syntheticMethods[i]; + switch (syntheticMethod.purpose) { + case SyntheticMethodBinding.FieldReadAccess : + case SyntheticMethodBinding.SuperFieldReadAccess : + // generate a method info to emulate an reading access to + // a non-accessible field + addSyntheticFieldReadAccessMethod(syntheticMethod); + break; + case SyntheticMethodBinding.FieldWriteAccess : + case SyntheticMethodBinding.SuperFieldWriteAccess : + // generate a method info to emulate an writing access to + // a non-accessible field + addSyntheticFieldWriteAccessMethod(syntheticMethod); + break; + case SyntheticMethodBinding.MethodAccess : + case SyntheticMethodBinding.SuperMethodAccess : + case SyntheticMethodBinding.BridgeMethod : + // generate a method info to emulate an access to a non-accessible method / super-method or bridge method + addSyntheticMethodAccessMethod(syntheticMethod); + break; + case SyntheticMethodBinding.ConstructorAccess : + // generate a method info to emulate an access to a non-accessible constructor + addSyntheticConstructorAccessMethod(syntheticMethod); + break; + case SyntheticMethodBinding.EnumValues : + // generate a method info to define <enum>#values() + addSyntheticEnumValuesMethod(syntheticMethod); + break; + case SyntheticMethodBinding.EnumValueOf : + // generate a method info to define <enum>#valueOf(String) + addSyntheticEnumValueOfMethod(syntheticMethod); + break; + case SyntheticMethodBinding.SwitchTable : + // generate a method info to define the switch table synthetic method + addSyntheticSwitchTable(syntheticMethod); + break; + case SyntheticMethodBinding.TooManyEnumsConstants : + addSyntheticEnumInitializationMethod(syntheticMethod); + break; + case SyntheticMethodBinding.LambdaMethod: + syntheticMethod.lambda.generateCode(this.referenceBinding.scope, this); + continueScanningSynthetics = true; // lambda code generation could schedule additional nested lambdas for code generation. + break; + case SyntheticMethodBinding.ArrayConstructor: + addSyntheticArrayConstructor(syntheticMethod); + break; + case SyntheticMethodBinding.ArrayClone: + addSyntheticArrayClone(syntheticMethod); + break; + case SyntheticMethodBinding.FactoryMethod: + addSyntheticFactoryMethod(syntheticMethod); + break; + case SyntheticMethodBinding.DeserializeLambda: + // TODO [andy] do we need to do this after the loop to ensure it is done last? + addSyntheticDeserializeLambda(syntheticMethod,this.referenceBinding.syntheticMethods()); + break; + } + } + emittedSyntheticsCount = currentSyntheticsCount; + } + } + } + + public void addSyntheticArrayConstructor(SyntheticMethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForArrayConstructor(methodBinding); + completeCodeAttributeForSyntheticMethod( + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + public void addSyntheticArrayClone(SyntheticMethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForArrayClone(methodBinding); + completeCodeAttributeForSyntheticMethod( + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + public void addSyntheticFactoryMethod(SyntheticMethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForFactoryMethod(methodBinding); + completeCodeAttributeForSyntheticMethod( + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + /** + * INTERNAL USE-ONLY + * Generate the bytes for a synthetic method that provides an access to a private constructor. + * + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding + */ + public void addSyntheticConstructorAccessMethod(SyntheticMethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForConstructorAccess(methodBinding); + completeCodeAttributeForSyntheticMethod( + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + + /** + * INTERNAL USE-ONLY + * Generate the bytes for a synthetic method that implements Enum#valueOf(String) for a given enum type + * + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding + */ + public void addSyntheticEnumValueOfMethod(SyntheticMethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForEnumValueOf(methodBinding); + completeCodeAttributeForSyntheticMethod( + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + if ((this.produceAttributes & ClassFileConstants.ATTR_METHOD_PARAMETERS) != 0) { + attributeNumber += generateMethodParameters(methodBinding); + } + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + + /** + * INTERNAL USE-ONLY + * Generate the bytes for a synthetic method that implements Enum#values() for a given enum type + * + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding + */ + public void addSyntheticEnumValuesMethod(SyntheticMethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForEnumValues(methodBinding); + completeCodeAttributeForSyntheticMethod( + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + + public void addSyntheticEnumInitializationMethod(SyntheticMethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForEnumInitializationMethod(methodBinding); + completeCodeAttributeForSyntheticMethod( + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + /** + * INTERNAL USE-ONLY + * Generate the byte for a problem method info that correspond to a synthetic method that + * generate an read access to a private field. + * + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding + */ + public void addSyntheticFieldReadAccessMethod(SyntheticMethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForFieldReadAccess(methodBinding); + completeCodeAttributeForSyntheticMethod( + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + + /** + * INTERNAL USE-ONLY + * Generate the byte for a problem method info that correspond to a synthetic method that + * generate an write access to a private field. + * + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding + */ + public void addSyntheticFieldWriteAccessMethod(SyntheticMethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForFieldWriteAccess(methodBinding); + completeCodeAttributeForSyntheticMethod( + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + + /** + * INTERNAL USE-ONLY + * Generate the bytes for a synthetic method that provides access to a private method. + * + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding + */ + public void addSyntheticMethodAccessMethod(SyntheticMethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForMethodAccess(methodBinding); + completeCodeAttributeForSyntheticMethod( + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + + public void addSyntheticSwitchTable(SyntheticMethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForSwitchTable(methodBinding); + completeCodeAttributeForSyntheticMethod( + true, + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + + /** + * INTERNAL USE-ONLY + * That method completes the creation of the code attribute by setting + * - the attribute_length + * - max_stack + * - max_locals + * - code_length + * - exception table + * - and debug attributes if necessary. + * + * @param codeAttributeOffset <CODE>int</CODE> + */ + public void completeCodeAttribute(int codeAttributeOffset) { + // reinitialize the localContents with the byte modified by the code stream + this.contents = this.codeStream.bCodeStream; + int localContentsOffset = this.codeStream.classFileOffset; + // codeAttributeOffset is the position inside localContents byte array before we started to write + // any information about the codeAttribute + // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset + // to get the right position, 6 for the max_stack etc... + int code_length = this.codeStream.position; + if (code_length > 65535) { + if (this.codeStream.methodDeclaration != null) { + this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(this.codeStream.methodDeclaration); + } else { + this.codeStream.lambdaExpression.scope.problemReporter().bytecodeExceeds64KLimit(this.codeStream.lambdaExpression); + } + } + if (localContentsOffset + 20 >= this.contents.length) { + resizeContents(20); + } + int max_stack = this.codeStream.stackMax; + this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8); + this.contents[codeAttributeOffset + 7] = (byte) max_stack; + int max_locals = this.codeStream.maxLocals; + this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8); + this.contents[codeAttributeOffset + 9] = (byte) max_locals; + this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24); + this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16); + this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8); + this.contents[codeAttributeOffset + 13] = (byte) code_length; + + boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0; + // write the exception table + ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels; + int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous) + for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) { + exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2; + } + int exSize = exceptionHandlersCount * 8 + 2; + if (exSize + localContentsOffset >= this.contents.length) { + resizeContents(exSize); + } + // there is no exception table, so we need to offset by 2 the current offset and move + // on the attribute generation + this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8); + this.contents[localContentsOffset++] = (byte) exceptionHandlersCount; + for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) { + ExceptionLabel exceptionLabel = exceptionLabels[i]; + if (exceptionLabel != null) { + int iRange = 0, maxRange = exceptionLabel.getCount(); + if ((maxRange & 1) != 0) { + if (this.codeStream.methodDeclaration != null) { + this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError( + Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.methodDeclaration.selector)), + this.codeStream.methodDeclaration); + } else { + this.codeStream.lambdaExpression.scope.problemReporter().abortDueToInternalError( + Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.lambdaExpression.binding.selector)), + this.codeStream.lambdaExpression); + } + } + while (iRange < maxRange) { + int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions + this.contents[localContentsOffset++] = (byte) (start >> 8); + this.contents[localContentsOffset++] = (byte) start; + int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions + this.contents[localContentsOffset++] = (byte) (end >> 8); + this.contents[localContentsOffset++] = (byte) end; + int handlerPC = exceptionLabel.position; + if (addStackMaps) { + StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream; + stackMapFrameCodeStream.addFramePosition(handlerPC); +// stackMapFrameCodeStream.addExceptionMarker(handlerPC, exceptionLabel.exceptionType); + } + this.contents[localContentsOffset++] = (byte) (handlerPC >> 8); + this.contents[localContentsOffset++] = (byte) handlerPC; + if (exceptionLabel.exceptionType == null) { + // any exception handler + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + } else { + int nameIndex; + if (exceptionLabel.exceptionType == TypeBinding.NULL) { + /* represents ClassNotFoundException, see class literal access*/ + nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName); + } else { + nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType); + } + this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); + this.contents[localContentsOffset++] = (byte) nameIndex; + } + } + } + } + // debug attributes + int codeAttributeAttributeOffset = localContentsOffset; + int attributesNumber = 0; + // leave two bytes for the attribute_length + localContentsOffset += 2; + if (localContentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + + this.contentsOffset = localContentsOffset; + + // first we handle the linenumber attribute + if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) { + attributesNumber += generateLineNumberAttribute(); + } + // then we do the local variable attribute + if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) { + final boolean methodDeclarationIsStatic = this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.isStatic() : this.codeStream.lambdaExpression.binding.isStatic(); + attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, false); + } + + if (addStackMaps) { + attributesNumber += generateStackMapTableAttribute( + this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.binding : this.codeStream.lambdaExpression.binding, + code_length, + codeAttributeOffset, + max_locals, + false); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { + attributesNumber += generateStackMapAttribute( + this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.binding : this.codeStream.lambdaExpression.binding, + code_length, + codeAttributeOffset, + max_locals, + false); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) { + attributesNumber += generateTypeAnnotationsOnCodeAttribute(); + } + + this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8); + this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber; + + // update the attribute length + int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6); + this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); + this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); + this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); + this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; + } + + public int generateTypeAnnotationsOnCodeAttribute() { + int attributesNumber = 0; + + List allTypeAnnotationContexts = ((TypeAnnotationCodeStream) this.codeStream).allTypeAnnotationContexts; + int invisibleTypeAnnotationsCounter = 0; + int visibleTypeAnnotationsCounter = 0; + + for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) { + LocalVariableBinding localVariable = this.codeStream.locals[i]; + if (localVariable.isCatchParameter()) continue; + LocalDeclaration declaration = localVariable.declaration; + if (declaration == null + || (declaration.isArgument() && ((declaration.bits & ASTNode.IsUnionType) == 0)) + || (localVariable.initializationCount == 0) + || ((declaration.bits & ASTNode.HasTypeAnnotations) == 0)) { + continue; + } + int targetType = ((localVariable.tagBits & TagBits.IsResource) == 0) ? AnnotationTargetTypeConstants.LOCAL_VARIABLE : AnnotationTargetTypeConstants.RESOURCE_VARIABLE; + declaration.getAllAnnotationContexts(targetType, localVariable, allTypeAnnotationContexts); + } + + ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels; + for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) { + ExceptionLabel exceptionLabel = exceptionLabels[i]; + if (exceptionLabel.exceptionTypeReference != null && (exceptionLabel.exceptionTypeReference.bits & ASTNode.HasTypeAnnotations) != 0) { + exceptionLabel.exceptionTypeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.EXCEPTION_PARAMETER, i, allTypeAnnotationContexts, exceptionLabel.se7Annotations); + } + } + + int size = allTypeAnnotationContexts.size(); + if (size != 0) { + AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size]; + allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray); + for (int j = 0, max2 = allTypeAnnotationContextsArray.length; j < max2; j++) { + AnnotationContext annotationContext = allTypeAnnotationContextsArray[j]; + if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) { + invisibleTypeAnnotationsCounter++; + } else { + visibleTypeAnnotationsCounter++; + } + } + attributesNumber += generateRuntimeTypeAnnotations( + allTypeAnnotationContextsArray, + visibleTypeAnnotationsCounter, + invisibleTypeAnnotationsCounter); + } + return attributesNumber; + } + + /** + * INTERNAL USE-ONLY + * That method completes the creation of the code attribute by setting + * - the attribute_length + * - max_stack + * - max_locals + * - code_length + * - exception table + * - and debug attributes if necessary. + * + * @param codeAttributeOffset <CODE>int</CODE> + */ + public void completeCodeAttributeForClinit(int codeAttributeOffset) { + // reinitialize the contents with the byte modified by the code stream + this.contents = this.codeStream.bCodeStream; + int localContentsOffset = this.codeStream.classFileOffset; + // codeAttributeOffset is the position inside contents byte array before we started to write + // any information about the codeAttribute + // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset + // to get the right position, 6 for the max_stack etc... + int code_length = this.codeStream.position; + if (code_length > 65535) { + this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit( + this.codeStream.methodDeclaration.scope.referenceType()); + } + if (localContentsOffset + 20 >= this.contents.length) { + resizeContents(20); + } + int max_stack = this.codeStream.stackMax; + this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8); + this.contents[codeAttributeOffset + 7] = (byte) max_stack; + int max_locals = this.codeStream.maxLocals; + this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8); + this.contents[codeAttributeOffset + 9] = (byte) max_locals; + this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24); + this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16); + this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8); + this.contents[codeAttributeOffset + 13] = (byte) code_length; + + boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0; + // write the exception table + ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels; + int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous) + for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) { + exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2; + } + int exSize = exceptionHandlersCount * 8 + 2; + if (exSize + localContentsOffset >= this.contents.length) { + resizeContents(exSize); + } + // there is no exception table, so we need to offset by 2 the current offset and move + // on the attribute generation + this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8); + this.contents[localContentsOffset++] = (byte) exceptionHandlersCount; + for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) { + ExceptionLabel exceptionLabel = exceptionLabels[i]; + if (exceptionLabel != null) { + int iRange = 0, maxRange = exceptionLabel.getCount(); + if ((maxRange & 1) != 0) { + this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError( + Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.methodDeclaration.selector)), + this.codeStream.methodDeclaration); + } + while (iRange < maxRange) { + int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions + this.contents[localContentsOffset++] = (byte) (start >> 8); + this.contents[localContentsOffset++] = (byte) start; + int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions + this.contents[localContentsOffset++] = (byte) (end >> 8); + this.contents[localContentsOffset++] = (byte) end; + int handlerPC = exceptionLabel.position; + this.contents[localContentsOffset++] = (byte) (handlerPC >> 8); + this.contents[localContentsOffset++] = (byte) handlerPC; + if (addStackMaps) { + StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream; + stackMapFrameCodeStream.addFramePosition(handlerPC); +// stackMapFrameCodeStream.addExceptionMarker(handlerPC, exceptionLabel.exceptionType); + } + if (exceptionLabel.exceptionType == null) { + // any exception handler + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + } else { + int nameIndex; + if (exceptionLabel.exceptionType == TypeBinding.NULL) { + /* represents denote ClassNotFoundException, see class literal access*/ + nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName); + } else { + nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType); + } + this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); + this.contents[localContentsOffset++] = (byte) nameIndex; + } + } + } + } + // debug attributes + int codeAttributeAttributeOffset = localContentsOffset; + int attributesNumber = 0; + // leave two bytes for the attribute_length + localContentsOffset += 2; + if (localContentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + + this.contentsOffset = localContentsOffset; + + // first we handle the linenumber attribute + if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) { + attributesNumber += generateLineNumberAttribute(); + } + // then we do the local variable attribute + if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) { + attributesNumber += generateLocalVariableTableAttribute(code_length, true, false); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) { + attributesNumber += generateStackMapTableAttribute( + null, + code_length, + codeAttributeOffset, + max_locals, + true); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { + attributesNumber += generateStackMapAttribute( + null, + code_length, + codeAttributeOffset, + max_locals, + true); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) { + attributesNumber += generateTypeAnnotationsOnCodeAttribute(); + } + + // update the number of attributes + // ensure first that there is enough space available inside the contents array + if (codeAttributeAttributeOffset + 2 >= this.contents.length) { + resizeContents(2); + } + this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8); + this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber; + // update the attribute length + int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6); + this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); + this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); + this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); + this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; + } + + /** + * INTERNAL USE-ONLY + * That method completes the creation of the code attribute by setting + * - the attribute_length + * - max_stack + * - max_locals + * - code_length + * - exception table + * - and debug attributes if necessary. + */ + public void completeCodeAttributeForClinit( + int codeAttributeOffset, + int problemLine) { + // reinitialize the contents with the byte modified by the code stream + this.contents = this.codeStream.bCodeStream; + int localContentsOffset = this.codeStream.classFileOffset; + // codeAttributeOffset is the position inside contents byte array before we started to write + // any information about the codeAttribute + // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset + // to get the right position, 6 for the max_stack etc... + int code_length = this.codeStream.position; + if (code_length > 65535) { + this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit( + this.codeStream.methodDeclaration.scope.referenceType()); + } + if (localContentsOffset + 20 >= this.contents.length) { + resizeContents(20); + } + int max_stack = this.codeStream.stackMax; + this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8); + this.contents[codeAttributeOffset + 7] = (byte) max_stack; + int max_locals = this.codeStream.maxLocals; + this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8); + this.contents[codeAttributeOffset + 9] = (byte) max_locals; + this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24); + this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16); + this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8); + this.contents[codeAttributeOffset + 13] = (byte) code_length; + + // write the exception table + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + + // debug attributes + int codeAttributeAttributeOffset = localContentsOffset; + int attributesNumber = 0; // leave two bytes for the attribute_length + localContentsOffset += 2; // first we handle the linenumber attribute + if (localContentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + + this.contentsOffset = localContentsOffset; + // first we handle the linenumber attribute + if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) { + attributesNumber += generateLineNumberAttribute(problemLine); + } + localContentsOffset = this.contentsOffset; + // then we do the local variable attribute + if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) { + int localVariableNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName); + if (localContentsOffset + 8 >= this.contents.length) { + resizeContents(8); + } + this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) localVariableNameIndex; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 2; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + attributesNumber++; + } + + this.contentsOffset = localContentsOffset; + + if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) { + attributesNumber += generateStackMapTableAttribute( + null, + code_length, + codeAttributeOffset, + max_locals, + true); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { + attributesNumber += generateStackMapAttribute( + null, + code_length, + codeAttributeOffset, + max_locals, + true); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) { + attributesNumber += generateTypeAnnotationsOnCodeAttribute(); + } + + // update the number of attributes + // ensure first that there is enough space available inside the contents array + if (codeAttributeAttributeOffset + 2 >= this.contents.length) { + resizeContents(2); + } + this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8); + this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber; + // update the attribute length + int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6); + this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); + this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); + this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); + this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; + } + + + /** + * + */ + public void completeCodeAttributeForMissingAbstractProblemMethod( + MethodBinding binding, + int codeAttributeOffset, + int[] startLineIndexes, + int problemLine) { + // reinitialize the localContents with the byte modified by the code stream + this.contents = this.codeStream.bCodeStream; + int localContentsOffset = this.codeStream.classFileOffset; + // codeAttributeOffset is the position inside localContents byte array before we started to write// any information about the codeAttribute// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset// to get the right position, 6 for the max_stack etc... + int max_stack = this.codeStream.stackMax; + this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8); + this.contents[codeAttributeOffset + 7] = (byte) max_stack; + int max_locals = this.codeStream.maxLocals; + this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8); + this.contents[codeAttributeOffset + 9] = (byte) max_locals; + int code_length = this.codeStream.position; + this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24); + this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16); + this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8); + this.contents[codeAttributeOffset + 13] = (byte) code_length; + // write the exception table + if (localContentsOffset + 50 >= this.contents.length) { + resizeContents(50); + } + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + // debug attributes + int codeAttributeAttributeOffset = localContentsOffset; + int attributesNumber = 0; // leave two bytes for the attribute_length + localContentsOffset += 2; // first we handle the linenumber attribute + if (localContentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + + this.contentsOffset = localContentsOffset; + if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) { + if (problemLine == 0) { + problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1); + } + attributesNumber += generateLineNumberAttribute(problemLine); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) { + attributesNumber += generateStackMapTableAttribute( + binding, + code_length, + codeAttributeOffset, + max_locals, + false); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { + attributesNumber += generateStackMapAttribute( + binding, + code_length, + codeAttributeOffset, + max_locals, + false); + } + + // then we do the local variable attribute + // update the number of attributes// ensure first that there is enough space available inside the localContents array + if (codeAttributeAttributeOffset + 2 >= this.contents.length) { + resizeContents(2); + } + this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8); + this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber; + // update the attribute length + int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6); + this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); + this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); + this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); + this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; + } + + /** + * INTERNAL USE-ONLY + * That method completes the creation of the code attribute by setting + * - the attribute_length + * - max_stack + * - max_locals + * - code_length + * - exception table + * - and debug attributes if necessary. + * + * @param codeAttributeOffset <CODE>int</CODE> + */ + public void completeCodeAttributeForProblemMethod( + AbstractMethodDeclaration method, + MethodBinding binding, + int codeAttributeOffset, + int[] startLineIndexes, + int problemLine) { + // reinitialize the localContents with the byte modified by the code stream + this.contents = this.codeStream.bCodeStream; + int localContentsOffset = this.codeStream.classFileOffset; + // codeAttributeOffset is the position inside localContents byte array before we started to write// any information about the codeAttribute// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset// to get the right position, 6 for the max_stack etc... + int max_stack = this.codeStream.stackMax; + this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8); + this.contents[codeAttributeOffset + 7] = (byte) max_stack; + int max_locals = this.codeStream.maxLocals; + this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8); + this.contents[codeAttributeOffset + 9] = (byte) max_locals; + int code_length = this.codeStream.position; + this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24); + this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16); + this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8); + this.contents[codeAttributeOffset + 13] = (byte) code_length; + // write the exception table + if (localContentsOffset + 50 >= this.contents.length) { + resizeContents(50); + } + + // write the exception table + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + // debug attributes + int codeAttributeAttributeOffset = localContentsOffset; + int attributesNumber = 0; // leave two bytes for the attribute_length + localContentsOffset += 2; // first we handle the linenumber attribute + if (localContentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + + this.contentsOffset = localContentsOffset; + if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) { + if (problemLine == 0) { + problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1); + } + attributesNumber += generateLineNumberAttribute(problemLine); + } + + // then we do the local variable attribute + if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) { + final boolean methodDeclarationIsStatic = this.codeStream.methodDeclaration.isStatic(); + attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, false); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) { + attributesNumber += generateStackMapTableAttribute( + binding, + code_length, + codeAttributeOffset, + max_locals, + false); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { + attributesNumber += generateStackMapAttribute( + binding, + code_length, + codeAttributeOffset, + max_locals, + false); + } + + // update the number of attributes// ensure first that there is enough space available inside the localContents array + if (codeAttributeAttributeOffset + 2 >= this.contents.length) { + resizeContents(2); + } + this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8); + this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber; + // update the attribute length + int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6); + this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); + this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); + this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); + this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; + } + + /** + * INTERNAL USE-ONLY + * That method completes the creation of the code attribute by setting + * - the attribute_length + * - max_stack + * - max_locals + * - code_length + * - exception table + * - and debug attributes if necessary. + * + * @param binding org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding + * @param codeAttributeOffset <CODE>int</CODE> + */ + public void completeCodeAttributeForSyntheticMethod( + boolean hasExceptionHandlers, + SyntheticMethodBinding binding, + int codeAttributeOffset, + int[] startLineIndexes) { + // reinitialize the contents with the byte modified by the code stream + this.contents = this.codeStream.bCodeStream; + int localContentsOffset = this.codeStream.classFileOffset; + // codeAttributeOffset is the position inside contents byte array before we started to write + // any information about the codeAttribute + // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset + // to get the right position, 6 for the max_stack etc... + int max_stack = this.codeStream.stackMax; + this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8); + this.contents[codeAttributeOffset + 7] = (byte) max_stack; + int max_locals = this.codeStream.maxLocals; + this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8); + this.contents[codeAttributeOffset + 9] = (byte) max_locals; + int code_length = this.codeStream.position; + this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24); + this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16); + this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8); + this.contents[codeAttributeOffset + 13] = (byte) code_length; + if ((localContentsOffset + 40) >= this.contents.length) { + resizeContents(40); + } + + boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0; + if (hasExceptionHandlers) { + // write the exception table + ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels; + int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous) + for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) { + exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2; + } + int exSize = exceptionHandlersCount * 8 + 2; + if (exSize + localContentsOffset >= this.contents.length) { + resizeContents(exSize); + } + // there is no exception table, so we need to offset by 2 the current offset and move + // on the attribute generation + this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8); + this.contents[localContentsOffset++] = (byte) exceptionHandlersCount; + for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) { + ExceptionLabel exceptionLabel = exceptionLabels[i]; + if (exceptionLabel != null) { + int iRange = 0, maxRange = exceptionLabel.getCount(); + if ((maxRange & 1) != 0) { + this.referenceBinding.scope.problemReporter().abortDueToInternalError( + Messages.bind(Messages.abort_invalidExceptionAttribute, new String(binding.selector), + this.referenceBinding.scope.problemReporter().referenceContext)); + } + while (iRange < maxRange) { + int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions + this.contents[localContentsOffset++] = (byte) (start >> 8); + this.contents[localContentsOffset++] = (byte) start; + int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions + this.contents[localContentsOffset++] = (byte) (end >> 8); + this.contents[localContentsOffset++] = (byte) end; + int handlerPC = exceptionLabel.position; + if (addStackMaps) { + StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream; + stackMapFrameCodeStream.addFramePosition(handlerPC); + } + this.contents[localContentsOffset++] = (byte) (handlerPC >> 8); + this.contents[localContentsOffset++] = (byte) handlerPC; + if (exceptionLabel.exceptionType == null) { + // any exception handler + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + } else { + int nameIndex; + switch(exceptionLabel.exceptionType.id) { + case T_null : + /* represents ClassNotFoundException, see class literal access*/ + nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName); + break; + case T_long : + /* represents NoSuchFieldError, see switch table generation*/ + nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangNoSuchFieldErrorConstantPoolName); + break; + default: + nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType); + } + this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); + this.contents[localContentsOffset++] = (byte) nameIndex; + } + } + } + } + } else { + // there is no exception table, so we need to offset by 2 the current offset and move + // on the attribute generation + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + } + // debug attributes + int codeAttributeAttributeOffset = localContentsOffset; + int attributesNumber = 0; + // leave two bytes for the attribute_length + localContentsOffset += 2; + if (localContentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + + this.contentsOffset = localContentsOffset; + // first we handle the linenumber attribute + if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) { + int lineNumber = Util.getLineNumber(binding.sourceStart, startLineIndexes, 0, startLineIndexes.length-1); + attributesNumber += generateLineNumberAttribute(lineNumber); + } + // then we do the local variable attribute + if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) { + final boolean methodDeclarationIsStatic = binding.isStatic(); + attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, true); + } + if (addStackMaps) { + attributesNumber += generateStackMapTableAttribute(binding, code_length, codeAttributeOffset, max_locals, false); + } + + if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { + attributesNumber += generateStackMapAttribute( + binding, + code_length, + codeAttributeOffset, + max_locals, + false); + } + + // update the number of attributes + // ensure first that there is enough space available inside the contents array + if (codeAttributeAttributeOffset + 2 >= this.contents.length) { + resizeContents(2); + } + this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8); + this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber; + + // update the attribute length + int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6); + this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); + this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); + this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); + this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; + } + + /** + * INTERNAL USE-ONLY + * That method completes the creation of the code attribute by setting + * - the attribute_length + * - max_stack + * - max_locals + * - code_length + * - exception table + * - and debug attributes if necessary. + * + * @param binding org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding + * @param codeAttributeOffset <CODE>int</CODE> + */ + public void completeCodeAttributeForSyntheticMethod( + SyntheticMethodBinding binding, + int codeAttributeOffset, + int[] startLineIndexes) { + + this.completeCodeAttributeForSyntheticMethod( + false, + binding, + codeAttributeOffset, + startLineIndexes); + } + + private void completeArgumentAnnotationInfo(Argument[] arguments, List allAnnotationContexts) { + for (int i = 0, max = arguments.length; i < max; i++) { + Argument argument = arguments[i]; + if ((argument.bits & ASTNode.HasTypeAnnotations) != 0) { + argument.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER, i, allAnnotationContexts); + } + } + } + + /** + * INTERNAL USE-ONLY + * Complete the creation of a method info by setting up the number of attributes at the right offset. + * + * @param methodAttributeOffset <CODE>int</CODE> + * @param attributesNumber <CODE>int</CODE> + */ + public void completeMethodInfo( + MethodBinding binding, + int methodAttributeOffset, + int attributesNumber) { + + if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) { + List allTypeAnnotationContexts = new ArrayList(); + int invisibleTypeAnnotationsCounter = 0; + int visibleTypeAnnotationsCounter = 0; + AbstractMethodDeclaration methodDeclaration = binding.sourceMethod(); + if (methodDeclaration != null) { + if ((methodDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) { + Argument[] arguments = methodDeclaration.arguments; + if (arguments != null) { + completeArgumentAnnotationInfo(arguments, allTypeAnnotationContexts); + } + Receiver receiver = methodDeclaration.receiver; + if (receiver != null && (receiver.type.bits & ASTNode.HasTypeAnnotations) != 0) { + receiver.type.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RECEIVER, allTypeAnnotationContexts); + } + } + Annotation[] annotations = methodDeclaration.annotations; + if (annotations != null && !methodDeclaration.isClinit() && (methodDeclaration.isConstructor() || binding.returnType.id != T_void)) { + methodDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts); + } + if (!methodDeclaration.isConstructor() && !methodDeclaration.isClinit() && binding.returnType.id != T_void) { + MethodDeclaration declaration = (MethodDeclaration) methodDeclaration; + TypeReference typeReference = declaration.returnType; + if ((typeReference.bits & ASTNode.HasTypeAnnotations) != 0) { + typeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts); + } + } + TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions; + if (thrownExceptions != null) { + for (int i = 0, max = thrownExceptions.length; i < max; i++) { + TypeReference thrownException = thrownExceptions[i]; + thrownException.getAllAnnotationContexts(AnnotationTargetTypeConstants.THROWS, i, allTypeAnnotationContexts); + } + } + TypeParameter[] typeParameters = methodDeclaration.typeParameters(); + if (typeParameters != null) { + for (int i = 0, max = typeParameters.length; i < max; i++) { + TypeParameter typeParameter = typeParameters[i]; + if ((typeParameter.bits & ASTNode.HasTypeAnnotations) != 0) { + typeParameter.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER, i, allTypeAnnotationContexts); + } + } + } + } else if (binding.sourceLambda() != null) { // SyntheticMethodBinding, purpose : LambdaMethod. + LambdaExpression lambda = binding.sourceLambda(); + if ((lambda.bits & ASTNode.HasTypeAnnotations) != 0) { + if (lambda.arguments != null) + completeArgumentAnnotationInfo(lambda.arguments, allTypeAnnotationContexts); + } + } + int size = allTypeAnnotationContexts.size(); + if (size != 0) { + AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size]; + allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray); + for (int j = 0, max2 = allTypeAnnotationContextsArray.length; j < max2; j++) { + AnnotationContext annotationContext = allTypeAnnotationContextsArray[j]; + if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) { + invisibleTypeAnnotationsCounter++; + } else { + visibleTypeAnnotationsCounter++; + } + } + attributesNumber += generateRuntimeTypeAnnotations( + allTypeAnnotationContextsArray, + visibleTypeAnnotationsCounter, + invisibleTypeAnnotationsCounter); + } + } + if ((this.produceAttributes & ClassFileConstants.ATTR_METHOD_PARAMETERS) != 0) { + attributesNumber += generateMethodParameters(binding); + } + // update the number of attributes + this.contents[methodAttributeOffset++] = (byte) (attributesNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributesNumber; + } + + private void dumpLocations(int[] locations) { + if (locations == null) { + // no type path + if (this.contentsOffset + 1 >= this.contents.length) { + resizeContents(1); + } + this.contents[this.contentsOffset++] = (byte) 0; + } else { + int length = locations.length; + if (this.contentsOffset + length >= this.contents.length) { + resizeContents(length + 1); + } + this.contents[this.contentsOffset++] = (byte) (locations.length / 2); + for (int i = 0; i < length; i++) { + this.contents[this.contentsOffset++] = (byte) locations[i]; + } + } + } + private void dumpTargetTypeContents(int targetType, AnnotationContext annotationContext) { + switch(targetType) { + case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER : + case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER : + // parameter index + this.contents[this.contentsOffset++] = (byte) annotationContext.info; + break; + + case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND : + // type_parameter_index + this.contents[this.contentsOffset++] = (byte) annotationContext.info; + // bound_index + this.contents[this.contentsOffset++] = (byte) annotationContext.info2; + break; + case AnnotationTargetTypeConstants.FIELD : + case AnnotationTargetTypeConstants.METHOD_RECEIVER : + case AnnotationTargetTypeConstants.METHOD_RETURN : + // target_info is empty_target + break; + case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER : + // target_info is parameter index + this.contents[this.contentsOffset++] = (byte) annotationContext.info; + break; + + case AnnotationTargetTypeConstants.INSTANCEOF : + case AnnotationTargetTypeConstants.NEW : + case AnnotationTargetTypeConstants.EXCEPTION_PARAMETER : + case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE : + case AnnotationTargetTypeConstants.METHOD_REFERENCE : + // bytecode offset for new/instanceof/method_reference + // exception table entry index for exception_parameter + this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8); + this.contents[this.contentsOffset++] = (byte) annotationContext.info; + break; + case AnnotationTargetTypeConstants.CAST : + // bytecode offset + this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8); + this.contents[this.contentsOffset++] = (byte) annotationContext.info; + this.contents[this.contentsOffset++] = (byte) annotationContext.info2; + break; + + case AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT : + case AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT : + case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT : + case AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT : + // bytecode offset + this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8); + this.contents[this.contentsOffset++] = (byte) annotationContext.info; + // type_argument_index + this.contents[this.contentsOffset++] = (byte) annotationContext.info2; + break; + + case AnnotationTargetTypeConstants.CLASS_EXTENDS : + case AnnotationTargetTypeConstants.THROWS : + // For CLASS_EXTENDS - info is supertype index (-1 = superclass) + // For THROWS - info is exception table index + this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8); + this.contents[this.contentsOffset++] = (byte) annotationContext.info; + break; + + case AnnotationTargetTypeConstants.LOCAL_VARIABLE : + case AnnotationTargetTypeConstants.RESOURCE_VARIABLE : + int localVariableTableOffset = this.contentsOffset; + LocalVariableBinding localVariable = annotationContext.variableBinding; + int actualSize = 0; + int initializationCount = localVariable.initializationCount; + actualSize += 6 * initializationCount; + // reserve enough space + if (this.contentsOffset + actualSize >= this.contents.length) { + resizeContents(actualSize); + } + this.contentsOffset += 2; + int numberOfEntries = 0; + for (int j = 0; j < initializationCount; j++) { + int startPC = localVariable.initializationPCs[j << 1]; + int endPC = localVariable.initializationPCs[(j << 1) + 1]; + if (startPC != endPC) { // only entries for non zero length + // now we can safely add the local entry + numberOfEntries++; + this.contents[this.contentsOffset++] = (byte) (startPC >> 8); + this.contents[this.contentsOffset++] = (byte) startPC; + int length = endPC - startPC; + this.contents[this.contentsOffset++] = (byte) (length >> 8); + this.contents[this.contentsOffset++] = (byte) length; + int resolvedPosition = localVariable.resolvedPosition; + this.contents[this.contentsOffset++] = (byte) (resolvedPosition >> 8); + this.contents[this.contentsOffset++] = (byte) resolvedPosition; + } + } + this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8); + this.contents[localVariableTableOffset] = (byte) numberOfEntries; + break; + case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND : + this.contents[this.contentsOffset++] = (byte) annotationContext.info; + this.contents[this.contentsOffset++] = (byte) annotationContext.info2; + break; + } + } + + + + /** + * INTERNAL USE-ONLY + * This methods returns a char[] representing the file name of the receiver + * + * @return char[] + */ + public char[] fileName() { + return this.constantPool.UTF8Cache.returnKeyFor(2); + } + + private void generateAnnotation(Annotation annotation, int currentOffset) { + int startingContentsOffset = currentOffset; + if (this.contentsOffset + 4 >= this.contents.length) { + resizeContents(4); + } + TypeBinding annotationTypeBinding = annotation.resolvedType; + if (annotationTypeBinding == null) { + this.contentsOffset = startingContentsOffset; + return; + } + if (annotationTypeBinding.isMemberType()) { + this.recordInnerClasses(annotationTypeBinding); + } + final int typeIndex = this.constantPool.literalIndex(annotationTypeBinding.signature()); + this.contents[this.contentsOffset++] = (byte) (typeIndex >> 8); + this.contents[this.contentsOffset++] = (byte) typeIndex; + if (annotation instanceof NormalAnnotation) { + NormalAnnotation normalAnnotation = (NormalAnnotation) annotation; + MemberValuePair[] memberValuePairs = normalAnnotation.memberValuePairs; + int memberValuePairOffset = this.contentsOffset; + if (memberValuePairs != null) { + int memberValuePairsCount = 0; + int memberValuePairsLengthPosition = this.contentsOffset; + this.contentsOffset+=2; // leave space to fill in the pair count later + int resetPosition = this.contentsOffset; + final int memberValuePairsLength = memberValuePairs.length; + loop: for (int i = 0; i < memberValuePairsLength; i++) { + MemberValuePair memberValuePair = memberValuePairs[i]; + if (this.contentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + final int elementNameIndex = this.constantPool.literalIndex(memberValuePair.name); + this.contents[this.contentsOffset++] = (byte) (elementNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) elementNameIndex; + MethodBinding methodBinding = memberValuePair.binding; + if (methodBinding == null) { + this.contentsOffset = resetPosition; + } else { + try { + generateElementValue(memberValuePair.value, methodBinding.returnType, startingContentsOffset); + if (this.contentsOffset == memberValuePairOffset) { + // ignore all annotation values +// this.contentsOffset = resetPosition; + this.contents[this.contentsOffset++]=0; + this.contents[this.contentsOffset++]=0; + break loop; + } + memberValuePairsCount++; + resetPosition = this.contentsOffset; + } catch(ClassCastException e) { + this.contentsOffset = resetPosition; + } catch(ShouldNotImplement e) { + this.contentsOffset = resetPosition; + } + } + } + this.contents[memberValuePairsLengthPosition++] = (byte) (memberValuePairsCount >> 8); + this.contents[memberValuePairsLengthPosition++] = (byte) memberValuePairsCount; + } else { + this.contents[this.contentsOffset++] = 0; + this.contents[this.contentsOffset++] = 0; + } + } else if (annotation instanceof SingleMemberAnnotation) { + SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) annotation; + // this is a single member annotation (one member value) + int memberValuePairCount = 0; // will not get to 1 if there is a problem with the annotation value + int memberValuePairLengthPosition = this.contentsOffset; + this.contentsOffset+=2;// leave space to fill in the pair count later + if (this.contentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + final int elementNameIndex = this.constantPool.literalIndex(VALUE); + int resetPosition = this.contentsOffset; + this.contents[this.contentsOffset++] = (byte) (elementNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) elementNameIndex; + MethodBinding methodBinding = singleMemberAnnotation.memberValuePairs()[0].binding; + if (methodBinding == null) { + this.contentsOffset = resetPosition; + } else { + int memberValuePairOffset = this.contentsOffset; + try { + generateElementValue(singleMemberAnnotation.memberValue, methodBinding.returnType, memberValuePairOffset); + if (this.contentsOffset == memberValuePairOffset) { + // ignore annotation value + this.contentsOffset = resetPosition; + } else { + memberValuePairCount++; + resetPosition = this.contentsOffset; + } + } catch(ClassCastException e) { + this.contentsOffset = resetPosition; + } catch(ShouldNotImplement e) { + this.contentsOffset = resetPosition; + } + } + this.contents[memberValuePairLengthPosition++] = (byte) (memberValuePairCount >> 8); + this.contents[memberValuePairLengthPosition++] = (byte) memberValuePairCount; + } else { + // this is a marker annotation (no member value pairs) + this.contents[this.contentsOffset++] = 0; + this.contents[this.contentsOffset++] = 0; + } + } + + private int generateAnnotationDefaultAttribute(AnnotationMethodDeclaration declaration, int attributeOffset) { + int attributesNumber = 0; + // add an annotation default attribute + int annotationDefaultNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.AnnotationDefaultName); + if (this.contentsOffset + 6 >= this.contents.length) { + resizeContents(6); + } + this.contents[this.contentsOffset++] = (byte) (annotationDefaultNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) annotationDefaultNameIndex; + int attributeLengthOffset = this.contentsOffset; + this.contentsOffset += 4; + generateElementValue(declaration.defaultValue, declaration.binding.returnType, attributeOffset); + if (this.contentsOffset != attributeOffset) { + int attributeLength = this.contentsOffset - attributeLengthOffset - 4; + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8); + this.contents[attributeLengthOffset++] = (byte) attributeLength; + attributesNumber++; + } + return attributesNumber; + } + /** + * INTERNAL USE-ONLY + * That method generates the header of a code attribute. + * - the index inside the constant pool for the attribute name ("Code") + * - leave some space for attribute_length(4), max_stack(2), max_locals(2), code_length(4). + */ + public void generateCodeAttributeHeader() { + if (this.contentsOffset + 20 >= this.contents.length) { + resizeContents(20); + } + int constantValueNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.CodeName); + this.contents[this.contentsOffset++] = (byte) (constantValueNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) constantValueNameIndex; + // leave space for attribute_length(4), max_stack(2), max_locals(2), code_length(4) + this.contentsOffset += 12; + } + + private int generateConstantValueAttribute(Constant fieldConstant, FieldBinding fieldBinding, int fieldAttributeOffset) { + int localContentsOffset = this.contentsOffset; + int attributesNumber = 1; + if (localContentsOffset + 8 >= this.contents.length) { + resizeContents(8); + } + // Now we generate the constant attribute corresponding to the fieldBinding + int constantValueNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.ConstantValueName); + this.contents[localContentsOffset++] = (byte) (constantValueNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) constantValueNameIndex; + // The attribute length = 2 in case of a constantValue attribute + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 2; + // Need to add the constant_value_index + switch (fieldConstant.typeID()) { + case T_boolean : + int booleanValueIndex = + this.constantPool.literalIndex(fieldConstant.booleanValue() ? 1 : 0); + this.contents[localContentsOffset++] = (byte) (booleanValueIndex >> 8); + this.contents[localContentsOffset++] = (byte) booleanValueIndex; + break; + case T_byte : + case T_char : + case T_int : + case T_short : + int integerValueIndex = + this.constantPool.literalIndex(fieldConstant.intValue()); + this.contents[localContentsOffset++] = (byte) (integerValueIndex >> 8); + this.contents[localContentsOffset++] = (byte) integerValueIndex; + break; + case T_float : + int floatValueIndex = + this.constantPool.literalIndex(fieldConstant.floatValue()); + this.contents[localContentsOffset++] = (byte) (floatValueIndex >> 8); + this.contents[localContentsOffset++] = (byte) floatValueIndex; + break; + case T_double : + int doubleValueIndex = + this.constantPool.literalIndex(fieldConstant.doubleValue()); + this.contents[localContentsOffset++] = (byte) (doubleValueIndex >> 8); + this.contents[localContentsOffset++] = (byte) doubleValueIndex; + break; + case T_long : + int longValueIndex = + this.constantPool.literalIndex(fieldConstant.longValue()); + this.contents[localContentsOffset++] = (byte) (longValueIndex >> 8); + this.contents[localContentsOffset++] = (byte) longValueIndex; + break; + case T_JavaLangString : + int stringValueIndex = + this.constantPool.literalIndex( + ((StringConstant) fieldConstant).stringValue()); + if (stringValueIndex == -1) { + if (!this.creatingProblemType) { + // report an error and abort: will lead to a problem type classfile creation + TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext; + FieldDeclaration[] fieldDecls = typeDeclaration.fields; + int max = fieldDecls == null ? 0 : fieldDecls.length; + for (int i = 0; i < max; i++) { + if (fieldDecls[i].binding == fieldBinding) { + // problem should abort + typeDeclaration.scope.problemReporter().stringConstantIsExceedingUtf8Limit( + fieldDecls[i]); + } + } + } else { + // already inside a problem type creation : no constant for this field + this.contentsOffset = fieldAttributeOffset; + attributesNumber = 0; + } + } else { + this.contents[localContentsOffset++] = (byte) (stringValueIndex >> 8); + this.contents[localContentsOffset++] = (byte) stringValueIndex; + } + } + this.contentsOffset = localContentsOffset; + return attributesNumber; + } + private int generateDeprecatedAttribute() { + int localContentsOffset = this.contentsOffset; + if (localContentsOffset + 6 >= this.contents.length) { + resizeContents(6); + } + int deprecatedAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.DeprecatedName); + this.contents[localContentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) deprecatedAttributeNameIndex; + // the length of a deprecated attribute is equals to 0 + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contentsOffset = localContentsOffset; + return 1; + } + private void generateElementValue( + Expression defaultValue, + TypeBinding memberValuePairReturnType, + int attributeOffset) { + Constant constant = defaultValue.constant; + TypeBinding defaultValueBinding = defaultValue.resolvedType; + if (defaultValueBinding == null) { + this.contentsOffset = attributeOffset; + } else { + if (defaultValueBinding.isMemberType()) { + this.recordInnerClasses(defaultValueBinding); + } + if (memberValuePairReturnType.isMemberType()) { + this.recordInnerClasses(memberValuePairReturnType); + } + if (memberValuePairReturnType.isArrayType() && !defaultValueBinding.isArrayType()) { + // automatic wrapping + if (this.contentsOffset + 3 >= this.contents.length) { + resizeContents(3); + } + this.contents[this.contentsOffset++] = (byte) '['; + this.contents[this.contentsOffset++] = (byte) 0; + this.contents[this.contentsOffset++] = (byte) 1; + } + if (constant != null && constant != Constant.NotAConstant) { + generateElementValue(attributeOffset, defaultValue, constant, memberValuePairReturnType.leafComponentType()); + } else { + generateElementValueForNonConstantExpression(defaultValue, attributeOffset, defaultValueBinding); + } + } + } + /** + * @param attributeOffset + */ + private void generateElementValue(int attributeOffset, Expression defaultValue, Constant constant, TypeBinding binding) { + if (this.contentsOffset + 3 >= this.contents.length) { + resizeContents(3); + } + switch (binding.id) { + case T_boolean : + this.contents[this.contentsOffset++] = (byte) 'Z'; + int booleanValueIndex = + this.constantPool.literalIndex(constant.booleanValue() ? 1 : 0); + this.contents[this.contentsOffset++] = (byte) (booleanValueIndex >> 8); + this.contents[this.contentsOffset++] = (byte) booleanValueIndex; + break; + case T_byte : + this.contents[this.contentsOffset++] = (byte) 'B'; + int integerValueIndex = + this.constantPool.literalIndex(constant.intValue()); + this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8); + this.contents[this.contentsOffset++] = (byte) integerValueIndex; + break; + case T_char : + this.contents[this.contentsOffset++] = (byte) 'C'; + integerValueIndex = + this.constantPool.literalIndex(constant.intValue()); + this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8); + this.contents[this.contentsOffset++] = (byte) integerValueIndex; + break; + case T_int : + this.contents[this.contentsOffset++] = (byte) 'I'; + integerValueIndex = + this.constantPool.literalIndex(constant.intValue()); + this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8); + this.contents[this.contentsOffset++] = (byte) integerValueIndex; + break; + case T_short : + this.contents[this.contentsOffset++] = (byte) 'S'; + integerValueIndex = + this.constantPool.literalIndex(constant.intValue()); + this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8); + this.contents[this.contentsOffset++] = (byte) integerValueIndex; + break; + case T_float : + this.contents[this.contentsOffset++] = (byte) 'F'; + int floatValueIndex = + this.constantPool.literalIndex(constant.floatValue()); + this.contents[this.contentsOffset++] = (byte) (floatValueIndex >> 8); + this.contents[this.contentsOffset++] = (byte) floatValueIndex; + break; + case T_double : + this.contents[this.contentsOffset++] = (byte) 'D'; + int doubleValueIndex = + this.constantPool.literalIndex(constant.doubleValue()); + this.contents[this.contentsOffset++] = (byte) (doubleValueIndex >> 8); + this.contents[this.contentsOffset++] = (byte) doubleValueIndex; + break; + case T_long : + this.contents[this.contentsOffset++] = (byte) 'J'; + int longValueIndex = + this.constantPool.literalIndex(constant.longValue()); + this.contents[this.contentsOffset++] = (byte) (longValueIndex >> 8); + this.contents[this.contentsOffset++] = (byte) longValueIndex; + break; + case T_JavaLangString : + this.contents[this.contentsOffset++] = (byte) 's'; + int stringValueIndex = + this.constantPool.literalIndex(((StringConstant) constant).stringValue().toCharArray()); + if (stringValueIndex == -1) { + if (!this.creatingProblemType) { + // report an error and abort: will lead to a problem type classfile creation + TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext; + typeDeclaration.scope.problemReporter().stringConstantIsExceedingUtf8Limit(defaultValue); + } else { + // already inside a problem type creation : no attribute + this.contentsOffset = attributeOffset; + } + } else { + this.contents[this.contentsOffset++] = (byte) (stringValueIndex >> 8); + this.contents[this.contentsOffset++] = (byte) stringValueIndex; + } + } + } + + private void generateElementValueForNonConstantExpression(Expression defaultValue, int attributeOffset, TypeBinding defaultValueBinding) { + if (defaultValueBinding != null) { + if (defaultValueBinding.isEnum()) { + if (this.contentsOffset + 5 >= this.contents.length) { + resizeContents(5); + } + this.contents[this.contentsOffset++] = (byte) 'e'; + FieldBinding fieldBinding = null; + if (defaultValue instanceof QualifiedNameReference) { + QualifiedNameReference nameReference = (QualifiedNameReference) defaultValue; + fieldBinding = (FieldBinding) nameReference.binding; + } else if (defaultValue instanceof SingleNameReference) { + SingleNameReference nameReference = (SingleNameReference) defaultValue; + fieldBinding = (FieldBinding) nameReference.binding; + } else { + this.contentsOffset = attributeOffset; + } + if (fieldBinding != null) { + final int enumConstantTypeNameIndex = this.constantPool.literalIndex(fieldBinding.type.signature()); + final int enumConstantNameIndex = this.constantPool.literalIndex(fieldBinding.name); + this.contents[this.contentsOffset++] = (byte) (enumConstantTypeNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) enumConstantTypeNameIndex; + this.contents[this.contentsOffset++] = (byte) (enumConstantNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) enumConstantNameIndex; + } + } else if (defaultValueBinding.isAnnotationType()) { + if (this.contentsOffset + 1 >= this.contents.length) { + resizeContents(1); + } + this.contents[this.contentsOffset++] = (byte) '@'; + generateAnnotation((Annotation) defaultValue, attributeOffset); + } else if (defaultValueBinding.isArrayType()) { + // array type + if (this.contentsOffset + 3 >= this.contents.length) { + resizeContents(3); + } + this.contents[this.contentsOffset++] = (byte) '['; + if (defaultValue instanceof ArrayInitializer) { + ArrayInitializer arrayInitializer = (ArrayInitializer) defaultValue; + int arrayLength = arrayInitializer.expressions != null ? arrayInitializer.expressions.length : 0; + this.contents[this.contentsOffset++] = (byte) (arrayLength >> 8); + this.contents[this.contentsOffset++] = (byte) arrayLength; + for (int i = 0; i < arrayLength; i++) { + generateElementValue(arrayInitializer.expressions[i], defaultValueBinding.leafComponentType(), attributeOffset); + } + } else { + this.contentsOffset = attributeOffset; + } + } else { + // class type + if (this.contentsOffset + 3 >= this.contents.length) { + resizeContents(3); + } + this.contents[this.contentsOffset++] = (byte) 'c'; + if (defaultValue instanceof ClassLiteralAccess) { + ClassLiteralAccess classLiteralAccess = (ClassLiteralAccess) defaultValue; + final int classInfoIndex = this.constantPool.literalIndex(classLiteralAccess.targetType.signature()); + this.contents[this.contentsOffset++] = (byte) (classInfoIndex >> 8); + this.contents[this.contentsOffset++] = (byte) classInfoIndex; + } else { + this.contentsOffset = attributeOffset; + } + } + } else { + this.contentsOffset = attributeOffset; + } + } + + private int generateEnclosingMethodAttribute() { + int localContentsOffset = this.contentsOffset; + // add enclosing method attribute (1.5 mode only) + if (localContentsOffset + 10 >= this.contents.length) { + resizeContents(10); + } + int enclosingMethodAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.EnclosingMethodName); + this.contents[localContentsOffset++] = (byte) (enclosingMethodAttributeNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) enclosingMethodAttributeNameIndex; + // the length of a signature attribute is equals to 2 + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 4; + + int enclosingTypeIndex = this.constantPool.literalIndexForType(this.referenceBinding.enclosingType().constantPoolName()); + this.contents[localContentsOffset++] = (byte) (enclosingTypeIndex >> 8); + this.contents[localContentsOffset++] = (byte) enclosingTypeIndex; + byte methodIndexByte1 = 0; + byte methodIndexByte2 = 0; + if (this.referenceBinding instanceof LocalTypeBinding) { + MethodBinding methodBinding = ((LocalTypeBinding) this.referenceBinding).enclosingMethod; + if (methodBinding != null) { + int enclosingMethodIndex = this.constantPool.literalIndexForNameAndType(methodBinding.selector, methodBinding.signature(this)); + methodIndexByte1 = (byte) (enclosingMethodIndex >> 8); + methodIndexByte2 = (byte) enclosingMethodIndex; + } + } + this.contents[localContentsOffset++] = methodIndexByte1; + this.contents[localContentsOffset++] = methodIndexByte2; + this.contentsOffset = localContentsOffset; + return 1; + } + private int generateExceptionsAttribute(ReferenceBinding[] thrownsExceptions) { + int localContentsOffset = this.contentsOffset; + int length = thrownsExceptions.length; + int exSize = 8 + length * 2; + if (exSize + this.contentsOffset >= this.contents.length) { + resizeContents(exSize); + } + int exceptionNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.ExceptionsName); + this.contents[localContentsOffset++] = (byte) (exceptionNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) exceptionNameIndex; + // The attribute length = length * 2 + 2 in case of a exception attribute + int attributeLength = length * 2 + 2; + this.contents[localContentsOffset++] = (byte) (attributeLength >> 24); + this.contents[localContentsOffset++] = (byte) (attributeLength >> 16); + this.contents[localContentsOffset++] = (byte) (attributeLength >> 8); + this.contents[localContentsOffset++] = (byte) attributeLength; + this.contents[localContentsOffset++] = (byte) (length >> 8); + this.contents[localContentsOffset++] = (byte) length; + for (int i = 0; i < length; i++) { + int exceptionIndex = this.constantPool.literalIndexForType(thrownsExceptions[i]); + this.contents[localContentsOffset++] = (byte) (exceptionIndex >> 8); + this.contents[localContentsOffset++] = (byte) exceptionIndex; + } + this.contentsOffset = localContentsOffset; + return 1; + } + private int generateHierarchyInconsistentAttribute() { + int localContentsOffset = this.contentsOffset; + // add an attribute for inconsistent hierarchy + if (localContentsOffset + 6 >= this.contents.length) { + resizeContents(6); + } + int inconsistentHierarchyNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.InconsistentHierarchy); + this.contents[localContentsOffset++] = (byte) (inconsistentHierarchyNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) inconsistentHierarchyNameIndex; + // the length of an inconsistent hierarchy attribute is equals to 0 + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contentsOffset = localContentsOffset; + return 1; + } + private int generateInnerClassAttribute(int numberOfInnerClasses, ReferenceBinding[] innerClasses) { + int localContentsOffset = this.contentsOffset; + // Generate the inner class attribute + int exSize = 8 * numberOfInnerClasses + 8; + if (exSize + localContentsOffset >= this.contents.length) { + resizeContents(exSize); + } + // Now we now the size of the attribute and the number of entries + // attribute name + int attributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.InnerClassName); + this.contents[localContentsOffset++] = (byte) (attributeNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) attributeNameIndex; + int value = (numberOfInnerClasses << 3) + 2; + this.contents[localContentsOffset++] = (byte) (value >> 24); + this.contents[localContentsOffset++] = (byte) (value >> 16); + this.contents[localContentsOffset++] = (byte) (value >> 8); + this.contents[localContentsOffset++] = (byte) value; + this.contents[localContentsOffset++] = (byte) (numberOfInnerClasses >> 8); + this.contents[localContentsOffset++] = (byte) numberOfInnerClasses; + for (int i = 0; i < numberOfInnerClasses; i++) { + ReferenceBinding innerClass = innerClasses[i]; + int accessFlags = innerClass.getAccessFlags(); + int innerClassIndex = this.constantPool.literalIndexForType(innerClass.constantPoolName()); + // inner class index + this.contents[localContentsOffset++] = (byte) (innerClassIndex >> 8); + this.contents[localContentsOffset++] = (byte) innerClassIndex; + // outer class index: anonymous and local have no outer class index + if (innerClass.isMemberType()) { + // member or member of local + int outerClassIndex = this.constantPool.literalIndexForType(innerClass.enclosingType().constantPoolName()); + this.contents[localContentsOffset++] = (byte) (outerClassIndex >> 8); + this.contents[localContentsOffset++] = (byte) outerClassIndex; + } else { + // equals to 0 if the innerClass is not a member type + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + } + // name index + if (!innerClass.isAnonymousType()) { + int nameIndex = this.constantPool.literalIndex(innerClass.sourceName()); + this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); + this.contents[localContentsOffset++] = (byte) nameIndex; + } else { + // equals to 0 if the innerClass is an anonymous type + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + } + // access flag + if (innerClass.isAnonymousType()) { + accessFlags &= ~ClassFileConstants.AccFinal; + } else if (innerClass.isMemberType() && innerClass.isInterface()) { + accessFlags |= ClassFileConstants.AccStatic; // implicitely static + } + this.contents[localContentsOffset++] = (byte) (accessFlags >> 8); + this.contents[localContentsOffset++] = (byte) accessFlags; + } + this.contentsOffset = localContentsOffset; + return 1; + } + + private int generateBootstrapMethods(List functionalExpressionList) { + /* See JVM spec 4.7.21 + The BootstrapMethods attribute has the following format: + BootstrapMethods_attribute { + u2 attribute_name_index; + u4 attribute_length; + u2 num_bootstrap_methods; + { u2 bootstrap_method_ref; + u2 num_bootstrap_arguments; + u2 bootstrap_arguments[num_bootstrap_arguments]; + } bootstrap_methods[num_bootstrap_methods]; + } + */ + // Record inner classes for MethodHandles$Lookup + ReferenceBinding methodHandlesLookup = this.referenceBinding.scope.getJavaLangInvokeMethodHandlesLookup(); + if (methodHandlesLookup == null) return 0; // skip bootstrap section, class path problem already reported, just avoid NPE. + recordInnerClasses(methodHandlesLookup); // Should be done, it's what javac does also + ReferenceBinding javaLangInvokeLambdaMetafactory = this.referenceBinding.scope.getJavaLangInvokeLambdaMetafactory(); + + // Depending on the complexity of the expression it may be necessary to use the altMetafactory() rather than the metafactory() + int indexForMetaFactory = 0; + int indexForAltMetaFactory = 0; + + int numberOfBootstraps = functionalExpressionList.size(); + int localContentsOffset = this.contentsOffset; + // Generate the boot strap attribute - since we are only making lambdas and + // functional expressions, we know the size ahead of time - this less general + // than the full invokedynamic scope, but fine for Java 8 + + final int contentsEntries = 10; + int exSize = contentsEntries * numberOfBootstraps + 8; + if (exSize + localContentsOffset >= this.contents.length) { + resizeContents(exSize); + } + + int attributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.BootstrapMethodsName); + this.contents[localContentsOffset++] = (byte) (attributeNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) attributeNameIndex; + // leave space for attribute_length and remember where to insert it + int attributeLengthPosition = localContentsOffset; + localContentsOffset += 4; + this.contents[localContentsOffset++] = (byte) (numberOfBootstraps >> 8); + this.contents[localContentsOffset++] = (byte) numberOfBootstraps; + for (int i = 0; i < numberOfBootstraps; i++) { + FunctionalExpression functional = (FunctionalExpression) functionalExpressionList.get(i); + MethodBinding [] bridges = functional.getRequiredBridges(); + TypeBinding[] markerInterfaces = null; + if (functional instanceof LambdaExpression && + (((markerInterfaces=((LambdaExpression)functional).getMarkerInterfaces()) != null) || + ((LambdaExpression)functional).isSerializable) || + bridges != null) { + + LambdaExpression lambdaEx = (LambdaExpression)functional; + // may need even more space + int extraSpace = 2; // at least 2 more than when the normal metafactory is used, for the bitflags entry + if (markerInterfaces != null) { + // 2 for the marker interface list size then 2 per marker interface index + extraSpace += (2 + 2 * markerInterfaces.length); + } + if (bridges != null) { + // 2 for bridge count then 2 per bridge method type. + extraSpace += (2 + 2 * bridges.length); + } + if (extraSpace + contentsEntries + localContentsOffset >= this.contents.length) { + resizeContents(extraSpace + contentsEntries); + } + + if (indexForAltMetaFactory == 0) { + indexForAltMetaFactory = + this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory, + ConstantPool.ALTMETAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_ALTMETAFACTORY_SIGNATURE, false); + } + this.contents[localContentsOffset++] = (byte) (indexForAltMetaFactory >> 8); + this.contents[localContentsOffset++] = (byte) indexForAltMetaFactory; + + // u2 num_bootstrap_arguments + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = (byte) (4 + (markerInterfaces==null?0:1+markerInterfaces.length) + + (bridges == null ? 0 : 1 + bridges.length)); + + int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature()); + this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8); + this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex; + + int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below. + this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8); + this.contents[localContentsOffset++] = (byte) methodHandleIndex; + + char [] instantiatedSignature = functional.descriptor.signature(); + int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature); + this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8); + this.contents[localContentsOffset++] = (byte) methodTypeIndex; + + int bitflags = 0; + if (lambdaEx.isSerializable) { + bitflags |= ClassFileConstants.FLAG_SERIALIZABLE; + } + if (markerInterfaces!=null) { + bitflags |= ClassFileConstants.FLAG_MARKERS; + } + if (bridges != null) { + bitflags |= ClassFileConstants.FLAG_BRIDGES; + } + int indexForBitflags = this.constantPool.literalIndex(bitflags); + + this.contents[localContentsOffset++] = (byte)(indexForBitflags>>8); + this.contents[localContentsOffset++] = (byte)(indexForBitflags); + + if (markerInterfaces != null) { + int markerInterfaceCountIndex = this.constantPool.literalIndex(markerInterfaces.length); + this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex>>8); + this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex); + for (int m = 0, maxm = markerInterfaces.length; m < maxm; m++) { + int classTypeIndex = this.constantPool.literalIndexForType(markerInterfaces[m]); + this.contents[localContentsOffset++] = (byte)(classTypeIndex>>8); + this.contents[localContentsOffset++] = (byte)(classTypeIndex); + } + } + if (bridges != null) { + int bridgeCountIndex = this.constantPool.literalIndex(bridges.length); + this.contents[localContentsOffset++] = (byte) (bridgeCountIndex >> 8); + this.contents[localContentsOffset++] = (byte) (bridgeCountIndex); + for (int m = 0, maxm = bridges.length; m < maxm; m++) { + char [] bridgeSignature = bridges[m].signature(); + int bridgeMethodTypeIndex = this.constantPool.literalIndexForMethodType(bridgeSignature); + this.contents[localContentsOffset++] = (byte) (bridgeMethodTypeIndex >> 8); + this.contents[localContentsOffset++] = (byte) bridgeMethodTypeIndex; + } + } + } else { + if (indexForMetaFactory == 0) { + indexForMetaFactory = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory, + ConstantPool.METAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_METAFACTORY_SIGNATURE, false); + } + this.contents[localContentsOffset++] = (byte) (indexForMetaFactory >> 8); + this.contents[localContentsOffset++] = (byte) indexForMetaFactory; + + // u2 num_bootstrap_arguments + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = (byte) 3; + + int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature()); + this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8); + this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex; + + int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below. + this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8); + this.contents[localContentsOffset++] = (byte) methodHandleIndex; + + char [] instantiatedSignature = functional.descriptor.signature(); + int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature); + this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8); + this.contents[localContentsOffset++] = (byte) methodTypeIndex; + } + } + + int attributeLength = localContentsOffset - attributeLengthPosition - 4; + this.contents[attributeLengthPosition++] = (byte) (attributeLength >> 24); + this.contents[attributeLengthPosition++] = (byte) (attributeLength >> 16); + this.contents[attributeLengthPosition++] = (byte) (attributeLength >> 8); + this.contents[attributeLengthPosition++] = (byte) attributeLength; + this.contentsOffset = localContentsOffset; + return 1; + } + private int generateLineNumberAttribute() { + int localContentsOffset = this.contentsOffset; + int attributesNumber = 0; + /* Create and add the line number attribute (used for debugging) + * Build the pairs of: + * (bytecodePC lineNumber) + * according to the table of start line indexes and the pcToSourceMap table + * contained into the codestream + */ + int[] pcToSourceMapTable; + if (((pcToSourceMapTable = this.codeStream.pcToSourceMap) != null) + && (this.codeStream.pcToSourceMapSize != 0)) { + int lineNumberNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName); + if (localContentsOffset + 8 >= this.contents.length) { + resizeContents(8); + } + this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) lineNumberNameIndex; + int lineNumberTableOffset = localContentsOffset; + localContentsOffset += 6; + // leave space for attribute_length and line_number_table_length + int numberOfEntries = 0; + int length = this.codeStream.pcToSourceMapSize; + for (int i = 0; i < length;) { + // write the entry + if (localContentsOffset + 4 >= this.contents.length) { + resizeContents(4); + } + int pc = pcToSourceMapTable[i++]; + this.contents[localContentsOffset++] = (byte) (pc >> 8); + this.contents[localContentsOffset++] = (byte) pc; + int lineNumber = pcToSourceMapTable[i++]; + this.contents[localContentsOffset++] = (byte) (lineNumber >> 8); + this.contents[localContentsOffset++] = (byte) lineNumber; + numberOfEntries++; + } + // now we change the size of the line number attribute + int lineNumberAttr_length = numberOfEntries * 4 + 2; + this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24); + this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16); + this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8); + this.contents[lineNumberTableOffset++] = (byte) lineNumberAttr_length; + this.contents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8); + this.contents[lineNumberTableOffset++] = (byte) numberOfEntries; + attributesNumber = 1; + } + this.contentsOffset = localContentsOffset; + return attributesNumber; + } + // this is used for problem and synthetic methods + private int generateLineNumberAttribute(int problemLine) { + int localContentsOffset = this.contentsOffset; + if (localContentsOffset + 12 >= this.contents.length) { + resizeContents(12); + } + /* Create and add the line number attribute (used for debugging) + * Build the pairs of: + * (bytecodePC lineNumber) + * according to the table of start line indexes and the pcToSourceMap table + * contained into the codestream + */ + int lineNumberNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName); + this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) lineNumberNameIndex; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 6; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 1; + // first entry at pc = 0 + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = (byte) (problemLine >> 8); + this.contents[localContentsOffset++] = (byte) problemLine; + // now we change the size of the line number attribute + this.contentsOffset = localContentsOffset; + return 1; + } + + private int generateLocalVariableTableAttribute(int code_length, boolean methodDeclarationIsStatic, boolean isSynthetic) { + int attributesNumber = 0; + int localContentsOffset = this.contentsOffset; + int numberOfEntries = 0; + int localVariableNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName); + int maxOfEntries = 8 + 10 * (methodDeclarationIsStatic ? 0 : 1); + for (int i = 0; i < this.codeStream.allLocalsCounter; i++) { + LocalVariableBinding localVariableBinding = this.codeStream.locals[i]; + maxOfEntries += 10 * localVariableBinding.initializationCount; + } + // reserve enough space + if (localContentsOffset + maxOfEntries >= this.contents.length) { + resizeContents(maxOfEntries); + } + this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) localVariableNameIndex; + int localVariableTableOffset = localContentsOffset; + // leave space for attribute_length and local_variable_table_length + localContentsOffset += 6; + int nameIndex; + int descriptorIndex; + SourceTypeBinding declaringClassBinding = null; + if (!methodDeclarationIsStatic && !isSynthetic) { + numberOfEntries++; + this.contents[localContentsOffset++] = 0; // the startPC for this is always 0 + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = (byte) (code_length >> 8); + this.contents[localContentsOffset++] = (byte) code_length; + nameIndex = this.constantPool.literalIndex(ConstantPool.This); + this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); + this.contents[localContentsOffset++] = (byte) nameIndex; + declaringClassBinding = (SourceTypeBinding) + (this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.binding.declaringClass : this.codeStream.lambdaExpression.binding.declaringClass); + descriptorIndex = + this.constantPool.literalIndex( + declaringClassBinding.signature()); + this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); + this.contents[localContentsOffset++] = (byte) descriptorIndex; + this.contents[localContentsOffset++] = 0;// the resolved position for this is always 0 + this.contents[localContentsOffset++] = 0; + } + // used to remember the local variable with a generic type + int genericLocalVariablesCounter = 0; + LocalVariableBinding[] genericLocalVariables = null; + int numberOfGenericEntries = 0; + + for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) { + LocalVariableBinding localVariable = this.codeStream.locals[i]; + int initializationCount = localVariable.initializationCount; + if (initializationCount == 0) continue; + if (localVariable.declaration == null) continue; + final TypeBinding localVariableTypeBinding = localVariable.type; + boolean isParameterizedType = localVariableTypeBinding.isParameterizedType() || localVariableTypeBinding.isTypeVariable(); + if (isParameterizedType) { + if (genericLocalVariables == null) { + // we cannot have more than max locals + genericLocalVariables = new LocalVariableBinding[max]; + } + genericLocalVariables[genericLocalVariablesCounter++] = localVariable; + } + for (int j = 0; j < initializationCount; j++) { + int startPC = localVariable.initializationPCs[j << 1]; + int endPC = localVariable.initializationPCs[(j << 1) + 1]; + if (startPC != endPC) { // only entries for non zero length + if (endPC == -1) { + localVariable.declaringScope.problemReporter().abortDueToInternalError( + Messages.bind(Messages.abort_invalidAttribute, new String(localVariable.name)), + (ASTNode) localVariable.declaringScope.methodScope().referenceContext); + } + if (isParameterizedType) { + numberOfGenericEntries++; + } + // now we can safely add the local entry + numberOfEntries++; + this.contents[localContentsOffset++] = (byte) (startPC >> 8); + this.contents[localContentsOffset++] = (byte) startPC; + int length = endPC - startPC; + this.contents[localContentsOffset++] = (byte) (length >> 8); + this.contents[localContentsOffset++] = (byte) length; + nameIndex = this.constantPool.literalIndex(localVariable.name); + this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); + this.contents[localContentsOffset++] = (byte) nameIndex; + descriptorIndex = this.constantPool.literalIndex(localVariableTypeBinding.signature()); + this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); + this.contents[localContentsOffset++] = (byte) descriptorIndex; + int resolvedPosition = localVariable.resolvedPosition; + this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8); + this.contents[localContentsOffset++] = (byte) resolvedPosition; + } + } + } + int value = numberOfEntries * 10 + 2; + this.contents[localVariableTableOffset++] = (byte) (value >> 24); + this.contents[localVariableTableOffset++] = (byte) (value >> 16); + this.contents[localVariableTableOffset++] = (byte) (value >> 8); + this.contents[localVariableTableOffset++] = (byte) value; + this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8); + this.contents[localVariableTableOffset] = (byte) numberOfEntries; + attributesNumber++; + + final boolean currentInstanceIsGeneric = + !methodDeclarationIsStatic + && declaringClassBinding != null + && declaringClassBinding.typeVariables != Binding.NO_TYPE_VARIABLES; + if (genericLocalVariablesCounter != 0 || currentInstanceIsGeneric) { + // add the local variable type table attribute + numberOfGenericEntries += (currentInstanceIsGeneric ? 1 : 0); + maxOfEntries = 8 + numberOfGenericEntries * 10; + // reserve enough space + if (localContentsOffset + maxOfEntries >= this.contents.length) { + resizeContents(maxOfEntries); + } + int localVariableTypeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTypeTableName); + this.contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) localVariableTypeNameIndex; + value = numberOfGenericEntries * 10 + 2; + this.contents[localContentsOffset++] = (byte) (value >> 24); + this.contents[localContentsOffset++] = (byte) (value >> 16); + this.contents[localContentsOffset++] = (byte) (value >> 8); + this.contents[localContentsOffset++] = (byte) value; + this.contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8); + this.contents[localContentsOffset++] = (byte) numberOfGenericEntries; + if (currentInstanceIsGeneric) { + this.contents[localContentsOffset++] = 0; // the startPC for this is always 0 + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = (byte) (code_length >> 8); + this.contents[localContentsOffset++] = (byte) code_length; + nameIndex = this.constantPool.literalIndex(ConstantPool.This); + this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); + this.contents[localContentsOffset++] = (byte) nameIndex; + descriptorIndex = this.constantPool.literalIndex(declaringClassBinding.genericTypeSignature()); + this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); + this.contents[localContentsOffset++] = (byte) descriptorIndex; + this.contents[localContentsOffset++] = 0;// the resolved position for this is always 0 + this.contents[localContentsOffset++] = 0; + } + + for (int i = 0; i < genericLocalVariablesCounter; i++) { + LocalVariableBinding localVariable = genericLocalVariables[i]; + for (int j = 0; j < localVariable.initializationCount; j++) { + int startPC = localVariable.initializationPCs[j << 1]; + int endPC = localVariable.initializationPCs[(j << 1) + 1]; + if (startPC != endPC) { + // only entries for non zero length + // now we can safely add the local entry + this.contents[localContentsOffset++] = (byte) (startPC >> 8); + this.contents[localContentsOffset++] = (byte) startPC; + int length = endPC - startPC; + this.contents[localContentsOffset++] = (byte) (length >> 8); + this.contents[localContentsOffset++] = (byte) length; + nameIndex = this.constantPool.literalIndex(localVariable.name); + this.contents[localContentsOffset++] = (byte) (nameIndex >> 8); + this.contents[localContentsOffset++] = (byte) nameIndex; + descriptorIndex = this.constantPool.literalIndex(localVariable.type.genericTypeSignature()); + this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8); + this.contents[localContentsOffset++] = (byte) descriptorIndex; + int resolvedPosition = localVariable.resolvedPosition; + this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8); + this.contents[localContentsOffset++] = (byte) resolvedPosition; + } + } + } + attributesNumber++; + } + this.contentsOffset = localContentsOffset; + return attributesNumber; + } + /** + * INTERNAL USE-ONLY + * That method generates the attributes of a code attribute. + * They could be: + * - an exception attribute for each try/catch found inside the method + * - a deprecated attribute + * - a synthetic attribute for synthetic access methods + * + * It returns the number of attributes created for the code attribute. + * + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding + * @return <CODE>int</CODE> + */ + public int generateMethodInfoAttributes(MethodBinding methodBinding, List extraAttributes) { // AspectJ: extra parameter + // leave two bytes for the attribute_number + this.contentsOffset += 2; + if (this.contentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + // now we can handle all the attribute for that method info: + // it could be: + // - a CodeAttribute + // - a ExceptionAttribute + // - a DeprecatedAttribute + // - a SyntheticAttribute + + // Exception attribute + ReferenceBinding[] thrownsExceptions; + int attributesNumber = 0; + if ((thrownsExceptions = methodBinding.thrownExceptions) != Binding.NO_EXCEPTIONS) { + // The method has a throw clause. So we need to add an exception attribute + // check that there is enough space to write all the bytes for the exception attribute + attributesNumber += generateExceptionsAttribute(thrownsExceptions); + } + if (methodBinding.isDeprecated()) { + // Deprecated attribute + attributesNumber += generateDeprecatedAttribute(); + } + if (this.targetJDK < ClassFileConstants.JDK1_5) { + if (methodBinding.isSynthetic()) { + attributesNumber += generateSyntheticAttribute(); + } + if (methodBinding.isVarargs()) { + attributesNumber += generateVarargsAttribute(); + } + } + // add signature attribute + char[] genericSignature = methodBinding.genericSignature(); + if (genericSignature != null) { + attributesNumber += generateSignatureAttribute(genericSignature); + } + if (this.targetJDK >= ClassFileConstants.JDK1_4) { + AbstractMethodDeclaration methodDeclaration = methodBinding.sourceMethod(); + if (methodBinding instanceof SyntheticMethodBinding) { + SyntheticMethodBinding syntheticMethod = (SyntheticMethodBinding) methodBinding; + if (syntheticMethod.purpose == SyntheticMethodBinding.SuperMethodAccess && CharOperation.equals(syntheticMethod.selector, syntheticMethod.targetMethod.selector)) + methodDeclaration = ((SyntheticMethodBinding)methodBinding).targetMethod.sourceMethod(); + } + if (methodDeclaration != null) { + Annotation[] annotations = methodDeclaration.annotations; + if (annotations != null) { + attributesNumber += generateRuntimeAnnotations(annotations, methodBinding.isConstructor() ? TagBits.AnnotationForConstructor : TagBits.AnnotationForMethod); + } + if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) { + Argument[] arguments = methodDeclaration.arguments; + if (arguments != null) { + attributesNumber += generateRuntimeAnnotationsForParameters(arguments); + } + } + } else { + LambdaExpression lambda = methodBinding.sourceLambda(); + if (lambda != null) { + if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) { + Argument[] arguments = lambda.arguments(); + if (arguments != null) { + int parameterCount = methodBinding.parameters.length; + int argumentCount = arguments.length; + if (parameterCount > argumentCount) { // synthetics prefixed + int redShift = parameterCount - argumentCount; + System.arraycopy(arguments, 0, arguments = new Argument[parameterCount], redShift, argumentCount); + for (int i = 0; i < redShift; i++) + arguments[i] = new Argument(CharOperation.NO_CHAR, 0, null, 0); + } + attributesNumber += generateRuntimeAnnotationsForParameters(arguments); + } + } + } + } + } + if ((methodBinding.tagBits & TagBits.HasMissingType) != 0) { + this.missingTypes = methodBinding.collectMissingTypes(this.missingTypes); + } + // AspectJ Extension + if (extraAttributes != null) { + for (int i=0, len = extraAttributes.size(); i < len; i++) { + IAttribute attribute = (IAttribute)extraAttributes.get(i); + short nameIndex = (short)constantPool.literalIndex(attribute.getNameChars()); + writeToContents(attribute.getAllBytes(nameIndex,constantPool)); + attributesNumber++; + } + } + // End AspectJ Extension + return attributesNumber; + } + // AspectJ Extension - new method stub that can pass 3rd param + public int generateMethodInfoAttributes(MethodBinding methodBinding) { + return generateMethodInfoAttributes(methodBinding,(List)null); + } + // End AspectJ Extension + public int generateMethodInfoAttributes(MethodBinding methodBinding, AnnotationMethodDeclaration declaration) { + int attributesNumber = generateMethodInfoAttributes(methodBinding); + int attributeOffset = this.contentsOffset; + if ((declaration.modifiers & ClassFileConstants.AccAnnotationDefault) != 0) { + // add an annotation default attribute + attributesNumber += generateAnnotationDefaultAttribute(declaration, attributeOffset); + } + return attributesNumber; + } + /** + * INTERNAL USE-ONLY + * That method generates the header of a method info: + * The header consists in: + * - the access flags + * - the name index of the method name inside the constant pool + * - the descriptor index of the signature of the method inside the constant pool. + * + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding + */ + public void generateMethodInfoHeader(MethodBinding methodBinding) { + generateMethodInfoHeader(methodBinding, methodBinding.modifiers); + } + + /** + * INTERNAL USE-ONLY + * That method generates the header of a method info: + * The header consists in: + * - the access flags + * - the name index of the method name inside the constant pool + * - the descriptor index of the signature of the method inside the constant pool. + * + * @param methodBinding org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding + * @param accessFlags the access flags + */ + public void generateMethodInfoHeader(MethodBinding methodBinding, int accessFlags) { + // check that there is enough space to write all the bytes for the method info corresponding + // to the @methodBinding + this.methodCount++; // add one more method + if (this.contentsOffset + 10 >= this.contents.length) { + resizeContents(10); + } + if (this.targetJDK < ClassFileConstants.JDK1_5) { + // pre 1.5, synthetic is an attribute, not a modifier + // pre 1.5, varargs is an attribute, not a modifier (-target jsr14 mode) + accessFlags &= ~(ClassFileConstants.AccSynthetic | ClassFileConstants.AccVarargs); + } + if ((methodBinding.tagBits & TagBits.ClearPrivateModifier) != 0) { + accessFlags &= ~ClassFileConstants.AccPrivate; + } + this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8); + this.contents[this.contentsOffset++] = (byte) accessFlags; + int nameIndex = this.constantPool.literalIndex(methodBinding.selector); + this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) nameIndex; + int descriptorIndex = this.constantPool.literalIndex(methodBinding.signature(this)); + this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8); + this.contents[this.contentsOffset++] = (byte) descriptorIndex; + } + + public void addSyntheticDeserializeLambda(SyntheticMethodBinding methodBinding, SyntheticMethodBinding[] syntheticMethodBindings ) { + generateMethodInfoHeader(methodBinding); + int methodAttributeOffset = this.contentsOffset; + // this will add exception attribute, synthetic attribute, deprecated attribute,... + int attributeNumber = generateMethodInfoAttributes(methodBinding); + // Code attribute + int codeAttributeOffset = this.contentsOffset; + attributeNumber++; // add code attribute + generateCodeAttributeHeader(); + this.codeStream.init(this); + this.codeStream.generateSyntheticBodyForDeserializeLambda(methodBinding, syntheticMethodBindings); + completeCodeAttributeForSyntheticMethod( + methodBinding, + codeAttributeOffset, + ((SourceTypeBinding) methodBinding.declaringClass) + .scope + .referenceCompilationUnit() + .compilationResult + .getLineSeparatorPositions()); + // update the number of attributes + if ((this.produceAttributes & ClassFileConstants.ATTR_METHOD_PARAMETERS) != 0) { + attributeNumber += generateMethodParameters(methodBinding); + } + this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8); + this.contents[methodAttributeOffset] = (byte) attributeNumber; + } + + /** + * INTERNAL USE-ONLY + * That method generates the method info header of a clinit: + * The header consists in: + * - the access flags (always default access + static) + * - the name index of the method name (always <clinit>) inside the constant pool + * - the descriptor index of the signature (always ()V) of the method inside the constant pool. + */ + public void generateMethodInfoHeaderForClinit() { + // check that there is enough space to write all the bytes for the method info corresponding + // to the @methodBinding + this.methodCount++; // add one more method + if (this.contentsOffset + 10 >= this.contents.length) { + resizeContents(10); + } + this.contents[this.contentsOffset++] = (byte) ((ClassFileConstants.AccDefault | ClassFileConstants.AccStatic) >> 8); + this.contents[this.contentsOffset++] = (byte) (ClassFileConstants.AccDefault | ClassFileConstants.AccStatic); + int nameIndex = this.constantPool.literalIndex(ConstantPool.Clinit); + this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) nameIndex; + int descriptorIndex = + this.constantPool.literalIndex(ConstantPool.ClinitSignature); + this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8); + this.contents[this.contentsOffset++] = (byte) descriptorIndex; + // We know that we won't get more than 1 attribute: the code attribute + this.contents[this.contentsOffset++] = 0; + this.contents[this.contentsOffset++] = 1; + } + + /** + * INTERNAL USE-ONLY + * Generate the byte for problem method infos that correspond to missing abstract methods. + * http://dev.eclipse.org/bugs/show_bug.cgi?id=3179 + * + * @param methodDeclarations Array of all missing abstract methods + */ + public void generateMissingAbstractMethods(MethodDeclaration[] methodDeclarations, CompilationResult compilationResult) { + if (methodDeclarations != null) { + TypeDeclaration currentDeclaration = this.referenceBinding.scope.referenceContext; + int typeDeclarationSourceStart = currentDeclaration.sourceStart(); + int typeDeclarationSourceEnd = currentDeclaration.sourceEnd(); + for (int i = 0, max = methodDeclarations.length; i < max; i++) { + MethodDeclaration methodDeclaration = methodDeclarations[i]; + MethodBinding methodBinding = methodDeclaration.binding; + String readableName = new String(methodBinding.readableName()); + CategorizedProblem[] problems = compilationResult.problems; + int problemsCount = compilationResult.problemCount; + for (int j = 0; j < problemsCount; j++) { + CategorizedProblem problem = problems[j]; + if (problem != null + && problem.getID() == IProblem.AbstractMethodMustBeImplemented + && problem.getMessage().indexOf(readableName) != -1 + && problem.getSourceStart() >= typeDeclarationSourceStart + && problem.getSourceEnd() <= typeDeclarationSourceEnd) { + // we found a match + addMissingAbstractProblemMethod(methodDeclaration, methodBinding, problem, compilationResult); + } + } + } + } + } + + private void generateMissingTypesAttribute() { + int initialSize = this.missingTypes.size(); + int[] missingTypesIndexes = new int[initialSize]; + int numberOfMissingTypes = 0; + if (initialSize > 1) { + Collections.sort(this.missingTypes, new Comparator() { + public int compare(Object o1, Object o2) { + TypeBinding typeBinding1 = (TypeBinding) o1; + TypeBinding typeBinding2 = (TypeBinding) o2; + return CharOperation.compareTo(typeBinding1.constantPoolName(), typeBinding2.constantPoolName()); + } + }); + } + int previousIndex = 0; + next: for (int i = 0; i < initialSize; i++) { + int missingTypeIndex = this.constantPool.literalIndexForType((TypeBinding) this.missingTypes.get(i)); + if (previousIndex == missingTypeIndex) { + continue next; + } + previousIndex = missingTypeIndex; + missingTypesIndexes[numberOfMissingTypes++] = missingTypeIndex; + } + // we don't need to resize as we interate from 0 to numberOfMissingTypes when recording the indexes in the .class file + int attributeLength = numberOfMissingTypes * 2 + 2; + if (this.contentsOffset + attributeLength + 6 >= this.contents.length) { + resizeContents(attributeLength + 6); + } + int missingTypesNameIndex = this.constantPool.literalIndex(AttributeNamesConstants.MissingTypesName); + this.contents[this.contentsOffset++] = (byte) (missingTypesNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) missingTypesNameIndex; + + // generate attribute length + this.contents[this.contentsOffset++] = (byte) (attributeLength >> 24); + this.contents[this.contentsOffset++] = (byte) (attributeLength >> 16); + this.contents[this.contentsOffset++] = (byte) (attributeLength >> 8); + this.contents[this.contentsOffset++] = (byte) attributeLength; + + // generate number of missing types + this.contents[this.contentsOffset++] = (byte) (numberOfMissingTypes >> 8); + this.contents[this.contentsOffset++] = (byte) numberOfMissingTypes; + // generate entry for each missing type + for (int i = 0; i < numberOfMissingTypes; i++) { + int missingTypeIndex = missingTypesIndexes[i]; + this.contents[this.contentsOffset++] = (byte) (missingTypeIndex >> 8); + this.contents[this.contentsOffset++] = (byte) missingTypeIndex; + } + } + + /** + * @param annotations + * @param targetMask allowed targets + * @return the number of attributes created while dumping the annotations in the .class file + */ + private int generateRuntimeAnnotations(final Annotation[] annotations, final long targetMask) { + int attributesNumber = 0; + final int length = annotations.length; + int visibleAnnotationsCounter = 0; + int invisibleAnnotationsCounter = 0; + for (int i = 0; i < length; i++) { + Annotation annotation; + if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container. + long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0; + // AspectJ Extension: this prevents a Type targeting annotation being stashed on a + // method representing an 'declare @type'. So don't enforce this restriction +// if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue; + // AspectJ Extension: End + if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible()) { + invisibleAnnotationsCounter++; + } else if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible()) { + visibleAnnotationsCounter++; + } + } + + int annotationAttributeOffset = this.contentsOffset; + int constantPOffset = this.constantPool.currentOffset; + int constantPoolIndex = this.constantPool.currentIndex; + if (invisibleAnnotationsCounter != 0) { + if (this.contentsOffset + 10 >= this.contents.length) { + resizeContents(10); + } + int runtimeInvisibleAnnotationsAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleAnnotationsName); + this.contents[this.contentsOffset++] = (byte) (runtimeInvisibleAnnotationsAttributeNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) runtimeInvisibleAnnotationsAttributeNameIndex; + int attributeLengthOffset = this.contentsOffset; + this.contentsOffset += 4; // leave space for the attribute length + + int annotationsLengthOffset = this.contentsOffset; + this.contentsOffset += 2; // leave space for the annotations length + + int counter = 0; + loop: for (int i = 0; i < length; i++) { + if (invisibleAnnotationsCounter == 0) break loop; + Annotation annotation; + if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container. + long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0; + // AspectJ Extension: this prevents a Type targeting annotation being stashed on a + // method representing an 'declare @type'. So don't enforce this restriction +// if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue; + // AspectJ Extension: end + if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible()) { + int currentAnnotationOffset = this.contentsOffset; + generateAnnotation(annotation, currentAnnotationOffset); + invisibleAnnotationsCounter--; + if (this.contentsOffset != currentAnnotationOffset) { + counter++; + } + } + } + if (counter != 0) { + this.contents[annotationsLengthOffset++] = (byte) (counter >> 8); + this.contents[annotationsLengthOffset++] = (byte) counter; + + int attributeLength = this.contentsOffset - attributeLengthOffset - 4; + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8); + this.contents[attributeLengthOffset++] = (byte) attributeLength; + attributesNumber++; + } else { + this.contentsOffset = annotationAttributeOffset; + // reset the constant pool to its state before the clinit + this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeInvisibleAnnotationsName, constantPoolIndex, constantPOffset); + } + } + + annotationAttributeOffset = this.contentsOffset; + constantPOffset = this.constantPool.currentOffset; + constantPoolIndex = this.constantPool.currentIndex; + if (visibleAnnotationsCounter != 0) { + if (this.contentsOffset + 10 >= this.contents.length) { + resizeContents(10); + } + int runtimeVisibleAnnotationsAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleAnnotationsName); + this.contents[this.contentsOffset++] = (byte) (runtimeVisibleAnnotationsAttributeNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) runtimeVisibleAnnotationsAttributeNameIndex; + int attributeLengthOffset = this.contentsOffset; + this.contentsOffset += 4; // leave space for the attribute length + + int annotationsLengthOffset = this.contentsOffset; + this.contentsOffset += 2; // leave space for the annotations length + + int counter = 0; + loop: for (int i = 0; i < length; i++) { + if (visibleAnnotationsCounter == 0) break loop; + Annotation annotation; + if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container. + long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0; + // AspectJ Extension: this prevents a Type targeting annotation being stashed on a + // method representing an 'declare @type'. So don't enforce this restriction +// if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue; + // AspectJ Extension: end + if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible()) { + visibleAnnotationsCounter--; + int currentAnnotationOffset = this.contentsOffset; + generateAnnotation(annotation, currentAnnotationOffset); + if (this.contentsOffset != currentAnnotationOffset) { + counter++; + } + } + } + if (counter != 0) { + this.contents[annotationsLengthOffset++] = (byte) (counter >> 8); + this.contents[annotationsLengthOffset++] = (byte) counter; + + int attributeLength = this.contentsOffset - attributeLengthOffset - 4; + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8); + this.contents[attributeLengthOffset++] = (byte) attributeLength; + attributesNumber++; + } else { + this.contentsOffset = annotationAttributeOffset; + this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeVisibleAnnotationsName, constantPoolIndex, constantPOffset); + } + } + return attributesNumber; + } + + private int generateRuntimeAnnotationsForParameters(Argument[] arguments) { + final int argumentsLength = arguments.length; + final int VISIBLE_INDEX = 0; + final int INVISIBLE_INDEX = 1; + int invisibleParametersAnnotationsCounter = 0; + int visibleParametersAnnotationsCounter = 0; + int[][] annotationsCounters = new int[argumentsLength][2]; + for (int i = 0; i < argumentsLength; i++) { + Argument argument = arguments[i]; + Annotation[] annotations = argument.annotations; + if (annotations != null) { + for (int j = 0, max2 = annotations.length; j < max2; j++) { + Annotation annotation; + if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container. + long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0; + if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue; + if (annotation.isRuntimeInvisible()) { + annotationsCounters[i][INVISIBLE_INDEX]++; + invisibleParametersAnnotationsCounter++; + } else if (annotation.isRuntimeVisible()) { + annotationsCounters[i][VISIBLE_INDEX]++; + visibleParametersAnnotationsCounter++; + } + } + } + } + int attributesNumber = 0; + int annotationAttributeOffset = this.contentsOffset; + if (invisibleParametersAnnotationsCounter != 0) { + int globalCounter = 0; + if (this.contentsOffset + 7 >= this.contents.length) { + resizeContents(7); + } + int attributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleParameterAnnotationsName); + this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) attributeNameIndex; + int attributeLengthOffset = this.contentsOffset; + this.contentsOffset += 4; // leave space for the attribute length + + this.contents[this.contentsOffset++] = (byte) argumentsLength; + for (int i = 0; i < argumentsLength; i++) { + if (this.contentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + if (invisibleParametersAnnotationsCounter == 0) { + this.contents[this.contentsOffset++] = (byte) 0; + this.contents[this.contentsOffset++] = (byte) 0; + } else { + final int numberOfInvisibleAnnotations = annotationsCounters[i][INVISIBLE_INDEX]; + int invisibleAnnotationsOffset = this.contentsOffset; + // leave space for number of annotations + this.contentsOffset += 2; + int counter = 0; + if (numberOfInvisibleAnnotations != 0) { + Argument argument = arguments[i]; + Annotation[] annotations = argument.annotations; + for (int j = 0, max = annotations.length; j < max; j++) { + Annotation annotation; + if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container. + long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0; + if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue; + if (annotation.isRuntimeInvisible()) { + int currentAnnotationOffset = this.contentsOffset; + generateAnnotation(annotation, currentAnnotationOffset); + if (this.contentsOffset != currentAnnotationOffset) { + counter++; + globalCounter++; + } + invisibleParametersAnnotationsCounter--; + } + } + } + this.contents[invisibleAnnotationsOffset++] = (byte) (counter >> 8); + this.contents[invisibleAnnotationsOffset] = (byte) counter; + } + } + if (globalCounter != 0) { + int attributeLength = this.contentsOffset - attributeLengthOffset - 4; + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8); + this.contents[attributeLengthOffset++] = (byte) attributeLength; + attributesNumber++; + } else { + // if globalCounter is 0, this means that the code generation for all visible annotations failed + this.contentsOffset = annotationAttributeOffset; + } + } + if (visibleParametersAnnotationsCounter != 0) { + int globalCounter = 0; + if (this.contentsOffset + 7 >= this.contents.length) { + resizeContents(7); + } + int attributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleParameterAnnotationsName); + this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) attributeNameIndex; + int attributeLengthOffset = this.contentsOffset; + this.contentsOffset += 4; // leave space for the attribute length + + this.contents[this.contentsOffset++] = (byte) argumentsLength; + for (int i = 0; i < argumentsLength; i++) { + if (this.contentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + if (visibleParametersAnnotationsCounter == 0) { + this.contents[this.contentsOffset++] = (byte) 0; + this.contents[this.contentsOffset++] = (byte) 0; + } else { + final int numberOfVisibleAnnotations = annotationsCounters[i][VISIBLE_INDEX]; + int visibleAnnotationsOffset = this.contentsOffset; + // leave space for number of annotations + this.contentsOffset += 2; + int counter = 0; + if (numberOfVisibleAnnotations != 0) { + Argument argument = arguments[i]; + Annotation[] annotations = argument.annotations; + for (int j = 0, max = annotations.length; j < max; j++) { + Annotation annotation; + if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container. + long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0; + if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue; + if (annotation.isRuntimeVisible()) { + int currentAnnotationOffset = this.contentsOffset; + generateAnnotation(annotation, currentAnnotationOffset); + if (this.contentsOffset != currentAnnotationOffset) { + counter++; + globalCounter++; + } + visibleParametersAnnotationsCounter--; + } + } + } + this.contents[visibleAnnotationsOffset++] = (byte) (counter >> 8); + this.contents[visibleAnnotationsOffset] = (byte) counter; + } + } + if (globalCounter != 0) { + int attributeLength = this.contentsOffset - attributeLengthOffset - 4; + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8); + this.contents[attributeLengthOffset++] = (byte) attributeLength; + attributesNumber++; + } else { + // if globalCounter is 0, this means that the code generation for all visible annotations failed + this.contentsOffset = annotationAttributeOffset; + } + } + return attributesNumber; + } + + /** + * @param annotationContexts the given annotation contexts + * @param visibleTypeAnnotationsNumber the given number of visible type annotations + * @param invisibleTypeAnnotationsNumber the given number of invisible type annotations + * @return the number of attributes created while dumping the annotations in the .class file + */ + private int generateRuntimeTypeAnnotations( + final AnnotationContext[] annotationContexts, + int visibleTypeAnnotationsNumber, + int invisibleTypeAnnotationsNumber) { + int attributesNumber = 0; + final int length = annotationContexts.length; + + int visibleTypeAnnotationsCounter = visibleTypeAnnotationsNumber; + int invisibleTypeAnnotationsCounter = invisibleTypeAnnotationsNumber; + int annotationAttributeOffset = this.contentsOffset; + int constantPOffset = this.constantPool.currentOffset; + int constantPoolIndex = this.constantPool.currentIndex; + if (invisibleTypeAnnotationsCounter != 0) { + if (this.contentsOffset + 10 >= this.contents.length) { + resizeContents(10); + } + int runtimeInvisibleAnnotationsAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleTypeAnnotationsName); + this.contents[this.contentsOffset++] = (byte) (runtimeInvisibleAnnotationsAttributeNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) runtimeInvisibleAnnotationsAttributeNameIndex; + int attributeLengthOffset = this.contentsOffset; + this.contentsOffset += 4; // leave space for the attribute length + + int annotationsLengthOffset = this.contentsOffset; + this.contentsOffset += 2; // leave space for the annotations length + + int counter = 0; + loop: for (int i = 0; i < length; i++) { + if (invisibleTypeAnnotationsCounter == 0) break loop; + AnnotationContext annotationContext = annotationContexts[i]; + if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) { + int currentAnnotationOffset = this.contentsOffset; + generateTypeAnnotation(annotationContext, currentAnnotationOffset); + invisibleTypeAnnotationsCounter--; + if (this.contentsOffset != currentAnnotationOffset) { + counter++; + } + } + } + if (counter != 0) { + this.contents[annotationsLengthOffset++] = (byte) (counter >> 8); + this.contents[annotationsLengthOffset++] = (byte) counter; + + int attributeLength = this.contentsOffset - attributeLengthOffset - 4; + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8); + this.contents[attributeLengthOffset++] = (byte) attributeLength; + attributesNumber++; + } else { + this.contentsOffset = annotationAttributeOffset; + // reset the constant pool to its state before the clinit + this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeInvisibleTypeAnnotationsName, constantPoolIndex, constantPOffset); + } + } + + annotationAttributeOffset = this.contentsOffset; + constantPOffset = this.constantPool.currentOffset; + constantPoolIndex = this.constantPool.currentIndex; + if (visibleTypeAnnotationsCounter != 0) { + if (this.contentsOffset + 10 >= this.contents.length) { + resizeContents(10); + } + int runtimeVisibleAnnotationsAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleTypeAnnotationsName); + this.contents[this.contentsOffset++] = (byte) (runtimeVisibleAnnotationsAttributeNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) runtimeVisibleAnnotationsAttributeNameIndex; + int attributeLengthOffset = this.contentsOffset; + this.contentsOffset += 4; // leave space for the attribute length + + int annotationsLengthOffset = this.contentsOffset; + this.contentsOffset += 2; // leave space for the annotations length + + int counter = 0; + loop: for (int i = 0; i < length; i++) { + if (visibleTypeAnnotationsCounter == 0) break loop; + AnnotationContext annotationContext = annotationContexts[i]; + if ((annotationContext.visibility & AnnotationContext.VISIBLE) != 0) { + visibleTypeAnnotationsCounter--; + int currentAnnotationOffset = this.contentsOffset; + generateTypeAnnotation(annotationContext, currentAnnotationOffset); + if (this.contentsOffset != currentAnnotationOffset) { + counter++; + } + } + } + if (counter != 0) { + this.contents[annotationsLengthOffset++] = (byte) (counter >> 8); + this.contents[annotationsLengthOffset++] = (byte) counter; + + int attributeLength = this.contentsOffset - attributeLengthOffset - 4; + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16); + this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8); + this.contents[attributeLengthOffset++] = (byte) attributeLength; + attributesNumber++; + } else { + this.contentsOffset = annotationAttributeOffset; + this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeVisibleTypeAnnotationsName, constantPoolIndex, constantPOffset); + } + } + return attributesNumber; + } + + /** + * @param binding the given method binding + * @return the number of attributes created while dumping he method's parameters in the .class file (0 or 1) + */ + private int generateMethodParameters(final MethodBinding binding) { + + int initialContentsOffset = this.contentsOffset; + int length = 0; // count of actual parameters + + AbstractMethodDeclaration methodDeclaration = binding.sourceMethod(); + + boolean isConstructor = binding.isConstructor(); + TypeBinding[] targetParameters = binding.parameters; + ReferenceBinding declaringClass = binding.declaringClass; + + if (declaringClass.isEnum()) { + if (isConstructor) { // insert String name,int ordinal + length = writeArgumentName(ConstantPool.EnumName, ClassFileConstants.AccSynthetic, length); + length = writeArgumentName(ConstantPool.EnumOrdinal, ClassFileConstants.AccSynthetic, length); + } else if (CharOperation.equals(ConstantPool.ValueOf, binding.selector)) { // insert String name + length = writeArgumentName(ConstantPool.Name, ClassFileConstants.AccMandated, length); + targetParameters = Binding.NO_PARAMETERS; // Override "unknown" synthetics below + } + } + + boolean needSynthetics = isConstructor && declaringClass.isNestedType(); + if (needSynthetics) { + // Take into account the synthetic argument names + // This tracks JLS8, paragraph 8.8.9 + boolean anonymousWithLocalSuper = declaringClass.isAnonymousType() && declaringClass.superclass().isLocalType(); + boolean anonymousWithNestedSuper = declaringClass.isAnonymousType() && declaringClass.superclass().isNestedType(); + boolean isImplicitlyDeclared = ((! declaringClass.isPrivate()) || declaringClass.isAnonymousType()) && !anonymousWithLocalSuper; + ReferenceBinding[] syntheticArgumentTypes = declaringClass.syntheticEnclosingInstanceTypes(); + if (syntheticArgumentTypes != null) { + for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) { + // This behaviour tracks JLS 15.9.5.1 + // This covers that the parameter ending up in a nested class must be mandated "on the way in", even if it + // isn't the first. The practical relevance of this is questionable, since the constructor call will be + // generated by the same constructor. + boolean couldForwardToMandated = anonymousWithNestedSuper ? declaringClass.superclass().enclosingType().equals(syntheticArgumentTypes[i]) : true; + int modifier = couldForwardToMandated && isImplicitlyDeclared ? ClassFileConstants.AccMandated : ClassFileConstants.AccSynthetic; + char[] name = CharOperation.concat( + TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX, + String.valueOf(i).toCharArray()); // cannot use depth, can be identical + length = writeArgumentName(name, modifier | ClassFileConstants.AccFinal, length); + } + } + if (binding instanceof SyntheticMethodBinding) { + targetParameters = ((SyntheticMethodBinding)binding).targetMethod.parameters; + methodDeclaration = ((SyntheticMethodBinding)binding).targetMethod.sourceMethod(); + } + } + if (targetParameters != Binding.NO_PARAMETERS) { + Argument[] arguments = null; + if (methodDeclaration != null && methodDeclaration.arguments != null) { + arguments = methodDeclaration.arguments; + } else if (binding.sourceLambda() != null) { // SyntheticMethodBinding, purpose : LambdaMethod. + arguments = binding.sourceLambda().arguments; + } + for (int i = 0, max = targetParameters.length, argumentsLength = arguments != null ? arguments.length : 0; i < max; i++) { + if (argumentsLength > i && arguments[i] != null) { + Argument argument = arguments[i]; + length = writeArgumentName(argument.name, argument.binding.modifiers, length); + } else { + length = writeArgumentName(null, ClassFileConstants.AccSynthetic, length); + } + } + } + if (needSynthetics) { + SyntheticArgumentBinding[] syntheticOuterArguments = declaringClass.syntheticOuterLocalVariables(); + int count = syntheticOuterArguments == null ? 0 : syntheticOuterArguments.length; + for (int i = 0; i < count; i++) { + length = writeArgumentName(syntheticOuterArguments[i].name, syntheticOuterArguments[i].modifiers | ClassFileConstants.AccSynthetic, length); + } + // move the extra padding arguments of the synthetic constructor invocation to the end + for (int i = targetParameters.length, extraLength = binding.parameters.length; i < extraLength; i++) { + TypeBinding parameter = binding.parameters[i]; + length = writeArgumentName(parameter.constantPoolName(), ClassFileConstants.AccSynthetic, length); + } + } + + if (length > 0) { + // so we actually output the parameter + int attributeLength = 1 + 4 * length; // u1 for count, u2+u2 per parameter + if (this.contentsOffset + 6 + attributeLength >= this.contents.length) { + resizeContents(6 + attributeLength); + } + int methodParametersNameIndex = this.constantPool.literalIndex(AttributeNamesConstants.MethodParametersName); + this.contents[initialContentsOffset++] = (byte) (methodParametersNameIndex >> 8); + this.contents[initialContentsOffset++] = (byte) methodParametersNameIndex; + this.contents[initialContentsOffset++] = (byte) (attributeLength >> 24); + this.contents[initialContentsOffset++] = (byte) (attributeLength >> 16); + this.contents[initialContentsOffset++] = (byte) (attributeLength >> 8); + this.contents[initialContentsOffset++] = (byte) attributeLength; + this.contents[initialContentsOffset++] = (byte) length; + return 1; + } + else { + return 0; + } + } + private int writeArgumentName(char[] name, int modifiers, int oldLength) { + int ensureRoomForBytes = 4; + if (oldLength == 0) { + // Make room for + ensureRoomForBytes += 7; + this.contentsOffset += 7; // Make room for attribute header + count byte + } + if (this.contentsOffset + ensureRoomForBytes > this.contents.length) { + resizeContents(ensureRoomForBytes); + } + int parameterNameIndex = name == null ? 0 : this.constantPool.literalIndex(name); + this.contents[this.contentsOffset++] = (byte) (parameterNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) parameterNameIndex; + int flags = modifiers & (ClassFileConstants.AccFinal | ClassFileConstants.AccSynthetic | ClassFileConstants.AccMandated); + this.contents[this.contentsOffset++] = (byte) (flags >> 8); + this.contents[this.contentsOffset++] = (byte) flags; + return oldLength + 1; + } + + private int generateSignatureAttribute(char[] genericSignature) { + int localContentsOffset = this.contentsOffset; + if (localContentsOffset + 8 >= this.contents.length) { + resizeContents(8); + } + int signatureAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.SignatureName); + this.contents[localContentsOffset++] = (byte) (signatureAttributeNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) signatureAttributeNameIndex; + // the length of a signature attribute is equals to 2 + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 2; + int signatureIndex = + this.constantPool.literalIndex(genericSignature); + this.contents[localContentsOffset++] = (byte) (signatureIndex >> 8); + this.contents[localContentsOffset++] = (byte) signatureIndex; + this.contentsOffset = localContentsOffset; + return 1; + } + + private int generateSourceAttribute(String fullFileName) { + int localContentsOffset = this.contentsOffset; + // check that there is enough space to write all the bytes for the field info corresponding + // to the @fieldBinding + if (localContentsOffset + 8 >= this.contents.length) { + resizeContents(8); + } + int sourceAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.SourceName); + this.contents[localContentsOffset++] = (byte) (sourceAttributeNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) sourceAttributeNameIndex; + // The length of a source file attribute is 2. This is a fixed-length + // attribute + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 2; + // write the source file name + int fileNameIndex = this.constantPool.literalIndex(fullFileName.toCharArray()); + this.contents[localContentsOffset++] = (byte) (fileNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) fileNameIndex; + this.contentsOffset = localContentsOffset; + return 1; + } + private int generateStackMapAttribute( + MethodBinding methodBinding, + int code_length, + int codeAttributeOffset, + int max_locals, + boolean isClinit) { + int attributesNumber = 0; + int localContentsOffset = this.contentsOffset; + StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream; + stackMapFrameCodeStream.removeFramePosition(code_length); + if (stackMapFrameCodeStream.hasFramePositions()) { + Map frames = new HashMap(); + List realFrames = traverse(isClinit ? null : methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit); + int numberOfFrames = realFrames.size(); + if (numberOfFrames > 1) { + int stackMapTableAttributeOffset = localContentsOffset; + // add the stack map table attribute + if (localContentsOffset + 8 >= this.contents.length) { + resizeContents(8); + } + int stackMapAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.StackMapName); + this.contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex; + + int stackMapAttributeLengthOffset = localContentsOffset; + // generate the attribute + localContentsOffset += 4; + if (localContentsOffset + 4 >= this.contents.length) { + resizeContents(4); + } + int numberOfFramesOffset = localContentsOffset; + localContentsOffset += 2; + if (localContentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + StackMapFrame currentFrame = (StackMapFrame) realFrames.get(0); + for (int j = 1; j < numberOfFrames; j++) { + // select next frame + currentFrame = (StackMapFrame) realFrames.get(j); + // generate current frame + // need to find differences between the current frame and the previous frame + int frameOffset = currentFrame.pc; + // FULL_FRAME + if (localContentsOffset + 5 >= this.contents.length) { + resizeContents(5); + } + this.contents[localContentsOffset++] = (byte) (frameOffset >> 8); + this.contents[localContentsOffset++] = (byte) frameOffset; + int numberOfLocalOffset = localContentsOffset; + localContentsOffset += 2; // leave two spots for number of locals + int numberOfLocalEntries = 0; + int numberOfLocals = currentFrame.getNumberOfLocals(); + int numberOfEntries = 0; + int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length; + for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { + if (localContentsOffset + 3 >= this.contents.length) { + resizeContents(3); + } + VerificationTypeInfo info = currentFrame.locals[i]; + if (info == null) { + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; + } else { + switch(info.id()) { + case T_boolean : + case T_byte : + case T_char : + case T_int : + case T_short : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; + break; + case T_float : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; + break; + case T_long : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; + i++; + break; + case T_double : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; + i++; + break; + case T_null : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; + break; + default: + this.contents[localContentsOffset++] = (byte) info.tag; + switch (info.tag) { + case VerificationTypeInfo.ITEM_UNINITIALIZED : + int offset = info.offset; + this.contents[localContentsOffset++] = (byte) (offset >> 8); + this.contents[localContentsOffset++] = (byte) offset; + break; + case VerificationTypeInfo.ITEM_OBJECT : + int indexForType = this.constantPool.literalIndexForType(info.constantPoolName()); + this.contents[localContentsOffset++] = (byte) (indexForType >> 8); + this.contents[localContentsOffset++] = (byte) indexForType; + } + } + numberOfLocalEntries++; + } + numberOfEntries++; + } + if (localContentsOffset + 4 >= this.contents.length) { + resizeContents(4); + } + this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8); + this.contents[numberOfLocalOffset] = (byte) numberOfEntries; + int numberOfStackItems = currentFrame.numberOfStackItems; + this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8); + this.contents[localContentsOffset++] = (byte) numberOfStackItems; + for (int i = 0; i < numberOfStackItems; i++) { + if (localContentsOffset + 3 >= this.contents.length) { + resizeContents(3); + } + VerificationTypeInfo info = currentFrame.stackItems[i]; + if (info == null) { + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; + } else { + switch(info.id()) { + case T_boolean : + case T_byte : + case T_char : + case T_int : + case T_short : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; + break; + case T_float : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; + break; + case T_long : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; + break; + case T_double : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; + break; + case T_null : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; + break; + default: + this.contents[localContentsOffset++] = (byte) info.tag; + switch (info.tag) { + case VerificationTypeInfo.ITEM_UNINITIALIZED : + int offset = info.offset; + this.contents[localContentsOffset++] = (byte) (offset >> 8); + this.contents[localContentsOffset++] = (byte) offset; + break; + case VerificationTypeInfo.ITEM_OBJECT : + int indexForType = this.constantPool.literalIndexForType(info.constantPoolName()); + this.contents[localContentsOffset++] = (byte) (indexForType >> 8); + this.contents[localContentsOffset++] = (byte) indexForType; + } + } + } + } + } + + numberOfFrames--; + if (numberOfFrames != 0) { + this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8); + this.contents[numberOfFramesOffset] = (byte) numberOfFrames; + + int attributeLength = localContentsOffset - stackMapAttributeLengthOffset - 4; + this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24); + this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16); + this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8); + this.contents[stackMapAttributeLengthOffset] = (byte) attributeLength; + attributesNumber++; + } else { + localContentsOffset = stackMapTableAttributeOffset; + } + } + } + this.contentsOffset = localContentsOffset; + return attributesNumber; + } + + private int generateStackMapTableAttribute( + MethodBinding methodBinding, + int code_length, + int codeAttributeOffset, + int max_locals, + boolean isClinit) { + int attributesNumber = 0; + int localContentsOffset = this.contentsOffset; + StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream; + stackMapFrameCodeStream.removeFramePosition(code_length); + if (stackMapFrameCodeStream.hasFramePositions()) { + Map frames = new HashMap(); + List realFrames = traverse(isClinit ? null: methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit); + int numberOfFrames = realFrames.size(); + if (numberOfFrames > 1) { + int stackMapTableAttributeOffset = localContentsOffset; + // add the stack map table attribute + if (localContentsOffset + 8 >= this.contents.length) { + resizeContents(8); + } + int stackMapTableAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); + this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex; + + int stackMapTableAttributeLengthOffset = localContentsOffset; + // generate the attribute + localContentsOffset += 4; + if (localContentsOffset + 4 >= this.contents.length) { + resizeContents(4); + } + int numberOfFramesOffset = localContentsOffset; + localContentsOffset += 2; + if (localContentsOffset + 2 >= this.contents.length) { + resizeContents(2); + } + StackMapFrame currentFrame = (StackMapFrame) realFrames.get(0); + StackMapFrame prevFrame = null; + for (int j = 1; j < numberOfFrames; j++) { + // select next frame + prevFrame = currentFrame; + currentFrame = (StackMapFrame) realFrames.get(j); + // generate current frame + // need to find differences between the current frame and the previous frame + int offsetDelta = currentFrame.getOffsetDelta(prevFrame); + switch (currentFrame.getFrameType(prevFrame)) { + case StackMapFrame.APPEND_FRAME : + if (localContentsOffset + 3 >= this.contents.length) { + resizeContents(3); + } + int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); + this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); + this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); + this.contents[localContentsOffset++] = (byte) offsetDelta; + int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); + int numberOfLocals = currentFrame.getNumberOfLocals(); + for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { + if (localContentsOffset + 6 >= this.contents.length) { + resizeContents(6); + } + VerificationTypeInfo info = currentFrame.locals[i]; + if (info == null) { + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; + } else { + switch(info.id()) { + case T_boolean : + case T_byte : + case T_char : + case T_int : + case T_short : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; + break; + case T_float : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; + break; + case T_long : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; + i++; + break; + case T_double : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; + i++; + break; + case T_null : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; + break; + default: + this.contents[localContentsOffset++] = (byte) info.tag; + switch (info.tag) { + case VerificationTypeInfo.ITEM_UNINITIALIZED : + int offset = info.offset; + this.contents[localContentsOffset++] = (byte) (offset >> 8); + this.contents[localContentsOffset++] = (byte) offset; + break; + case VerificationTypeInfo.ITEM_OBJECT : + int indexForType = this.constantPool.literalIndexForType(info.constantPoolName()); + this.contents[localContentsOffset++] = (byte) (indexForType >> 8); + this.contents[localContentsOffset++] = (byte) indexForType; + } + } + numberOfDifferentLocals--; + } + } + break; + case StackMapFrame.SAME_FRAME : + if (localContentsOffset + 1 >= this.contents.length) { + resizeContents(1); + } + this.contents[localContentsOffset++] = (byte) offsetDelta; + break; + case StackMapFrame.SAME_FRAME_EXTENDED : + if (localContentsOffset + 3 >= this.contents.length) { + resizeContents(3); + } + this.contents[localContentsOffset++] = (byte) 251; + this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); + this.contents[localContentsOffset++] = (byte) offsetDelta; + break; + case StackMapFrame.CHOP_FRAME : + if (localContentsOffset + 3 >= this.contents.length) { + resizeContents(3); + } + numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); + this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); + this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); + this.contents[localContentsOffset++] = (byte) offsetDelta; + break; + case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS : + if (localContentsOffset + 4 >= this.contents.length) { + resizeContents(4); + } + this.contents[localContentsOffset++] = (byte) (offsetDelta + 64); + if (currentFrame.stackItems[0] == null) { + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; + } else { + switch(currentFrame.stackItems[0].id()) { + case T_boolean : + case T_byte : + case T_char : + case T_int : + case T_short : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; + break; + case T_float : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; + break; + case T_long : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; + break; + case T_double : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; + break; + case T_null : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; + break; + default: + VerificationTypeInfo info = currentFrame.stackItems[0]; + byte tag = (byte) info.tag; + this.contents[localContentsOffset++] = tag; + switch (tag) { + case VerificationTypeInfo.ITEM_UNINITIALIZED : + int offset = info.offset; + this.contents[localContentsOffset++] = (byte) (offset >> 8); + this.contents[localContentsOffset++] = (byte) offset; + break; + case VerificationTypeInfo.ITEM_OBJECT : + int indexForType = this.constantPool.literalIndexForType(info.constantPoolName()); + this.contents[localContentsOffset++] = (byte) (indexForType >> 8); + this.contents[localContentsOffset++] = (byte) indexForType; + } + } + } + break; + case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED : + if (localContentsOffset + 6 >= this.contents.length) { + resizeContents(6); + } + this.contents[localContentsOffset++] = (byte) 247; + this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); + this.contents[localContentsOffset++] = (byte) offsetDelta; + if (currentFrame.stackItems[0] == null) { + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; + } else { + switch(currentFrame.stackItems[0].id()) { + case T_boolean : + case T_byte : + case T_char : + case T_int : + case T_short : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; + break; + case T_float : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; + break; + case T_long : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; + break; + case T_double : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; + break; + case T_null : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; + break; + default: + VerificationTypeInfo info = currentFrame.stackItems[0]; + byte tag = (byte) info.tag; + this.contents[localContentsOffset++] = tag; + switch (tag) { + case VerificationTypeInfo.ITEM_UNINITIALIZED : + int offset = info.offset; + this.contents[localContentsOffset++] = (byte) (offset >> 8); + this.contents[localContentsOffset++] = (byte) offset; + break; + case VerificationTypeInfo.ITEM_OBJECT : + int indexForType = this.constantPool.literalIndexForType(info.constantPoolName()); + this.contents[localContentsOffset++] = (byte) (indexForType >> 8); + this.contents[localContentsOffset++] = (byte) indexForType; + } + } + } + break; + default : + // FULL_FRAME + if (localContentsOffset + 5 >= this.contents.length) { + resizeContents(5); + } + this.contents[localContentsOffset++] = (byte) 255; + this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); + this.contents[localContentsOffset++] = (byte) offsetDelta; + int numberOfLocalOffset = localContentsOffset; + localContentsOffset += 2; // leave two spots for number of locals + int numberOfLocalEntries = 0; + numberOfLocals = currentFrame.getNumberOfLocals(); + int numberOfEntries = 0; + int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length; + for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { + if (localContentsOffset + 3 >= this.contents.length) { + resizeContents(3); + } + VerificationTypeInfo info = currentFrame.locals[i]; + if (info == null) { + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; + } else { + switch(info.id()) { + case T_boolean : + case T_byte : + case T_char : + case T_int : + case T_short : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; + break; + case T_float : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; + break; + case T_long : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; + i++; + break; + case T_double : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; + i++; + break; + case T_null : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; + break; + default: + this.contents[localContentsOffset++] = (byte) info.tag; + switch (info.tag) { + case VerificationTypeInfo.ITEM_UNINITIALIZED : + int offset = info.offset; + this.contents[localContentsOffset++] = (byte) (offset >> 8); + this.contents[localContentsOffset++] = (byte) offset; + break; + case VerificationTypeInfo.ITEM_OBJECT : + int indexForType = this.constantPool.literalIndexForType(info.constantPoolName()); + this.contents[localContentsOffset++] = (byte) (indexForType >> 8); + this.contents[localContentsOffset++] = (byte) indexForType; + } + } + numberOfLocalEntries++; + } + numberOfEntries++; + } + if (localContentsOffset + 4 >= this.contents.length) { + resizeContents(4); + } + this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8); + this.contents[numberOfLocalOffset] = (byte) numberOfEntries; + int numberOfStackItems = currentFrame.numberOfStackItems; + this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8); + this.contents[localContentsOffset++] = (byte) numberOfStackItems; + for (int i = 0; i < numberOfStackItems; i++) { + if (localContentsOffset + 3 >= this.contents.length) { + resizeContents(3); + } + VerificationTypeInfo info = currentFrame.stackItems[i]; + if (info == null) { + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP; + } else { + switch(info.id()) { + case T_boolean : + case T_byte : + case T_char : + case T_int : + case T_short : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER; + break; + case T_float : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT; + break; + case T_long : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG; + break; + case T_double : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE; + break; + case T_null : + this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL; + break; + default: + this.contents[localContentsOffset++] = (byte) info.tag; + switch (info.tag) { + case VerificationTypeInfo.ITEM_UNINITIALIZED : + int offset = info.offset; + this.contents[localContentsOffset++] = (byte) (offset >> 8); + this.contents[localContentsOffset++] = (byte) offset; + break; + case VerificationTypeInfo.ITEM_OBJECT : + int indexForType = this.constantPool.literalIndexForType(info.constantPoolName()); + this.contents[localContentsOffset++] = (byte) (indexForType >> 8); + this.contents[localContentsOffset++] = (byte) indexForType; + } + } + } + } + } + } + + numberOfFrames--; + if (numberOfFrames != 0) { + this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8); + this.contents[numberOfFramesOffset] = (byte) numberOfFrames; + + int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4; + this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24); + this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16); + this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8); + this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength; + attributesNumber++; + } else { + localContentsOffset = stackMapTableAttributeOffset; + } + } + } + this.contentsOffset = localContentsOffset; + return attributesNumber; + } + + private int generateSyntheticAttribute() { + int localContentsOffset = this.contentsOffset; + if (localContentsOffset + 6 >= this.contents.length) { + resizeContents(6); + } + int syntheticAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.SyntheticName); + this.contents[localContentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) syntheticAttributeNameIndex; + // the length of a synthetic attribute is equals to 0 + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contentsOffset = localContentsOffset; + return 1; + } + + private void generateTypeAnnotation(AnnotationContext annotationContext, int currentOffset) { + Annotation annotation = annotationContext.annotation.getPersistibleAnnotation(); + if (annotation == null || annotation.resolvedType == null) + return; + + int targetType = annotationContext.targetType; + + int[] locations = Annotation.getLocations( + annotationContext.typeReference, + annotationContext.annotation); + + if (this.contentsOffset + 5 >= this.contents.length) { + resizeContents(5); + } + this.contents[this.contentsOffset++] = (byte) targetType; + dumpTargetTypeContents(targetType, annotationContext); + dumpLocations(locations); + generateAnnotation(annotation, currentOffset); + } + + private int generateTypeAnnotationAttributeForTypeDeclaration() { + TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext; + if ((typeDeclaration.bits & ASTNode.HasTypeAnnotations) == 0) { + return 0; + } + int attributesNumber = 0; + int visibleTypeAnnotationsCounter = 0; + int invisibleTypeAnnotationsCounter = 0; + TypeReference superclass = typeDeclaration.superclass; + List allTypeAnnotationContexts = new ArrayList(); + if (superclass != null && (superclass.bits & ASTNode.HasTypeAnnotations) != 0) { + superclass.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, -1, allTypeAnnotationContexts); + } + TypeReference[] superInterfaces = typeDeclaration.superInterfaces; + if (superInterfaces != null) { + for (int i = 0; i < superInterfaces.length; i++) { + TypeReference superInterface = superInterfaces[i]; + if ((superInterface.bits & ASTNode.HasTypeAnnotations) == 0) { + continue; + } + superInterface.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, i, allTypeAnnotationContexts); + } + } + TypeParameter[] typeParameters = typeDeclaration.typeParameters; + if (typeParameters != null) { + for (int i = 0, max = typeParameters.length; i < max; i++) { + TypeParameter typeParameter = typeParameters[i]; + if ((typeParameter.bits & ASTNode.HasTypeAnnotations) != 0) { + typeParameter.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER, i, allTypeAnnotationContexts); + } + } + } + int size = allTypeAnnotationContexts.size(); + if (size != 0) { + AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size]; + allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray); + for (int j = 0, max = allTypeAnnotationContextsArray.length; j < max; j++) { + AnnotationContext annotationContext = allTypeAnnotationContextsArray[j]; + if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) { + invisibleTypeAnnotationsCounter++; + allTypeAnnotationContexts.add(annotationContext); + } else { + visibleTypeAnnotationsCounter++; + allTypeAnnotationContexts.add(annotationContext); + } + } + attributesNumber += generateRuntimeTypeAnnotations( + allTypeAnnotationContextsArray, + visibleTypeAnnotationsCounter, + invisibleTypeAnnotationsCounter); + } + return attributesNumber; + } + + + + + private int generateVarargsAttribute() { + int localContentsOffset = this.contentsOffset; + /* + * handle of the target jsr14 for varargs in the source + * Varargs attribute + * Check that there is enough space to write the attribute + */ + if (localContentsOffset + 6 >= this.contents.length) { + resizeContents(6); + } + int varargsAttributeNameIndex = + this.constantPool.literalIndex(AttributeNamesConstants.VarargsName); + this.contents[localContentsOffset++] = (byte) (varargsAttributeNameIndex >> 8); + this.contents[localContentsOffset++] = (byte) varargsAttributeNameIndex; + // the length of a varargs attribute is equals to 0 + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + this.contents[localContentsOffset++] = 0; + + this.contentsOffset = localContentsOffset; + return 1; + } + + /** + * EXTERNAL API + * Answer the actual bytes of the class file + * + * This method encodes the receiver structure into a byte array which is the content of the classfile. + * Returns the byte array that represents the encoded structure of the receiver. + * + * @return byte[] + */ + public byte[] getBytes() { + if (this.bytes == null) { + this.bytes = new byte[this.headerOffset + this.contentsOffset]; + System.arraycopy(this.header, 0, this.bytes, 0, this.headerOffset); + System.arraycopy(this.contents, 0, this.bytes, this.headerOffset, this.contentsOffset); + } + return this.bytes; + } + /** + * EXTERNAL API + * Answer the compound name of the class file. + * @return char[][] + * e.g. {{java}, {util}, {Hashtable}}. + */ + public char[][] getCompoundName() { + return CharOperation.splitOn('/', fileName()); + } + + private int getParametersCount(char[] methodSignature) { + int i = CharOperation.indexOf('(', methodSignature); + i++; + char currentCharacter = methodSignature[i]; + if (currentCharacter == ')') { + return 0; + } + int result = 0; + while (true) { + currentCharacter = methodSignature[i]; + if (currentCharacter == ')') { + return result; + } + switch (currentCharacter) { + case '[': + // array type + int scanType = scanType(methodSignature, i + 1); + result++; + i = scanType + 1; + break; + case 'L': + scanType = CharOperation.indexOf(';', methodSignature, + i + 1); + result++; + i = scanType + 1; + break; + case 'Z': + case 'B': + case 'C': + case 'D': + case 'F': + case 'I': + case 'J': + case 'S': + result++; + i++; + break; + default: + throw new IllegalArgumentException("Invalid starting type character : " + currentCharacter); //$NON-NLS-1$ + } + } + } + + private char[] getReturnType(char[] methodSignature) { + // skip type parameters + int paren = CharOperation.lastIndexOf(')', methodSignature); + // there could be thrown exceptions behind, thus scan one type exactly + return CharOperation.subarray(methodSignature, paren + 1, + methodSignature.length); + } + + private final int i4At(byte[] reference, int relativeOffset, + int structOffset) { + int position = relativeOffset + structOffset; + return ((reference[position++] & 0xFF) << 24) + + ((reference[position++] & 0xFF) << 16) + + ((reference[position++] & 0xFF) << 8) + + (reference[position] & 0xFF); + } + + protected void initByteArrays() { + int members = this.referenceBinding.methods().length + this.referenceBinding.fields().length; + this.header = new byte[INITIAL_HEADER_SIZE]; + this.contents = new byte[members < 15 ? INITIAL_CONTENTS_SIZE : INITIAL_HEADER_SIZE]; + } + + public void initialize(SourceTypeBinding aType, ClassFile parentClassFile, boolean createProblemType) { + // generate the magic numbers inside the header + this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 24); + this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 16); + this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 8); + this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 0); + + long targetVersion = this.targetJDK; + this.header[this.headerOffset++] = (byte) (targetVersion >> 8); // minor high + this.header[this.headerOffset++] = (byte) (targetVersion>> 0); // minor low + this.header[this.headerOffset++] = (byte) (targetVersion >> 24); // major high + this.header[this.headerOffset++] = (byte) (targetVersion >> 16); // major low + + this.constantPoolOffset = this.headerOffset; + this.headerOffset += 2; + this.constantPool.initialize(this); + + // Modifier manipulations for classfile + int accessFlags = aType.getAccessFlags(); + if (aType.isPrivate()) { // rewrite private to non-public + accessFlags &= ~ClassFileConstants.AccPublic; + } + if (aType.isProtected()) { // rewrite protected into public + accessFlags |= ClassFileConstants.AccPublic; + } + // clear all bits that are illegal for a class or an interface + accessFlags + &= ~( + ClassFileConstants.AccStrictfp + | ClassFileConstants.AccProtected + | ClassFileConstants.AccPrivate + | ClassFileConstants.AccStatic + | ClassFileConstants.AccSynchronized + | ClassFileConstants.AccNative); + + // set the AccSuper flag (has to be done after clearing AccSynchronized - since same value) + if (!aType.isInterface()) { // class or enum + accessFlags |= ClassFileConstants.AccSuper; + } + if (aType.isAnonymousType()) { + accessFlags &= ~ClassFileConstants.AccFinal; + } + int finalAbstract = ClassFileConstants.AccFinal | ClassFileConstants.AccAbstract; + if ((accessFlags & finalAbstract) == finalAbstract) { + accessFlags &= ~finalAbstract; + } + this.enclosingClassFile = parentClassFile; + // innerclasses get their names computed at code gen time + + // now we continue to generate the bytes inside the contents array + this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8); + this.contents[this.contentsOffset++] = (byte) accessFlags; + int classNameIndex = this.constantPool.literalIndexForType(aType); + this.contents[this.contentsOffset++] = (byte) (classNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) classNameIndex; + // AspectJ Extension - don't include result of decp weaving in the class created by compilation + /*old{ + int superclassNameIndex; + if (aType.isInterface()) { + superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName); + } else { + if (aType.superclass != null) { + if ((aType.superclass.tagBits & TagBits.HasMissingType) != 0) { + superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName); + } else { + superclassNameIndex = this.constantPool.literalIndexForType(aType.superclass); + } + } else { + superclassNameIndex = 0; + } + } + }new:*/ + ReferenceBinding superclass = aType.superclass; + int superclassNameIndex; + if (aType.originalSuperclass!=null) { + superclass = aType.originalSuperclass; + } + if (aType.isInterface()) { + superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName); + } else { + if (superclass != null) { + if ((superclass.tagBits & TagBits.HasMissingType) != 0) { + superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName); + } else { + superclassNameIndex = this.constantPool.literalIndexForType(superclass); + } + } else { + superclassNameIndex = 0; + } + } + // AspectJ Extension end + this.contents[this.contentsOffset++] = (byte) (superclassNameIndex >> 8); + this.contents[this.contentsOffset++] = (byte) superclassNameIndex; + ReferenceBinding[] superInterfacesBinding = aType.superInterfaces(); + // AspectJ Extension - don't include result of decp weaving in the class created by compilaton + if (aType.originalSuperInterfaces!=null) { + superInterfacesBinding = aType.originalSuperInterfaces; + } + // AspectJ Extension end + int interfacesCount = superInterfacesBinding.length; + int interfacesCountPosition = this.contentsOffset; + this.contentsOffset += 2; + int interfaceCounter = 0; + for (int i = 0; i < interfacesCount; i++) { + ReferenceBinding binding = superInterfacesBinding[i]; + if ((binding.tagBits & TagBits.HasMissingType) != 0) { + continue; + } + interfaceCounter++; + int interfaceIndex = this.constantPool.literalIndexForType(binding); + this.contents[this.contentsOffset++] = (byte) (interfaceIndex >> 8); + this.contents[this.contentsOffset++] = (byte) interfaceIndex; + } + this.contents[interfacesCountPosition++] = (byte) (interfaceCounter >> 8); + this.contents[interfacesCountPosition] = (byte) interfaceCounter; + this.creatingProblemType = createProblemType; + + // retrieve the enclosing one guaranteed to be the one matching the propagated flow info + // 1FF9ZBU: LFCOM:ALL - Local variable attributes busted (Sanity check) + this.codeStream.maxFieldCount = aType.scope.outerMostClassScope().referenceType().maxFieldCount; + } + + private void initializeDefaultLocals(StackMapFrame frame, + MethodBinding methodBinding, + int maxLocals, + int codeLength) { + if (maxLocals != 0) { + int resolvedPosition = 0; + // take into account enum constructor synthetic name+ordinal + final boolean isConstructor = methodBinding.isConstructor(); + if (isConstructor || !methodBinding.isStatic()) { + LocalVariableBinding localVariableBinding = new LocalVariableBinding(ConstantPool.This, methodBinding.declaringClass, 0, false); + localVariableBinding.resolvedPosition = 0; + this.codeStream.record(localVariableBinding); + localVariableBinding.recordInitializationStartPC(0); + localVariableBinding.recordInitializationEndPC(codeLength); + frame.putLocal(resolvedPosition, new VerificationTypeInfo( + isConstructor ? VerificationTypeInfo.ITEM_UNINITIALIZED_THIS : VerificationTypeInfo.ITEM_OBJECT, + methodBinding.declaringClass)); + resolvedPosition++; + } + + if (isConstructor) { + if (methodBinding.declaringClass.isEnum()) { + LocalVariableBinding localVariableBinding = new LocalVariableBinding(" name".toCharArray(), this.referenceBinding.scope.getJavaLangString(), 0, false); //$NON-NLS-1$ + localVariableBinding.resolvedPosition = resolvedPosition; + this.codeStream.record(localVariableBinding); + localVariableBinding.recordInitializationStartPC(0); + localVariableBinding.recordInitializationEndPC(codeLength); + + frame.putLocal(resolvedPosition, new VerificationTypeInfo( + TypeIds.T_JavaLangString, + ConstantPool.JavaLangStringConstantPoolName)); + resolvedPosition++; + + localVariableBinding = new LocalVariableBinding(" ordinal".toCharArray(), TypeBinding.INT, 0, false); //$NON-NLS-1$ + localVariableBinding.resolvedPosition = resolvedPosition; + this.codeStream.record(localVariableBinding); + localVariableBinding.recordInitializationStartPC(0); + localVariableBinding.recordInitializationEndPC(codeLength); + frame.putLocal(resolvedPosition, new VerificationTypeInfo( + TypeBinding.INT)); + resolvedPosition++; + } + + // take into account the synthetic parameters + if (methodBinding.declaringClass.isNestedType()) { + ReferenceBinding enclosingInstanceTypes[]; + if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) { + for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) { + // an enclosingInstanceType can only be a reference + // binding. It cannot be + // LongBinding or DoubleBinding + LocalVariableBinding localVariableBinding = new LocalVariableBinding((" enclosingType" + i).toCharArray(), enclosingInstanceTypes[i], 0, false); //$NON-NLS-1$ + localVariableBinding.resolvedPosition = resolvedPosition; + this.codeStream.record(localVariableBinding); + localVariableBinding.recordInitializationStartPC(0); + localVariableBinding.recordInitializationEndPC(codeLength); + + frame.putLocal(resolvedPosition, + new VerificationTypeInfo(enclosingInstanceTypes[i])); + resolvedPosition++; + } + } + + TypeBinding[] arguments; + if ((arguments = methodBinding.parameters) != null) { + for (int i = 0, max = arguments.length; i < max; i++) { + final TypeBinding typeBinding = arguments[i]; + frame.putLocal(resolvedPosition, + new VerificationTypeInfo(typeBinding)); + switch (typeBinding.id) { + case TypeIds.T_double: + case TypeIds.T_long: + resolvedPosition += 2; + break; + default: + resolvedPosition++; + } + } + } + + SyntheticArgumentBinding syntheticArguments[]; + if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) { + for (int i = 0, max = syntheticArguments.length; i < max; i++) { + final TypeBinding typeBinding = syntheticArguments[i].type; + LocalVariableBinding localVariableBinding = new LocalVariableBinding((" synthetic" + i).toCharArray(), typeBinding, 0, false); //$NON-NLS-1$ + localVariableBinding.resolvedPosition = resolvedPosition; + this.codeStream.record(localVariableBinding); + localVariableBinding.recordInitializationStartPC(0); + localVariableBinding.recordInitializationEndPC(codeLength); + + frame.putLocal(resolvedPosition, + new VerificationTypeInfo(typeBinding)); + switch (typeBinding.id) { + case TypeIds.T_double: + case TypeIds.T_long: + resolvedPosition += 2; + break; + default: + resolvedPosition++; + } + } + } + } else { + TypeBinding[] arguments; + if ((arguments = methodBinding.parameters) != null) { + for (int i = 0, max = arguments.length; i < max; i++) { + final TypeBinding typeBinding = arguments[i]; + frame.putLocal(resolvedPosition, + new VerificationTypeInfo(typeBinding)); + switch (typeBinding.id) { + case TypeIds.T_double: + case TypeIds.T_long: + resolvedPosition += 2; + break; + default: + resolvedPosition++; + } + } + } + } + } else { + TypeBinding[] arguments; + if ((arguments = methodBinding.parameters) != null) { + for (int i = 0, max = arguments.length; i < max; i++) { + final TypeBinding typeBinding = arguments[i]; + // For the branching complexities in the generated $deserializeLambda$ we need the local variable + LocalVariableBinding localVariableBinding = new LocalVariableBinding((" synthetic"+i).toCharArray(), typeBinding, 0, true); //$NON-NLS-1$ + localVariableBinding.resolvedPosition = i; + this.codeStream.record(localVariableBinding); + localVariableBinding.recordInitializationStartPC(0); + localVariableBinding.recordInitializationEndPC(codeLength); + frame.putLocal(resolvedPosition, + new VerificationTypeInfo(typeBinding)); + switch (typeBinding.id) { + case TypeIds.T_double: + case TypeIds.T_long: + resolvedPosition += 2; + break; + default: + resolvedPosition++; + } + } + } + } + } + } + + private void initializeLocals(boolean isStatic, int currentPC, StackMapFrame currentFrame) { + VerificationTypeInfo[] locals = currentFrame.locals; + int localsLength = locals.length; + int i = 0; + if (!isStatic) { + // we don't want to reset the first local if the method is not static + i = 1; + } + for (; i < localsLength; i++) { + locals[i] = null; + } + i = 0; + locals: for (int max = this.codeStream.allLocalsCounter; i < max; i++) { + LocalVariableBinding localVariable = this.codeStream.locals[i]; + if (localVariable == null) continue; + int resolvedPosition = localVariable.resolvedPosition; + final TypeBinding localVariableTypeBinding = localVariable.type; + inits: for (int j = 0; j < localVariable.initializationCount; j++) { + int startPC = localVariable.initializationPCs[j << 1]; + int endPC = localVariable.initializationPCs[(j << 1) + 1]; + if (currentPC < startPC) { + continue inits; + } else if (currentPC < endPC) { + // the current local is an active local + if (currentFrame.locals[resolvedPosition] == null) { + currentFrame.locals[resolvedPosition] = + new VerificationTypeInfo( + localVariableTypeBinding); + } + continue locals; + } + } + } + } + /** + * INTERNAL USE-ONLY + * Returns the most enclosing classfile of the receiver. This is used know to store the constant pool name + * for all inner types of the receiver. + * @return org.aspectj.org.eclipse.jdt.internal.compiler.codegen.ClassFile + */ + public ClassFile outerMostEnclosingClassFile() { + ClassFile current = this; + while (current.enclosingClassFile != null) + current = current.enclosingClassFile; + return current; + } + + public void recordInnerClasses(TypeBinding binding) { + if (this.innerClassesBindings == null) { + this.innerClassesBindings = new HashSet(INNER_CLASSES_SIZE); + } + ReferenceBinding innerClass = (ReferenceBinding) binding; + this.innerClassesBindings.add(innerClass.erasure().unannotated(false)); // should not emit yet another inner class for Outer.@Inner Inner. + ReferenceBinding enclosingType = innerClass.enclosingType(); + while (enclosingType != null + && enclosingType.isNestedType()) { + this.innerClassesBindings.add(enclosingType.erasure().unannotated(false)); + enclosingType = enclosingType.enclosingType(); + } + } + + public int recordBootstrapMethod(FunctionalExpression expression) { + if (this.bootstrapMethods == null) { + this.bootstrapMethods = new ArrayList(); + } + this.bootstrapMethods.add(expression); + // Record which bootstrap method was assigned to the expression + expression.bootstrapMethodNumber = this.bootstrapMethods.size() - 1; + return this.bootstrapMethods.size() - 1; + } + + public void reset(SourceTypeBinding typeBinding) { + // the code stream is reinitialized for each method + final CompilerOptions options = typeBinding.scope.compilerOptions(); + this.referenceBinding = typeBinding; + this.isNestedType = typeBinding.isNestedType(); + this.targetJDK = options.targetJDK; + this.produceAttributes = options.produceDebugAttributes; + if (this.targetJDK >= ClassFileConstants.JDK1_6) { + this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE; + if (this.targetJDK >= ClassFileConstants.JDK1_8) { + this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION; + if (options.produceMethodParameters) { + this.produceAttributes |= ClassFileConstants.ATTR_METHOD_PARAMETERS; + } + } + } else if (this.targetJDK == ClassFileConstants.CLDC_1_1) { + this.targetJDK = ClassFileConstants.JDK1_1; // put back 45.3 + this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP; + } + this.bytes = null; + this.constantPool.reset(); + this.codeStream.reset(this); + this.constantPoolOffset = 0; + this.contentsOffset = 0; + this.creatingProblemType = false; + this.enclosingClassFile = null; + this.headerOffset = 0; + this.methodCount = 0; + this.methodCountOffset = 0; + if (this.innerClassesBindings != null) { + this.innerClassesBindings.clear(); + } + if (this.bootstrapMethods != null) { + this.bootstrapMethods.clear(); + } + this.missingTypes = null; + this.visitedTypes = null; + } + + /** + * Resize the pool contents + */ + private final void resizeContents(int minimalSize) { + int length = this.contents.length; + int toAdd = length; + if (toAdd < minimalSize) + toAdd = minimalSize; + System.arraycopy(this.contents, 0, this.contents = new byte[length + toAdd], 0, length); + } + + private VerificationTypeInfo retrieveLocal(int currentPC, int resolvedPosition) { + for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) { + LocalVariableBinding localVariable = this.codeStream.locals[i]; + if (localVariable == null) continue; + if (resolvedPosition == localVariable.resolvedPosition) { + inits: for (int j = 0; j < localVariable.initializationCount; j++) { + int startPC = localVariable.initializationPCs[j << 1]; + int endPC = localVariable.initializationPCs[(j << 1) + 1]; + if (currentPC < startPC) { + continue inits; + } else if (currentPC < endPC) { + // the current local is an active local + return new VerificationTypeInfo(localVariable.type); + } + } + } + } + return null; + } + + private int scanType(char[] methodSignature, int index) { + switch (methodSignature[index]) { + case '[': + // array type + return scanType(methodSignature, index + 1); + case 'L': + return CharOperation.indexOf(';', methodSignature, index + 1); + case 'Z': + case 'B': + case 'C': + case 'D': + case 'F': + case 'I': + case 'J': + case 'S': + return index; + default: + throw new IllegalArgumentException(); + } + } + + /** + * INTERNAL USE-ONLY + * This methods leaves the space for method counts recording. + */ + public void setForMethodInfos() { + // leave some space for the methodCount + this.methodCountOffset = this.contentsOffset; + this.contentsOffset += 2; + } + + private List filterFakeFrames(Set realJumpTargets, Map frames, int codeLength) { + // no more frame to generate + // filter out "fake" frames + realJumpTargets.remove(new Integer(codeLength)); + List result = new ArrayList(); + for (Iterator iterator = realJumpTargets.iterator(); iterator.hasNext(); ) { + Integer jumpTarget = (Integer) iterator.next(); + StackMapFrame frame = (StackMapFrame) frames.get(jumpTarget); + if (frame != null) { + result.add(frame); + } + } + Collections.sort(result, new Comparator() { + public int compare(Object o1, Object o2) { + StackMapFrame frame = (StackMapFrame) o1; + StackMapFrame frame2 = (StackMapFrame) o2; + return frame.pc - frame2.pc; + } + }); + return result; + } + + public List traverse(MethodBinding methodBinding, int maxLocals, byte[] bytecodes, int codeOffset, int codeLength, Map frames, boolean isClinit) { + Set realJumpTarget = new HashSet(); + + StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream; + int[] framePositions = stackMapFrameCodeStream.getFramePositions(); + int pc = codeOffset; + int index; + int[] constantPoolOffsets = this.constantPool.offsets; + byte[] poolContents = this.constantPool.poolContent; + + // set initial values for frame positions + int indexInFramePositions = 0; + int framePositionsLength = framePositions.length; + int currentFramePosition = framePositions[0]; + + // set initial values for stack depth markers + int indexInStackDepthMarkers = 0; + StackDepthMarker[] stackDepthMarkers = stackMapFrameCodeStream.getStackDepthMarkers(); + int stackDepthMarkersLength = stackDepthMarkers == null ? 0 : stackDepthMarkers.length; + boolean hasStackDepthMarkers = stackDepthMarkersLength != 0; + StackDepthMarker stackDepthMarker = null; + if (hasStackDepthMarkers) { + stackDepthMarker = stackDepthMarkers[0]; + } + + // set initial values for stack markers (used only in cldc mode) + int indexInStackMarkers = 0; + StackMarker[] stackMarkers = stackMapFrameCodeStream.getStackMarkers(); + int stackMarkersLength = stackMarkers == null ? 0 : stackMarkers.length; + boolean hasStackMarkers = stackMarkersLength != 0; + StackMarker stackMarker = null; + if (hasStackMarkers) { + stackMarker = stackMarkers[0]; + } + + // set initial values for exception markers + int indexInExceptionMarkers = 0; + ExceptionMarker[] exceptionMarkers= stackMapFrameCodeStream.getExceptionMarkers(); + int exceptionsMarkersLength = exceptionMarkers == null ? 0 : exceptionMarkers.length; + boolean hasExceptionMarkers = exceptionsMarkersLength != 0; + ExceptionMarker exceptionMarker = null; + if (hasExceptionMarkers) { + exceptionMarker = exceptionMarkers[0]; + } + + StackMapFrame frame = new StackMapFrame(maxLocals); + if (!isClinit) { + initializeDefaultLocals(frame, methodBinding, maxLocals, codeLength); + } + frame.pc = -1; + add(frames, frame.duplicate()); + addRealJumpTarget(realJumpTarget, -1); + for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) { + ExceptionLabel exceptionLabel = this.codeStream.exceptionLabels[i]; + if (exceptionLabel != null) { + addRealJumpTarget(realJumpTarget, exceptionLabel.position); + } + } + while (true) { + int currentPC = pc - codeOffset; + if (hasStackMarkers && stackMarker.pc == currentPC) { + VerificationTypeInfo[] infos = frame.stackItems; + VerificationTypeInfo[] tempInfos = new VerificationTypeInfo[frame.numberOfStackItems]; + System.arraycopy(infos, 0, tempInfos, 0, frame.numberOfStackItems); + stackMarker.setInfos(tempInfos); + } else if (hasStackMarkers && stackMarker.destinationPC == currentPC) { + VerificationTypeInfo[] infos = stackMarker.infos; + frame.stackItems = infos; + frame.numberOfStackItems = infos.length; + indexInStackMarkers++; + if (indexInStackMarkers < stackMarkersLength) { + stackMarker = stackMarkers[indexInStackMarkers]; + } else { + hasStackMarkers = false; + } + } + if (hasStackDepthMarkers && stackDepthMarker.pc == currentPC) { + TypeBinding typeBinding = stackDepthMarker.typeBinding; + if (typeBinding != null) { + if (stackDepthMarker.delta > 0) { + frame.addStackItem(new VerificationTypeInfo(typeBinding)); + } else { + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(typeBinding); + } + } else { + frame.numberOfStackItems--; + } + indexInStackDepthMarkers++; + if (indexInStackDepthMarkers < stackDepthMarkersLength) { + stackDepthMarker = stackDepthMarkers[indexInStackDepthMarkers]; + } else { + hasStackDepthMarkers = false; + } + } + if (hasExceptionMarkers && exceptionMarker.pc == currentPC) { + frame.numberOfStackItems = 0; + frame.addStackItem(new VerificationTypeInfo(0, VerificationTypeInfo.ITEM_OBJECT, exceptionMarker.constantPoolName)); + indexInExceptionMarkers++; + if (indexInExceptionMarkers < exceptionsMarkersLength) { + exceptionMarker = exceptionMarkers[indexInExceptionMarkers]; + } else { + hasExceptionMarkers = false; + } + } + if (currentFramePosition < currentPC) { + do { + indexInFramePositions++; + if (indexInFramePositions < framePositionsLength) { + currentFramePosition = framePositions[indexInFramePositions]; + } else { + currentFramePosition = Integer.MAX_VALUE; + } + } while (currentFramePosition < currentPC); + } + if (currentFramePosition == currentPC) { + // need to build a new frame and create a stack map attribute entry + StackMapFrame currentFrame = frame.duplicate(); + currentFrame.pc = currentPC; + // initialize locals + initializeLocals(isClinit ? true : methodBinding.isStatic(), currentPC, currentFrame); + // insert a new frame + add(frames, currentFrame); + indexInFramePositions++; + if (indexInFramePositions < framePositionsLength) { + currentFramePosition = framePositions[indexInFramePositions]; + } else { + currentFramePosition = Integer.MAX_VALUE; + } + } + byte opcode = (byte) u1At(bytecodes, 0, pc); + switch (opcode) { + case Opcodes.OPC_nop: + pc++; + break; + case Opcodes.OPC_aconst_null: + frame.addStackItem(TypeBinding.NULL); + pc++; + break; + case Opcodes.OPC_iconst_m1: + case Opcodes.OPC_iconst_0: + case Opcodes.OPC_iconst_1: + case Opcodes.OPC_iconst_2: + case Opcodes.OPC_iconst_3: + case Opcodes.OPC_iconst_4: + case Opcodes.OPC_iconst_5: + frame.addStackItem(TypeBinding.INT); + pc++; + break; + case Opcodes.OPC_lconst_0: + case Opcodes.OPC_lconst_1: + frame.addStackItem(TypeBinding.LONG); + pc++; + break; + case Opcodes.OPC_fconst_0: + case Opcodes.OPC_fconst_1: + case Opcodes.OPC_fconst_2: + frame.addStackItem(TypeBinding.FLOAT); + pc++; + break; + case Opcodes.OPC_dconst_0: + case Opcodes.OPC_dconst_1: + frame.addStackItem(TypeBinding.DOUBLE); + pc++; + break; + case Opcodes.OPC_bipush: + frame.addStackItem(TypeBinding.BYTE); + pc += 2; + break; + case Opcodes.OPC_sipush: + frame.addStackItem(TypeBinding.SHORT); + pc += 3; + break; + case Opcodes.OPC_ldc: + index = u1At(bytecodes, 1, pc); + switch (u1At(poolContents, 0, constantPoolOffsets[index])) { + case ClassFileConstants.StringTag: + frame + .addStackItem(new VerificationTypeInfo( + TypeIds.T_JavaLangString, + ConstantPool.JavaLangStringConstantPoolName)); + break; + case ClassFileConstants.IntegerTag: + frame.addStackItem(TypeBinding.INT); + break; + case ClassFileConstants.FloatTag: + frame.addStackItem(TypeBinding.FLOAT); + break; + case ClassFileConstants.ClassTag: + frame.addStackItem(new VerificationTypeInfo( + TypeIds.T_JavaLangClass, + ConstantPool.JavaLangClassConstantPoolName)); + } + pc += 2; + break; + case Opcodes.OPC_ldc_w: + index = u2At(bytecodes, 1, pc); + switch (u1At(poolContents, 0, constantPoolOffsets[index])) { + case ClassFileConstants.StringTag: + frame + .addStackItem(new VerificationTypeInfo( + TypeIds.T_JavaLangString, + ConstantPool.JavaLangStringConstantPoolName)); + break; + case ClassFileConstants.IntegerTag: + frame.addStackItem(TypeBinding.INT); + break; + case ClassFileConstants.FloatTag: + frame.addStackItem(TypeBinding.FLOAT); + break; + case ClassFileConstants.ClassTag: + frame.addStackItem(new VerificationTypeInfo( + TypeIds.T_JavaLangClass, + ConstantPool.JavaLangClassConstantPoolName)); + } + pc += 3; + break; + case Opcodes.OPC_ldc2_w: + index = u2At(bytecodes, 1, pc); + switch (u1At(poolContents, 0, constantPoolOffsets[index])) { + case ClassFileConstants.DoubleTag: + frame.addStackItem(TypeBinding.DOUBLE); + break; + case ClassFileConstants.LongTag: + frame.addStackItem(TypeBinding.LONG); + break; + } + pc += 3; + break; + case Opcodes.OPC_iload: + frame.addStackItem(TypeBinding.INT); + pc += 2; + break; + case Opcodes.OPC_lload: + frame.addStackItem(TypeBinding.LONG); + pc += 2; + break; + case Opcodes.OPC_fload: + frame.addStackItem(TypeBinding.FLOAT); + pc += 2; + break; + case Opcodes.OPC_dload: + frame.addStackItem(TypeBinding.DOUBLE); + pc += 2; + break; + case Opcodes.OPC_aload: + index = u1At(bytecodes, 1, pc); + VerificationTypeInfo localsN = retrieveLocal(currentPC, index); + frame.addStackItem(localsN); + pc += 2; + break; + case Opcodes.OPC_iload_0: + case Opcodes.OPC_iload_1: + case Opcodes.OPC_iload_2: + case Opcodes.OPC_iload_3: + frame.addStackItem(TypeBinding.INT); + pc++; + break; + case Opcodes.OPC_lload_0: + case Opcodes.OPC_lload_1: + case Opcodes.OPC_lload_2: + case Opcodes.OPC_lload_3: + frame.addStackItem(TypeBinding.LONG); + pc++; + break; + case Opcodes.OPC_fload_0: + case Opcodes.OPC_fload_1: + case Opcodes.OPC_fload_2: + case Opcodes.OPC_fload_3: + frame.addStackItem(TypeBinding.FLOAT); + pc++; + break; + case Opcodes.OPC_dload_0: + case Opcodes.OPC_dload_1: + case Opcodes.OPC_dload_2: + case Opcodes.OPC_dload_3: + frame.addStackItem(TypeBinding.DOUBLE); + pc++; + break; + case Opcodes.OPC_aload_0: + VerificationTypeInfo locals0 = frame.locals[0]; + if (locals0 == null || locals0.tag != VerificationTypeInfo.ITEM_UNINITIALIZED_THIS) { + // special case to handle uninitialized object + locals0 = retrieveLocal(currentPC, 0); + } + frame.addStackItem(locals0); + pc++; + break; + case Opcodes.OPC_aload_1: + VerificationTypeInfo locals1 = retrieveLocal(currentPC, 1); + frame.addStackItem(locals1); + pc++; + break; + case Opcodes.OPC_aload_2: + VerificationTypeInfo locals2 = retrieveLocal(currentPC, 2); + frame.addStackItem(locals2); + pc++; + break; + case Opcodes.OPC_aload_3: + VerificationTypeInfo locals3 = retrieveLocal(currentPC, 3); + frame.addStackItem(locals3); + pc++; + break; + case Opcodes.OPC_iaload: + frame.numberOfStackItems -=2; + frame.addStackItem(TypeBinding.INT); + pc++; + break; + case Opcodes.OPC_laload: + frame.numberOfStackItems -=2; + frame.addStackItem(TypeBinding.LONG); + pc++; + break; + case Opcodes.OPC_faload: + frame.numberOfStackItems -=2; + frame.addStackItem(TypeBinding.FLOAT); + pc++; + break; + case Opcodes.OPC_daload: + frame.numberOfStackItems -=2; + frame.addStackItem(TypeBinding.DOUBLE); + pc++; + break; + case Opcodes.OPC_aaload: + frame.numberOfStackItems--; + frame.replaceWithElementType(); + pc++; + break; + case Opcodes.OPC_baload: + frame.numberOfStackItems -=2; + frame.addStackItem(TypeBinding.BYTE); + pc++; + break; + case Opcodes.OPC_caload: + frame.numberOfStackItems -=2; + frame.addStackItem(TypeBinding.CHAR); + pc++; + break; + case Opcodes.OPC_saload: + frame.numberOfStackItems -=2; + frame.addStackItem(TypeBinding.SHORT); + pc++; + break; + case Opcodes.OPC_istore: + case Opcodes.OPC_lstore: + case Opcodes.OPC_fstore: + case Opcodes.OPC_dstore: + frame.numberOfStackItems--; + pc += 2; + break; + case Opcodes.OPC_astore: + index = u1At(bytecodes, 1, pc); + frame.numberOfStackItems--; + pc += 2; + break; + case Opcodes.OPC_astore_0: + frame.locals[0] = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + pc++; + break; + case Opcodes.OPC_astore_1: + case Opcodes.OPC_astore_2: + case Opcodes.OPC_astore_3: + case Opcodes.OPC_istore_0: + case Opcodes.OPC_istore_1: + case Opcodes.OPC_istore_2: + case Opcodes.OPC_istore_3: + case Opcodes.OPC_lstore_0: + case Opcodes.OPC_lstore_1: + case Opcodes.OPC_lstore_2: + case Opcodes.OPC_lstore_3: + case Opcodes.OPC_fstore_0: + case Opcodes.OPC_fstore_1: + case Opcodes.OPC_fstore_2: + case Opcodes.OPC_fstore_3: + case Opcodes.OPC_dstore_0: + case Opcodes.OPC_dstore_1: + case Opcodes.OPC_dstore_2: + case Opcodes.OPC_dstore_3: + frame.numberOfStackItems--; + pc++; + break; + case Opcodes.OPC_iastore: + case Opcodes.OPC_lastore: + case Opcodes.OPC_fastore: + case Opcodes.OPC_dastore: + case Opcodes.OPC_aastore: + case Opcodes.OPC_bastore: + case Opcodes.OPC_castore: + case Opcodes.OPC_sastore: + frame.numberOfStackItems-=3; + pc++; + break; + case Opcodes.OPC_pop: + frame.numberOfStackItems--; + pc++; + break; + case Opcodes.OPC_pop2: + int numberOfStackItems = frame.numberOfStackItems; + switch(frame.stackItems[numberOfStackItems - 1].id()) { + case TypeIds.T_long : + case TypeIds.T_double : + frame.numberOfStackItems--; + break; + default: + frame.numberOfStackItems -= 2; + } + pc++; + break; + case Opcodes.OPC_dup: + frame.addStackItem(frame.stackItems[frame.numberOfStackItems - 1]); + pc++; + break; + case Opcodes.OPC_dup_x1: + VerificationTypeInfo info = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + VerificationTypeInfo info2 = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + frame.addStackItem(info); + frame.addStackItem(info2); + frame.addStackItem(info); + pc++; + break; + case Opcodes.OPC_dup_x2: + info = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + info2 = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + switch(info2.id()) { + case TypeIds.T_long : + case TypeIds.T_double : + frame.addStackItem(info); + frame.addStackItem(info2); + frame.addStackItem(info); + break; + default: + numberOfStackItems = frame.numberOfStackItems; + VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1]; + frame.numberOfStackItems--; + frame.addStackItem(info); + frame.addStackItem(info3); + frame.addStackItem(info2); + frame.addStackItem(info); + } + pc++; + break; + case Opcodes.OPC_dup2: + info = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + switch(info.id()) { + case TypeIds.T_double : + case TypeIds.T_long : + frame.addStackItem(info); + frame.addStackItem(info); + break; + default: + info2 = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + frame.addStackItem(info2); + frame.addStackItem(info); + frame.addStackItem(info2); + frame.addStackItem(info); + } + pc++; + break; + case Opcodes.OPC_dup2_x1: + info = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + info2 = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + switch(info.id()) { + case TypeIds.T_double : + case TypeIds.T_long : + frame.addStackItem(info); + frame.addStackItem(info2); + frame.addStackItem(info); + break; + default: + VerificationTypeInfo info3 = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + frame.addStackItem(info2); + frame.addStackItem(info); + frame.addStackItem(info3); + frame.addStackItem(info2); + frame.addStackItem(info); + } + pc++; + break; + case Opcodes.OPC_dup2_x2: + numberOfStackItems = frame.numberOfStackItems; + info = frame.stackItems[numberOfStackItems - 1]; + frame.numberOfStackItems--; + info2 = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + switch(info.id()) { + case TypeIds.T_long : + case TypeIds.T_double : + switch(info2.id()) { + case TypeIds.T_long : + case TypeIds.T_double : + // form 4 + frame.addStackItem(info); + frame.addStackItem(info2); + frame.addStackItem(info); + break; + default: + // form 2 + numberOfStackItems = frame.numberOfStackItems; + VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1]; + frame.numberOfStackItems--; + frame.addStackItem(info); + frame.addStackItem(info3); + frame.addStackItem(info2); + frame.addStackItem(info); + } + break; + default: + numberOfStackItems = frame.numberOfStackItems; + VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1]; + frame.numberOfStackItems--; + switch(info3.id()) { + case TypeIds.T_long : + case TypeIds.T_double : + // form 3 + frame.addStackItem(info2); + frame.addStackItem(info); + frame.addStackItem(info3); + frame.addStackItem(info2); + frame.addStackItem(info); + break; + default: + // form 1 + numberOfStackItems = frame.numberOfStackItems; + VerificationTypeInfo info4 = frame.stackItems[numberOfStackItems - 1]; + frame.numberOfStackItems--; + frame.addStackItem(info2); + frame.addStackItem(info); + frame.addStackItem(info4); + frame.addStackItem(info3); + frame.addStackItem(info2); + frame.addStackItem(info); + } + } + pc++; + break; + case Opcodes.OPC_swap: + numberOfStackItems = frame.numberOfStackItems; + info = frame.stackItems[numberOfStackItems - 1]; + info2 = frame.stackItems[numberOfStackItems - 2]; + frame.stackItems[numberOfStackItems - 1] = info2; + frame.stackItems[numberOfStackItems - 2] = info; + pc++; + break; + case Opcodes.OPC_iadd: + case Opcodes.OPC_ladd: + case Opcodes.OPC_fadd: + case Opcodes.OPC_dadd: + case Opcodes.OPC_isub: + case Opcodes.OPC_lsub: + case Opcodes.OPC_fsub: + case Opcodes.OPC_dsub: + case Opcodes.OPC_imul: + case Opcodes.OPC_lmul: + case Opcodes.OPC_fmul: + case Opcodes.OPC_dmul: + case Opcodes.OPC_idiv: + case Opcodes.OPC_ldiv: + case Opcodes.OPC_fdiv: + case Opcodes.OPC_ddiv: + case Opcodes.OPC_irem: + case Opcodes.OPC_lrem: + case Opcodes.OPC_frem: + case Opcodes.OPC_drem: + case Opcodes.OPC_ishl: + case Opcodes.OPC_lshl: + case Opcodes.OPC_ishr: + case Opcodes.OPC_lshr: + case Opcodes.OPC_iushr: + case Opcodes.OPC_lushr: + case Opcodes.OPC_iand: + case Opcodes.OPC_land: + case Opcodes.OPC_ior: + case Opcodes.OPC_lor: + case Opcodes.OPC_ixor: + case Opcodes.OPC_lxor: + frame.numberOfStackItems--; + pc++; + break; + case Opcodes.OPC_ineg: + case Opcodes.OPC_lneg: + case Opcodes.OPC_fneg: + case Opcodes.OPC_dneg: + pc++; + break; + case Opcodes.OPC_iinc: + pc += 3; + break; + case Opcodes.OPC_i2l: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG); + pc++; + break; + case Opcodes.OPC_i2f: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT); + pc++; + break; + case Opcodes.OPC_i2d: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE); + pc++; + break; + case Opcodes.OPC_l2i: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT); + pc++; + break; + case Opcodes.OPC_l2f: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT); + pc++; + break; + case Opcodes.OPC_l2d: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE); + pc++; + break; + case Opcodes.OPC_f2i: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT); + pc++; + break; + case Opcodes.OPC_f2l: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG); + pc++; + break; + case Opcodes.OPC_f2d: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE); + pc++; + break; + case Opcodes.OPC_d2i: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT); + pc++; + break; + case Opcodes.OPC_d2l: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG); + pc++; + break; + case Opcodes.OPC_d2f: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT); + pc++; + break; + case Opcodes.OPC_i2b: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.BYTE); + pc++; + break; + case Opcodes.OPC_i2c: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.CHAR); + pc++; + break; + case Opcodes.OPC_i2s: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.SHORT); + pc++; + break; + case Opcodes.OPC_lcmp: + case Opcodes.OPC_fcmpl: + case Opcodes.OPC_fcmpg: + case Opcodes.OPC_dcmpl: + case Opcodes.OPC_dcmpg: + frame.numberOfStackItems-=2; + frame.addStackItem(TypeBinding.INT); + pc++; + break; + case Opcodes.OPC_ifeq: + case Opcodes.OPC_ifne: + case Opcodes.OPC_iflt: + case Opcodes.OPC_ifge: + case Opcodes.OPC_ifgt: + case Opcodes.OPC_ifle: + frame.numberOfStackItems--; + addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc)); + pc += 3; + break; + case Opcodes.OPC_if_icmpeq: + case Opcodes.OPC_if_icmpne: + case Opcodes.OPC_if_icmplt: + case Opcodes.OPC_if_icmpge: + case Opcodes.OPC_if_icmpgt: + case Opcodes.OPC_if_icmple: + case Opcodes.OPC_if_acmpeq: + case Opcodes.OPC_if_acmpne: + frame.numberOfStackItems -= 2; + addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc)); + pc += 3; + break; + case Opcodes.OPC_goto: + addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc)); + pc += 3; + addRealJumpTarget(realJumpTarget, pc - codeOffset); + break; + case Opcodes.OPC_tableswitch: + pc++; + while (((pc - codeOffset) & 0x03) != 0) { + pc++; + } + // default offset + addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc)); + pc += 4; // default + int low = i4At(bytecodes, 0, pc); + pc += 4; + int high = i4At(bytecodes, 0, pc); + pc += 4; + int length = high - low + 1; + for (int i = 0; i < length; i++) { + // pair offset + addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc)); + pc += 4; + } + frame.numberOfStackItems--; + break; + case Opcodes.OPC_lookupswitch: + pc++; + while (((pc - codeOffset) & 0x03) != 0) { + pc++; + } + addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc)); + pc += 4; // default offset + int npairs = (int) u4At(bytecodes, 0, pc); + pc += 4; // npair value + for (int i = 0; i < npairs; i++) { + pc += 4; // case value + // pair offset + addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc)); + pc += 4; + } + frame.numberOfStackItems--; + break; + case Opcodes.OPC_ireturn: + case Opcodes.OPC_lreturn: + case Opcodes.OPC_freturn: + case Opcodes.OPC_dreturn: + case Opcodes.OPC_areturn: + frame.numberOfStackItems--; + pc++; + addRealJumpTarget(realJumpTarget, pc - codeOffset); + break; + case Opcodes.OPC_return: + pc++; + addRealJumpTarget(realJumpTarget, pc - codeOffset); + break; + case Opcodes.OPC_getstatic: + index = u2At(bytecodes, 1, pc); + int nameAndTypeIndex = u2At(poolContents, 3, + constantPoolOffsets[index]); + int utf8index = u2At(poolContents, 3, + constantPoolOffsets[nameAndTypeIndex]); + char[] descriptor = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + if (descriptor.length == 1) { + // base type + switch(descriptor[0]) { + case 'Z': + frame.addStackItem(TypeBinding.BOOLEAN); + break; + case 'B': + frame.addStackItem(TypeBinding.BYTE); + break; + case 'C': + frame.addStackItem(TypeBinding.CHAR); + break; + case 'D': + frame.addStackItem(TypeBinding.DOUBLE); + break; + case 'F': + frame.addStackItem(TypeBinding.FLOAT); + break; + case 'I': + frame.addStackItem(TypeBinding.INT); + break; + case 'J': + frame.addStackItem(TypeBinding.LONG); + break; + case 'S': + frame.addStackItem(TypeBinding.SHORT); + break; + } + } else if (descriptor[0] == '[') { + frame.addStackItem(new VerificationTypeInfo(0, descriptor)); + } else { + frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(descriptor, 1, descriptor.length - 1))); + } + pc += 3; + break; + case Opcodes.OPC_putstatic: + frame.numberOfStackItems--; + pc += 3; + break; + case Opcodes.OPC_getfield: + index = u2At(bytecodes, 1, pc); + nameAndTypeIndex = u2At(poolContents, 3, + constantPoolOffsets[index]); + utf8index = u2At(poolContents, 3, + constantPoolOffsets[nameAndTypeIndex]); + descriptor = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + frame.numberOfStackItems--; + if (descriptor.length == 1) { + // base type + switch(descriptor[0]) { + case 'Z': + frame.addStackItem(TypeBinding.BOOLEAN); + break; + case 'B': + frame.addStackItem(TypeBinding.BYTE); + break; + case 'C': + frame.addStackItem(TypeBinding.CHAR); + break; + case 'D': + frame.addStackItem(TypeBinding.DOUBLE); + break; + case 'F': + frame.addStackItem(TypeBinding.FLOAT); + break; + case 'I': + frame.addStackItem(TypeBinding.INT); + break; + case 'J': + frame.addStackItem(TypeBinding.LONG); + break; + case 'S': + frame.addStackItem(TypeBinding.SHORT); + break; + } + } else if (descriptor[0] == '[') { + frame.addStackItem(new VerificationTypeInfo(0, descriptor)); + } else { + frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(descriptor, 1, descriptor.length - 1))); + } + pc += 3; + break; + case Opcodes.OPC_putfield: + frame.numberOfStackItems -= 2; + pc += 3; + break; + case Opcodes.OPC_invokevirtual: + index = u2At(bytecodes, 1, pc); + nameAndTypeIndex = u2At(poolContents, 3, + constantPoolOffsets[index]); + utf8index = u2At(poolContents, 3, + constantPoolOffsets[nameAndTypeIndex]); + descriptor = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + utf8index = u2At(poolContents, 1, + constantPoolOffsets[nameAndTypeIndex]); + char[] name = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + frame.numberOfStackItems -= (getParametersCount(descriptor) + 1); + char[] returnType = getReturnType(descriptor); + if (returnType.length == 1) { + // base type + switch(returnType[0]) { + case 'Z': + frame.addStackItem(TypeBinding.BOOLEAN); + break; + case 'B': + frame.addStackItem(TypeBinding.BYTE); + break; + case 'C': + frame.addStackItem(TypeBinding.CHAR); + break; + case 'D': + frame.addStackItem(TypeBinding.DOUBLE); + break; + case 'F': + frame.addStackItem(TypeBinding.FLOAT); + break; + case 'I': + frame.addStackItem(TypeBinding.INT); + break; + case 'J': + frame.addStackItem(TypeBinding.LONG); + break; + case 'S': + frame.addStackItem(TypeBinding.SHORT); + break; + } + } else { + if (returnType[0] == '[') { + frame.addStackItem(new VerificationTypeInfo(0, returnType)); + } else { + frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1))); + } + } + pc += 3; + break; + case Opcodes.OPC_invokedynamic: + index = u2At(bytecodes, 1, pc); + nameAndTypeIndex = u2At(poolContents, 3, + constantPoolOffsets[index]); + utf8index = u2At(poolContents, 3, + constantPoolOffsets[nameAndTypeIndex]); + descriptor = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + frame.numberOfStackItems -= getParametersCount(descriptor); + returnType = getReturnType(descriptor); + if (returnType.length == 1) { + // base type + switch(returnType[0]) { + case 'Z': + frame.addStackItem(TypeBinding.BOOLEAN); + break; + case 'B': + frame.addStackItem(TypeBinding.BYTE); + break; + case 'C': + frame.addStackItem(TypeBinding.CHAR); + break; + case 'D': + frame.addStackItem(TypeBinding.DOUBLE); + break; + case 'F': + frame.addStackItem(TypeBinding.FLOAT); + break; + case 'I': + frame.addStackItem(TypeBinding.INT); + break; + case 'J': + frame.addStackItem(TypeBinding.LONG); + break; + case 'S': + frame.addStackItem(TypeBinding.SHORT); + break; + } + } else { + if (returnType[0] == '[') { + frame.addStackItem(new VerificationTypeInfo(0, returnType)); + } else { + frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1))); + } + } + pc += 5; + break; + case Opcodes.OPC_invokespecial: + index = u2At(bytecodes, 1, pc); + nameAndTypeIndex = u2At(poolContents, 3, + constantPoolOffsets[index]); + utf8index = u2At(poolContents, 3, + constantPoolOffsets[nameAndTypeIndex]); + descriptor = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + utf8index = u2At(poolContents, 1, + constantPoolOffsets[nameAndTypeIndex]); + name = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + frame.numberOfStackItems -= getParametersCount(descriptor); + if (CharOperation.equals(ConstantPool.Init, name)) { + // constructor + frame.stackItems[frame.numberOfStackItems - 1].tag = VerificationTypeInfo.ITEM_OBJECT; + } + frame.numberOfStackItems--; + returnType = getReturnType(descriptor); + if (returnType.length == 1) { + // base type + switch(returnType[0]) { + case 'Z': + frame.addStackItem(TypeBinding.BOOLEAN); + break; + case 'B': + frame.addStackItem(TypeBinding.BYTE); + break; + case 'C': + frame.addStackItem(TypeBinding.CHAR); + break; + case 'D': + frame.addStackItem(TypeBinding.DOUBLE); + break; + case 'F': + frame.addStackItem(TypeBinding.FLOAT); + break; + case 'I': + frame.addStackItem(TypeBinding.INT); + break; + case 'J': + frame.addStackItem(TypeBinding.LONG); + break; + case 'S': + frame.addStackItem(TypeBinding.SHORT); + break; + } + } else { + if (returnType[0] == '[') { + frame.addStackItem(new VerificationTypeInfo(0, returnType)); + } else { + frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1))); + } + } + pc += 3; + break; + case Opcodes.OPC_invokestatic: + index = u2At(bytecodes, 1, pc); + nameAndTypeIndex = u2At(poolContents, 3, + constantPoolOffsets[index]); + utf8index = u2At(poolContents, 3, + constantPoolOffsets[nameAndTypeIndex]); + descriptor = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + utf8index = u2At(poolContents, 1, + constantPoolOffsets[nameAndTypeIndex]); + name = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + frame.numberOfStackItems -= getParametersCount(descriptor); + returnType = getReturnType(descriptor); + if (returnType.length == 1) { + // base type + switch(returnType[0]) { + case 'Z': + frame.addStackItem(TypeBinding.BOOLEAN); + break; + case 'B': + frame.addStackItem(TypeBinding.BYTE); + break; + case 'C': + frame.addStackItem(TypeBinding.CHAR); + break; + case 'D': + frame.addStackItem(TypeBinding.DOUBLE); + break; + case 'F': + frame.addStackItem(TypeBinding.FLOAT); + break; + case 'I': + frame.addStackItem(TypeBinding.INT); + break; + case 'J': + frame.addStackItem(TypeBinding.LONG); + break; + case 'S': + frame.addStackItem(TypeBinding.SHORT); + break; + } + } else { + if (returnType[0] == '[') { + frame.addStackItem(new VerificationTypeInfo(0, returnType)); + } else { + frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1))); + } + } + pc += 3; + break; + case Opcodes.OPC_invokeinterface: + index = u2At(bytecodes, 1, pc); + nameAndTypeIndex = u2At(poolContents, 3, + constantPoolOffsets[index]); + utf8index = u2At(poolContents, 3, + constantPoolOffsets[nameAndTypeIndex]); + descriptor = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + utf8index = u2At(poolContents, 1, + constantPoolOffsets[nameAndTypeIndex]); + name = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + // we don't need count and args + // u1At(bytecodes, 3, pc); // count + // u1At(bytecodes, 4, pc); // extra args + frame.numberOfStackItems -= (getParametersCount(descriptor) + 1); + returnType = getReturnType(descriptor); + if (returnType.length == 1) { + // base type + switch(returnType[0]) { + case 'Z': + frame.addStackItem(TypeBinding.BOOLEAN); + break; + case 'B': + frame.addStackItem(TypeBinding.BYTE); + break; + case 'C': + frame.addStackItem(TypeBinding.CHAR); + break; + case 'D': + frame.addStackItem(TypeBinding.DOUBLE); + break; + case 'F': + frame.addStackItem(TypeBinding.FLOAT); + break; + case 'I': + frame.addStackItem(TypeBinding.INT); + break; + case 'J': + frame.addStackItem(TypeBinding.LONG); + break; + case 'S': + frame.addStackItem(TypeBinding.SHORT); + break; + } + } else { + if (returnType[0] == '[') { + frame.addStackItem(new VerificationTypeInfo(0, returnType)); + } else { + frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1))); + } + } + pc += 5; + break; + case Opcodes.OPC_new: + index = u2At(bytecodes, 1, pc); + utf8index = u2At(poolContents, 1, + constantPoolOffsets[index]); + char[] className = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(0, VerificationTypeInfo.ITEM_UNINITIALIZED, className); + verificationTypeInfo.offset = currentPC; + frame.addStackItem(verificationTypeInfo); + pc += 3; + break; + case Opcodes.OPC_newarray: + char[] constantPoolName = null; + switch (u1At(bytecodes, 1, pc)) { + case ClassFileConstants.INT_ARRAY : + constantPoolName = new char[] { '[', 'I' }; + break; + case ClassFileConstants.BYTE_ARRAY : + constantPoolName = new char[] { '[', 'B' }; + break; + case ClassFileConstants.BOOLEAN_ARRAY : + constantPoolName = new char[] { '[', 'Z' }; + break; + case ClassFileConstants.SHORT_ARRAY : + constantPoolName = new char[] { '[', 'S' }; + break; + case ClassFileConstants.CHAR_ARRAY : + constantPoolName = new char[] { '[', 'C' }; + break; + case ClassFileConstants.LONG_ARRAY : + constantPoolName = new char[] { '[', 'J' }; + break; + case ClassFileConstants.FLOAT_ARRAY : + constantPoolName = new char[] { '[', 'F' }; + break; + case ClassFileConstants.DOUBLE_ARRAY : + constantPoolName = new char[] { '[', 'D' }; + break; + } + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangObject, constantPoolName); + pc += 2; + break; + case Opcodes.OPC_anewarray: + index = u2At(bytecodes, 1, pc); + utf8index = u2At(poolContents, 1, + constantPoolOffsets[index]); + className = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + int classNameLength = className.length; + if (className[0] != '[') { + // this is a type name (class or interface). So we add appropriate '[', 'L' and ';'. + System.arraycopy(className, 0, (constantPoolName = new char[classNameLength + 3]), 2, classNameLength); + constantPoolName[0] = '['; + constantPoolName[1] = 'L'; + constantPoolName[classNameLength + 2] = ';'; + } else { + // if class name is already an array, we just need to add one dimension + System.arraycopy(className, 0, (constantPoolName = new char[classNameLength + 1]), 1, classNameLength); + constantPoolName[0] = '['; + } + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(0, constantPoolName); + pc += 3; + break; + case Opcodes.OPC_arraylength: + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT); + pc++; + break; + case Opcodes.OPC_athrow: + frame.numberOfStackItems--; + pc++; + addRealJumpTarget(realJumpTarget, pc - codeOffset); + break; + case Opcodes.OPC_checkcast: + index = u2At(bytecodes, 1, pc); + utf8index = u2At(poolContents, 1, + constantPoolOffsets[index]); + className = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(0, className); + pc += 3; + break; + case Opcodes.OPC_instanceof: + // no need to know the class index = u2At(bytecodes, 1, pc); + frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT); + pc += 3; + break; + case Opcodes.OPC_monitorenter: + case Opcodes.OPC_monitorexit: + frame.numberOfStackItems--; + pc++; + break; + case Opcodes.OPC_wide: + opcode = (byte) u1At(bytecodes, 1, pc); + if (opcode == Opcodes.OPC_iinc) { + // index = u2At(bytecodes, 2, pc); + // i2At(bytecodes, 4, pc); // const + // we don't need the index and the const value + pc += 6; + } else { + index = u2At(bytecodes, 2, pc); + // need to handle iload, fload, aload, lload, dload, istore, fstore, astore, lstore or dstore + switch(opcode) { + case Opcodes.OPC_iload : + frame.addStackItem(TypeBinding.INT); + break; + case Opcodes.OPC_fload : + frame.addStackItem(TypeBinding.FLOAT); + break; + case Opcodes.OPC_aload : + localsN = frame.locals[index]; + if (localsN == null) { + localsN = retrieveLocal(currentPC, index); + } + frame.addStackItem(localsN); + break; + case Opcodes.OPC_lload : + frame.addStackItem(TypeBinding.LONG); + break; + case Opcodes.OPC_dload : + frame.addStackItem(TypeBinding.DOUBLE); + break; + case Opcodes.OPC_istore : + frame.numberOfStackItems--; + break; + case Opcodes.OPC_fstore : + frame.numberOfStackItems--; + break; + case Opcodes.OPC_astore : + frame.locals[index] = frame.stackItems[frame.numberOfStackItems - 1]; + frame.numberOfStackItems--; + break; + case Opcodes.OPC_lstore : + frame.numberOfStackItems--; + break; + case Opcodes.OPC_dstore : + frame.numberOfStackItems--; + break; + } + pc += 4; + } + break; + case Opcodes.OPC_multianewarray: + index = u2At(bytecodes, 1, pc); + utf8index = u2At(poolContents, 1, + constantPoolOffsets[index]); + className = utf8At(poolContents, + constantPoolOffsets[utf8index] + 3, u2At( + poolContents, 1, + constantPoolOffsets[utf8index])); + int dimensions = u1At(bytecodes, 3, pc); // dimensions + frame.numberOfStackItems -= dimensions; + classNameLength = className.length; + constantPoolName = new char[classNameLength + dimensions]; + for (int i = 0; i < dimensions; i++) { + constantPoolName[i] = '['; + } + System.arraycopy(className, 0, constantPoolName, dimensions, classNameLength); + frame.addStackItem(new VerificationTypeInfo(0, constantPoolName)); + pc += 4; + break; + case Opcodes.OPC_ifnull: + case Opcodes.OPC_ifnonnull: + frame.numberOfStackItems--; + addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc)); + pc += 3; + break; + case Opcodes.OPC_goto_w: + addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 1, pc)); + pc += 5; + addRealJumpTarget(realJumpTarget, pc - codeOffset); // handle infinite loop + break; + default: // should not occur + if (this.codeStream.methodDeclaration != null) { + this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError( + Messages.bind( + Messages.abort_invalidOpcode, + new Object[] { + new Byte(opcode), + new Integer(pc), + new String(methodBinding.shortReadableName()), + }), + this.codeStream.methodDeclaration); + } else { + this.codeStream.lambdaExpression.scope.problemReporter().abortDueToInternalError( + Messages.bind( + Messages.abort_invalidOpcode, + new Object[] { + new Byte(opcode), + new Integer(pc), + new String(methodBinding.shortReadableName()), + }), + this.codeStream.lambdaExpression); + } + break; + } + if (pc >= (codeLength + codeOffset)) { + break; + } + } + return filterFakeFrames(realJumpTarget, frames, codeLength); + } + + private void addRealJumpTarget(Set realJumpTarget, int pc) { + realJumpTarget.add(new Integer(pc)); + } + private void add(Map frames, StackMapFrame frame) { + frames.put(new Integer(frame.pc), frame); + } + private final int u1At(byte[] reference, int relativeOffset, + int structOffset) { + return (reference[relativeOffset + structOffset] & 0xFF); + } + + private final int u2At(byte[] reference, int relativeOffset, + int structOffset) { + int position = relativeOffset + structOffset; + return ((reference[position++] & 0xFF) << 8) + + (reference[position] & 0xFF); + } + + private final long u4At(byte[] reference, int relativeOffset, + int structOffset) { + int position = relativeOffset + structOffset; + return (((reference[position++] & 0xFFL) << 24) + + ((reference[position++] & 0xFF) << 16) + + ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF)); + } + // AspectJ Extension + void writeToContents(byte[] data) { + int N = data.length; + if (contentsOffset + N >= this.contents.length) { + resizeContents(N); + } + System.arraycopy(data,0,contents,contentsOffset,N); + contentsOffset += N; + } + // End AspectJ Extension + + private final int i2At(byte[] reference, int relativeOffset, int structOffset) { + int position = relativeOffset + structOffset; + return (reference[position++] << 8) + (reference[position] & 0xFF); + } + + public char[] utf8At(byte[] reference, int absoluteOffset, + int bytesAvailable) { + int length = bytesAvailable; + char outputBuf[] = new char[bytesAvailable]; + int outputPos = 0; + int readOffset = absoluteOffset; + + while (length != 0) { + int x = reference[readOffset++] & 0xFF; + length--; + if ((0x80 & x) != 0) { + if ((x & 0x20) != 0) { + length -= 2; + x = ((x & 0xF) << 12) + | ((reference[readOffset++] & 0x3F) << 6) + | (reference[readOffset++] & 0x3F); + } else { + length--; + x = ((x & 0x1F) << 6) | (reference[readOffset++] & 0x3F); + } + } + outputBuf[outputPos++] = (char) x; + } + + if (outputPos != bytesAvailable) { + System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]), + 0, outputPos); + } + return outputBuf; + } +} diff --git a/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java b/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java index 84bc8e5ec..48957fabd 100644 --- a/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java +++ b/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java @@ -253,9 +253,9 @@ public class AjcTask extends MatchingTask { public static final String COMMAND_EDITOR_NAME = AjcTask.class.getName() + ".COMMAND_EDITOR"; - static final String[] TARGET_INPUTS = new String[] { "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8" }; - static final String[] SOURCE_INPUTS = new String[] { "1.3", "1.4", "1.5", "1.6", "1.7", "1.8" }; - static final String[] COMPLIANCE_INPUTS = new String[] { "-1.3", "-1.4", "-1.5", "-1.6", "-1.7", "-1.8" }; + static final String[] TARGET_INPUTS = new String[] { "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "9" }; + static final String[] SOURCE_INPUTS = new String[] { "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "9" }; + static final String[] COMPLIANCE_INPUTS = new String[] { "-1.3", "-1.4", "-1.5", "-1.6", "-1.7", "-1.8", "-1.9", "-9" }; private static final ICommandEditor COMMAND_EDITOR; diff --git a/testing-client/src/org/aspectj/testing/server/TestServer.java b/testing-client/src/org/aspectj/testing/server/TestServer.java index 12e8d097e..80cbc357b 100644 --- a/testing-client/src/org/aspectj/testing/server/TestServer.java +++ b/testing-client/src/org/aspectj/testing/server/TestServer.java @@ -1,12 +1,9 @@ /******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. + * Copyright (c) 2006,2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Matthew Webster - initial implementation *******************************************************************************/ package org.aspectj.testing.server; @@ -25,6 +22,10 @@ import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; +/** + * @author Matthew Webster + * @author Andy Clement + */ public class TestServer implements Runnable { private static final boolean debug = Boolean.getBoolean("org.aspectj.testing.server.debug"); @@ -49,7 +50,7 @@ public class TestServer implements Runnable { props.load(in); in.close(); - Enumeration enu = props.propertyNames(); + Enumeration<?> enu = props.propertyNames(); while (enu.hasMoreElements()) { String key = (String)enu.nextElement(); if (key.startsWith("loader.")) { @@ -69,19 +70,20 @@ public class TestServer implements Runnable { StringTokenizer st = new StringTokenizer(property,","); String name = st.nextToken(); String classpath = st.nextToken(); + if (debug) System.err.println("Creating loader "+name+" with classpath "+classpath); if (st.hasMoreTokens()) { String parentName = st.nextToken(); parent = (ClassLoader)loaders.get(parentName); if (parent == null) error("No such loader: " + parentName); } - + List<URL> urlList = new ArrayList<>(); st = new StringTokenizer(classpath,";"); while (st.hasMoreTokens()) { String fileName = st.nextToken(); File file = new File(workingDirectory,fileName).getCanonicalFile(); if (!file.exists()) error("Missing or invalid file: " + file.getPath()); - URL url = file.toURL(); + URL url = file.toURI().toURL(); urlList.add(url); } URL[] urls = new URL[urlList.size()]; @@ -92,25 +94,26 @@ public class TestServer implements Runnable { loaders.put(name,loader); } - private void createRootLoader () throws IOException { - List<URL> urlList = new ArrayList(); + private void createRootLoader() throws IOException { + List<URL> urlList = new ArrayList<>(); - /* Sandbox */ - URL url = workingDirectory.getCanonicalFile().toURL(); + // Sandbox + URL url = workingDirectory.getCanonicalFile().toURI().toURL(); urlList.add(url); - /* AspectJ runtime */ - URL[] urls = ((URLClassLoader)getClass().getClassLoader()).getURLs(); - for (int i = 0; i < urls.length; i++) { - url = urls[i]; - String file = url.getFile(); - if (debug) System.err.println("? TestServer.createRootLoader() " + file); - if (file.indexOf("runtime") != -1 || file.indexOf("aspectjrt") != -1 || file.indexOf("aspectj5rt") != -1) { - urlList.add(url); - } + // Find the AspectJ root folder (i.e. org.aspectj) + File aspectjBase = new File(".").getCanonicalFile(); + while (aspectjBase!= null && !aspectjBase.getName().equals("org.aspectj")) { + aspectjBase = aspectjBase.getParentFile(); + } + if (aspectjBase == null) { + error("Unable to locate 'org.aspectj' in "+new File(".").getCanonicalPath()); } + urlList.add(new File(aspectjBase,"runtime/bin").toURI().toURL()); + urlList.add(new File(aspectjBase,"aspectjrt/bin").toURI().toURL()); + urlList.add(new File(aspectjBase,"aspectj5rt/bin").toURI().toURL()); - urls = new URL[urlList.size()]; + URL[] urls = new URL[urlList.size()]; urlList.toArray(urls); ClassLoader parent = getClass().getClassLoader().getParent(); rootLoader = new URLClassLoader(urls,parent); @@ -156,9 +159,9 @@ public class TestServer implements Runnable { } } - public void invokeMain (Class clazz, String[] args) + public void invokeMain (Class<?> clazz, String[] args) { - Class[] paramTypes = new Class[1]; + Class<?>[] paramTypes = new Class[1]; paramTypes[0] = args.getClass(); try { diff --git a/testing-drivers/testsrc/org/aspectj/testing/drivers/HarnessSelectionTest.java b/testing-drivers/testsrc/org/aspectj/testing/drivers/HarnessSelectionTest.java index 9f50d0ff1..ac937ac44 100644 --- a/testing-drivers/testsrc/org/aspectj/testing/drivers/HarnessSelectionTest.java +++ b/testing-drivers/testsrc/org/aspectj/testing/drivers/HarnessSelectionTest.java @@ -18,6 +18,7 @@ import org.aspectj.bridge.MessageHandler; import org.aspectj.bridge.MessageUtil; import org.aspectj.testing.harness.bridge.AbstractRunSpec; import org.aspectj.testing.harness.bridge.AjcTest; +import org.aspectj.testing.harness.bridge.IRunSpec; import org.aspectj.testing.run.IRunStatus; import org.aspectj.testing.run.RunValidator; import org.aspectj.testing.util.BridgeUtil; @@ -298,7 +299,7 @@ public class HarnessSelectionTest extends TestCase { runtime.setOptions(options); AjcTest.Suite.Spec spec = getSpec(suiteFile); assertNotNull(spec); - ArrayList kids = spec.getChildren(); + ArrayList<IRunSpec> kids = spec.getChildren(); assertNotNull(kids); if ((suiteFile == SELECT) && (17 != kids.size())) { assertTrue("expected 17 kids, got " + kids.size(), false); diff --git a/testing/newsrc/org/aspectj/testing/AjcTest.java b/testing/newsrc/org/aspectj/testing/AjcTest.java index e022d1c45..2cc450636 100644 --- a/testing/newsrc/org/aspectj/testing/AjcTest.java +++ b/testing/newsrc/org/aspectj/testing/AjcTest.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.List; import org.aspectj.tools.ajc.AjcTestCase; +import org.aspectj.util.LangUtil; /** * @author Adrian Colyer @@ -25,28 +26,15 @@ public class AjcTest { private static boolean is16VMOrGreater = false; private static boolean is17VMOrGreater = false; private static boolean is18VMOrGreater = false; + private static boolean is19VMOrGreater = false; static { // matching logic is also in org.aspectj.util.LangUtil - String vm = System.getProperty("java.version"); // JLS 20.18.7 - if (vm==null) vm = System.getProperty("java.runtime.version"); - if (vm==null) vm = System.getProperty("java.vm.version"); - if (vm.startsWith("1.3")) { - is14VMOrGreater = false; - } else if (vm.startsWith("1.5")) { - is15VMOrGreater = true; - } else if (vm.startsWith("1.6")) { - is15VMOrGreater = true; - is16VMOrGreater = true; - } else if (vm.startsWith("1.7")) { - is15VMOrGreater = true; - is16VMOrGreater = true; - is17VMOrGreater = true; - } else if (vm.startsWith("1.8")) { - is15VMOrGreater = true; - is16VMOrGreater = true; - is17VMOrGreater = true; - is18VMOrGreater = true; - } + is14VMOrGreater = LangUtil.is14VMOrGreater(); + is15VMOrGreater = LangUtil.is15VMOrGreater(); + is16VMOrGreater = LangUtil.is16VMOrGreater(); + is17VMOrGreater = LangUtil.is17VMOrGreater(); + is18VMOrGreater = LangUtil.is18VMOrGreater(); + is19VMOrGreater = LangUtil.is19VMOrGreater(); } private List<ITestStep> testSteps = new ArrayList<ITestStep>(); @@ -89,6 +77,7 @@ public class AjcTest { if (vmLevel.equals("1.6")) canRun = is16VMOrGreater; if (vmLevel.equals("1.7")) canRun = is17VMOrGreater; if (vmLevel.equals("1.8")) canRun = is18VMOrGreater; + if (vmLevel.equals("1.9")) canRun = is19VMOrGreater; if (!canRun) { System.out.println("***SKIPPING TEST***" + getTitle()+ " needs " + getVmLevel() + ", currently running on " + System.getProperty("java.vm.version")); diff --git a/testing/newsrc/org/aspectj/testing/CompileSpec.java b/testing/newsrc/org/aspectj/testing/CompileSpec.java index 714158a11..22570e3d1 100644 --- a/testing/newsrc/org/aspectj/testing/CompileSpec.java +++ b/testing/newsrc/org/aspectj/testing/CompileSpec.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; +import org.aspectj.testing.util.TestUtil; import org.aspectj.tools.ajc.AjcTestCase; import org.aspectj.tools.ajc.CompilationResult; @@ -31,6 +32,7 @@ public class CompileSpec implements ITestStep { private boolean includeClassesDir; private String aspectpath; private String classpath; + private String modulepath; private String inpath; private String sourceroots; private String outjar; @@ -97,6 +99,14 @@ public class CompileSpec implements ITestStep { public void setClasspath(String classpath) { this.classpath = classpath.replace(',',File.pathSeparatorChar); } + + public String getModulepath() { + return this.modulepath; + } + + public void setModulepath(String modulepath) { + this.modulepath = modulepath.replace(',', File.pathSeparatorChar); + } /** * @return Returns the files. */ @@ -241,6 +251,11 @@ public class CompileSpec implements ITestStep { args.append(getClasspath()); args.append(" "); } + if (getModulepath() != null) { + args.append("-p "); + args.append(rewrite(getModulepath())); + args.append(" "); + } if (getXlintfile() != null) { args.append("-Xlintfile "); args.append(getXlintfile()); @@ -287,6 +302,11 @@ public class CompileSpec implements ITestStep { return ret; } + private String rewrite(String path) { + path = path.replace("$runtime", TestUtil.aspectjrtPath().toString()); + return path; + } + protected AjcTestCase.MessageSpec buildMessageSpec() { List<AjcTestCase.Message> infos = null; List<AjcTestCase.Message> warnings = new ArrayList<AjcTestCase.Message>(); diff --git a/testing/newsrc/org/aspectj/testing/FileSpec.java b/testing/newsrc/org/aspectj/testing/FileSpec.java index 448e5e34e..f9876928b 100644 --- a/testing/newsrc/org/aspectj/testing/FileSpec.java +++ b/testing/newsrc/org/aspectj/testing/FileSpec.java @@ -40,10 +40,25 @@ public class FileSpec implements ITestStep { public void execute(AjcTestCase inTestCase) { File sandbox = inTestCase.getSandboxDirectory(); if (toDelete != null) { - new File(sandbox, toDelete).delete(); + File targetForDeletion = new File(sandbox, toDelete); + if (targetForDeletion.isFile()) { + targetForDeletion.delete(); + } else { + recursiveDelete(targetForDeletion); + } } } + private void recursiveDelete(File toDelete) { + if (toDelete.isDirectory()) { + File[] files = toDelete.listFiles(); + for (File f: files) { + recursiveDelete(f); + } + } + toDelete.delete(); + } + public void setBaseDir(String dir) { // this.dir = dir; } diff --git a/testing/newsrc/org/aspectj/testing/OutputLine.java b/testing/newsrc/org/aspectj/testing/OutputLine.java index d7350428a..fc6fe4ce9 100644 --- a/testing/newsrc/org/aspectj/testing/OutputLine.java +++ b/testing/newsrc/org/aspectj/testing/OutputLine.java @@ -12,25 +12,31 @@ package org.aspectj.testing; /** - * @author colyer - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Style - Code Templates + * @author Adrian Colyer + * @author Andy Clement */ public class OutputLine { + // Expected text private String text; + + // Comma separated list of vm versions on which this is expected + private String vm; - /** - * @return Returns the text. - */ public String getText() { return text; } - /** - * @param text The text to set. - */ + public void setText(String text) { this.text = text; } + + public String getVm() { + return vm; + } + + public void setVm(String vm) { + this.vm = vm; + } + } diff --git a/testing/newsrc/org/aspectj/testing/OutputSpec.java b/testing/newsrc/org/aspectj/testing/OutputSpec.java index ffb3362f3..9eab46098 100644 --- a/testing/newsrc/org/aspectj/testing/OutputSpec.java +++ b/testing/newsrc/org/aspectj/testing/OutputSpec.java @@ -16,15 +16,38 @@ import java.util.ArrayList; import java.util.StringTokenizer; import org.aspectj.tools.ajc.AjcTestCase; +import org.aspectj.util.LangUtil; public class OutputSpec { private List<String> expectedOutputLines = new ArrayList<String>(); public void addLine(OutputLine line) { - expectedOutputLines.add(line.getText()); + if (line.getVm() == null || matchesThisVm(line.getVm())) { + expectedOutputLines.add(line.getText()); + } } + /** + * For a test output line that has specified a vm version, check if it matches the vm we are running on. + * vm might be "1.2,1.3,1.4,1.5" or simply "9" or it may be a version with a '+' suffix indicating that + * level or later, e.g. "9+" should be ok on Java 10 + * @return true if the current vm version matches the spec + */ + private boolean matchesThisVm(String vm) { + // vm might be 1.2, 1.3, 1.4, 1.5 or 1.9 possibly with a '+' in there + // For now assume + is attached to there only being one version, like "9+" + if (vm.contains(LangUtil.getVmVersionString())) { + return true; + } + if (vm.endsWith("+")) { + double vmVersion = LangUtil.getVmVersion(); + double vmSpecified = Double.parseDouble(vm.substring(0,vm.length()-1)); + return vmVersion >= vmSpecified; + } + return false; + } + public void matchAgainst(String output) { matchAgainst(output, "yes"); } diff --git a/testing/newsrc/org/aspectj/testing/RunSpec.java b/testing/newsrc/org/aspectj/testing/RunSpec.java index 2309788bc..9d21b599c 100644 --- a/testing/newsrc/org/aspectj/testing/RunSpec.java +++ b/testing/newsrc/org/aspectj/testing/RunSpec.java @@ -21,6 +21,9 @@ import java.util.StringTokenizer; import org.aspectj.tools.ajc.AjcTestCase; import org.aspectj.util.FileUtil; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.Utils; +import org.aspectj.weaver.bcel.Utility; /** * @author Adrian Colyer @@ -29,9 +32,11 @@ public class RunSpec implements ITestStep { private List<ExpectedMessageSpec> expected = new ArrayList<ExpectedMessageSpec>(); private String classToRun; + private String moduleToRun; // alternative to classToRun on JDK9+ private String baseDir; private String options; private String cpath; + private String mpath; private String orderedStderr; private AjcTest myTest; private OutputSpec stdErrSpec; @@ -59,9 +64,9 @@ public class RunSpec implements ITestStep { try { setSystemProperty("test.base.dir", inTestCase.getSandboxDirectory().getAbsolutePath()); - AjcTestCase.RunResult rr = inTestCase.run(getClassToRun(), args, vmargs, getClasspath(), useLtw, "true".equalsIgnoreCase(usefullltw)); + AjcTestCase.RunResult rr = inTestCase.run(getClassToRun(), getModuleToRun(), args, vmargs, getClasspath(), getModulepath(), useLtw, "true".equalsIgnoreCase(usefullltw)); - if (stdErrSpec != null) { + if (stdErrSpec != null) { stdErrSpec.matchAgainst(rr.getStdErr(), orderedStderr); } if (stdOutSpec != null) { @@ -129,6 +134,16 @@ public class RunSpec implements ITestStep { return this.cpath.replace('/', File.separatorChar).replace(',', File.pathSeparatorChar); } + public String getModulepath() { + if (mpath == null) + return null; + return this.mpath.replace('/', File.separatorChar).replace(',', File.pathSeparatorChar); + } + + public void setModulepath(String mpath) { + this.mpath = mpath; + } + public void setClasspath(String cpath) { this.cpath = cpath; } @@ -144,20 +159,22 @@ public class RunSpec implements ITestStep { public void setOrderedStderr(String orderedStderr) { this.orderedStderr = orderedStderr; } - - /** - * @return Returns the classToRun. - */ + public String getClassToRun() { return classToRun; } - - /** - * @param classToRun The classToRun to set. - */ + public void setClassToRun(String classToRun) { this.classToRun = classToRun; } + + public void setModuleToRun(String moduleToRun) { + this.moduleToRun = moduleToRun; + } + + public String getModuleToRun() { + return this.moduleToRun; + } public String getLtwFile() { return ltwFile; diff --git a/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java b/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java index 18b9233dc..fa47c98c4 100644 --- a/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java +++ b/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java @@ -202,6 +202,7 @@ public abstract class XMLBasedAjcTestCase extends AjcTestCase { digester.addSetNext("suite/ajc-test/file", "addTestStep", "org.aspectj.testing.ITestStep"); digester.addObjectCreate("suite/ajc-test/run", RunSpec.class); digester.addSetProperties("suite/ajc-test/run", "class", "classToRun"); + digester.addSetProperties("suite/ajc-test/run", "module", "moduleToRun"); digester.addSetProperties("suite/ajc-test/run", "ltw", "ltwFile"); digester.addSetProperties("suite/ajc-test/run", "xlintfile", "xlintFile"); digester.addSetProperties("suite/ajc-test/run/stderr", "ordered", "orderedStderr"); diff --git a/testing/src/org/aspectj/testing/ajde/CompileCommand.java b/testing/src/org/aspectj/testing/ajde/CompileCommand.java index 2fd748ff2..86c5fbaf7 100644 --- a/testing/src/org/aspectj/testing/ajde/CompileCommand.java +++ b/testing/src/org/aspectj/testing/ajde/CompileCommand.java @@ -378,6 +378,18 @@ class MyCompilerConfig implements ICompilerConfiguration { return null; } + @Override + public String getModulepath() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getModuleSourcepath() { + // TODO Auto-generated method stub + return null; + } + } class MyOutputLocationManager implements IOutputLocationManager { @@ -417,7 +429,6 @@ class MyOutputLocationManager implements IOutputLocationManager { } public int discoverChangesSince(File dir, long buildtime) { - // TODO Auto-generated method stub return 0; } diff --git a/testing/src/org/aspectj/testing/harness/bridge/JavaRun.java b/testing/src/org/aspectj/testing/harness/bridge/JavaRun.java index 8efad22de..aade35f48 100644 --- a/testing/src/org/aspectj/testing/harness/bridge/JavaRun.java +++ b/testing/src/org/aspectj/testing/harness/bridge/JavaRun.java @@ -610,6 +610,9 @@ public class JavaRun implements IAjcRun { /** fully-qualified name of the class to run */ protected String className; + /** Alternative to classname for specifying what to run modulename/type */ + protected String module; + /** minimum required version of Java, if any */ protected String javaVersion; @@ -669,6 +672,10 @@ public class JavaRun implements IAjcRun { this.className = className; } + public void setModule(String module) { + this.module = module; + } + public void setLTW(String ltw) { useLTW = TestUtil.parseBoolean(ltw); } diff --git a/testing/src/org/aspectj/testing/xml/AjcSpecXmlReader.java b/testing/src/org/aspectj/testing/xml/AjcSpecXmlReader.java index 1c295d795..370a9ac91 100644 --- a/testing/src/org/aspectj/testing/xml/AjcSpecXmlReader.java +++ b/testing/src/org/aspectj/testing/xml/AjcSpecXmlReader.java @@ -251,8 +251,8 @@ public class AjcSpecXmlReader { digester.addSetProperties(compileX + "/file"); digester.addSetProperties(inccompileX, "classes", "paths"); digester.addSetProperties(runX, - new String[] { "class", "vm", "skipTester", "fork", "vmargs", "aspectpath"}, - new String[] { "className", "javaVersion", "skipTester", "fork", "vmArgs", "aspectpath"}); + new String[] { "class", "vm", "skipTester", "fork", "vmargs", "aspectpath", "module"}, + new String[] { "className", "javaVersion", "skipTester", "fork", "vmArgs", "aspectpath", "module"}); digester.addSetProperties(dirchangesX); digester.addSetProperties(messageX); digester.addSetProperties(messageSrcLocX, "line", "lineAsString"); diff --git a/testing/testsrc/org/aspectj/testing/taskdefs/AjcTaskCompileCommandTest.java b/testing/testsrc/org/aspectj/testing/taskdefs/AjcTaskCompileCommandTest.java index 6ab5a386b..42a2063a4 100644 --- a/testing/testsrc/org/aspectj/testing/taskdefs/AjcTaskCompileCommandTest.java +++ b/testing/testsrc/org/aspectj/testing/taskdefs/AjcTaskCompileCommandTest.java @@ -44,7 +44,12 @@ public class AjcTaskCompileCommandTest extends TestCase { list.add("-d"); list.add(getClassesDir().getAbsolutePath()); list.add("-classpath"); - list.add(Globals.F_aspectjrt_jar.getAbsolutePath()); + StringBuilder classpath = new StringBuilder(); + classpath.append(Globals.F_aspectjrt_jar.getAbsolutePath()); + if (LangUtil.is19VMOrGreater()) { + classpath.append(File.pathSeparator).append(LangUtil.getJrtFsFilePath()); + } + list.add(classpath.toString()); } static boolean doWait(IMessageHolder holder, int seconds, int timeout) { diff --git a/tests/apt/test1/SimpleProcessor.java b/tests/apt/test1/SimpleProcessor.java index 29cb0a8ce..fb7e36673 100644 --- a/tests/apt/test1/SimpleProcessor.java +++ b/tests/apt/test1/SimpleProcessor.java @@ -239,7 +239,7 @@ public final class SimpleProcessor extends AbstractProcessor { bw.newLine(); } } catch (final Throwable e) { - + e.printStackTrace(System.err); // processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, e.getMessage()); } } diff --git a/tests/bugs1810/493554/example/aspect/FooAspect$ajcMightHaveAspect.class b/tests/bugs1810/493554/example/aspect/FooAspect$ajcMightHaveAspect.class Binary files differnew file mode 100644 index 000000000..8f9346bef --- /dev/null +++ b/tests/bugs1810/493554/example/aspect/FooAspect$ajcMightHaveAspect.class diff --git a/tests/bugs1810/493554/example/aspect/FooAspect.class b/tests/bugs1810/493554/example/aspect/FooAspect.class Binary files differnew file mode 100644 index 000000000..6c5f481fd --- /dev/null +++ b/tests/bugs1810/493554/example/aspect/FooAspect.class diff --git a/tests/bugs1810/493554/example/dep/Dep.class b/tests/bugs1810/493554/example/dep/Dep.class Binary files differnew file mode 100644 index 000000000..cda4a43e0 --- /dev/null +++ b/tests/bugs1810/493554/example/dep/Dep.class diff --git a/tests/bugs1810/493554/example/kusedep/Cmd.class b/tests/bugs1810/493554/example/kusedep/Cmd.class Binary files differnew file mode 100644 index 000000000..536d1120c --- /dev/null +++ b/tests/bugs1810/493554/example/kusedep/Cmd.class diff --git a/tests/bugs1810/generics/Code.java b/tests/bugs1810/generics/Code.java new file mode 100644 index 000000000..cc3672268 --- /dev/null +++ b/tests/bugs1810/generics/Code.java @@ -0,0 +1,9 @@ +class AbstractSuperClass<A,B> {} +interface InterfaceOne {} +interface InterfaceTwo<A> {} +class ID {} +abstract class AbstractTestClass<T> extends AbstractSuperClass<T,ID> implements InterfaceOne, InterfaceTwo<T> { +} +class TestType {} +class ConcreteClass extends AbstractTestClass<TestType> { +} diff --git a/tests/bugs1811/509235/parameterizedWithInner/Code.java b/tests/bugs1811/509235/parameterizedWithInner/Code.java deleted file mode 100644 index 182a01d88..000000000 --- a/tests/bugs1811/509235/parameterizedWithInner/Code.java +++ /dev/null @@ -1,20 +0,0 @@ -public class Code { - public static void main(String []argv) { - } -} - -class Outer<T> { - class Inner { - T t; - Inner(T t) { - this.t =t ; - } - } - - public Inner m() {return null;} - public Outer<String>.Inner m2() { - Outer<String> os = new Outer<String>(); - return os.new Inner("foo"); - } - public Outer<?>.Inner m3() {return null;} -} diff --git a/tests/bugs1813/generics/A.java b/tests/bugs1813/generics/A.java new file mode 100644 index 000000000..85ec82ea2 --- /dev/null +++ b/tests/bugs1813/generics/A.java @@ -0,0 +1,8 @@ +import java.util.List; + + +public interface A<T extends BaseT, I extends BaseI> { + + public T setInputs(List<I> inputs); + +}
\ No newline at end of file diff --git a/tests/bugs1813/generics/AlreadyImplementsA.java b/tests/bugs1813/generics/AlreadyImplementsA.java new file mode 100644 index 000000000..56f650d03 --- /dev/null +++ b/tests/bugs1813/generics/AlreadyImplementsA.java @@ -0,0 +1,15 @@ + +import java.util.List; + + +public class AlreadyImplementsA { + + + public ConcreteTImpl setInputs(List<ConcreteIImpl> inputs) { + return null; + } + + + + +}
\ No newline at end of file diff --git a/tests/bugs1813/generics/BaseI.java b/tests/bugs1813/generics/BaseI.java new file mode 100644 index 000000000..31f975853 --- /dev/null +++ b/tests/bugs1813/generics/BaseI.java @@ -0,0 +1,7 @@ + + +public interface BaseI { + + + +}
\ No newline at end of file diff --git a/tests/bugs1813/generics/BaseT.java b/tests/bugs1813/generics/BaseT.java new file mode 100644 index 000000000..72046e956 --- /dev/null +++ b/tests/bugs1813/generics/BaseT.java @@ -0,0 +1,4 @@ + +public interface BaseT { + +}
\ No newline at end of file diff --git a/tests/bugs1813/generics/BindInterfaceA.aj b/tests/bugs1813/generics/BindInterfaceA.aj new file mode 100644 index 000000000..2d3e56965 --- /dev/null +++ b/tests/bugs1813/generics/BindInterfaceA.aj @@ -0,0 +1,8 @@ + + +public aspect BindInterfaceA { + + declare parents: AlreadyImplementsA implements A<ConcreteTImpl,ConcreteIImpl>; + + +} diff --git a/tests/bugs1813/generics/ConcreteIImpl.java b/tests/bugs1813/generics/ConcreteIImpl.java new file mode 100644 index 000000000..3cbdac163 --- /dev/null +++ b/tests/bugs1813/generics/ConcreteIImpl.java @@ -0,0 +1,5 @@ + + +public class ConcreteIImpl implements BaseI { + +} diff --git a/tests/bugs1813/generics/ConcreteTImpl.java b/tests/bugs1813/generics/ConcreteTImpl.java new file mode 100644 index 000000000..aba55be3a --- /dev/null +++ b/tests/bugs1813/generics/ConcreteTImpl.java @@ -0,0 +1,6 @@ + + +public class ConcreteTImpl implements BaseT { + + +} diff --git a/tests/bugs1813/generics/Runner.java b/tests/bugs1813/generics/Runner.java new file mode 100644 index 000000000..6d4468b0f --- /dev/null +++ b/tests/bugs1813/generics/Runner.java @@ -0,0 +1,7 @@ +public class Runner { + public static void main(String[] argv) { + if (new AlreadyImplementsA() instanceof A) { + System.out.println("ok"); + } + } +} diff --git a/tests/bugs190/520135/FailsApectJ.java b/tests/bugs190/520135/FailsApectJ.java new file mode 100644 index 000000000..b7d67af4d --- /dev/null +++ b/tests/bugs190/520135/FailsApectJ.java @@ -0,0 +1,24 @@ +package com.afrozaar.aspectj.test; + +import java.util.function.Function; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class FailsApectJ { + static aspect X { + before(): within(FailsApectJ) && call(* *(..)) {} + } + + private <T> Function<String, Collection<String>> ASpectJFailWithWildCardAndVarArgeMethodReference() { + Function<T, ? extends Object> x = a -> a; // the wild card fails the compile + x.andThen(this::get); + return null; + } + + private <T> List<T> get(T... args) { + return Arrays.asList(args); + } + +} diff --git a/tests/bugs190/modules/aaa/com/foo1/C1.java b/tests/bugs190/modules/aaa/com/foo1/C1.java new file mode 100644 index 000000000..eb087840d --- /dev/null +++ b/tests/bugs190/modules/aaa/com/foo1/C1.java @@ -0,0 +1,3 @@ +package com.foo1; + +public class C1 {} diff --git a/tests/bugs190/modules/aaa/module-info.java b/tests/bugs190/modules/aaa/module-info.java new file mode 100644 index 000000000..b6bd69405 --- /dev/null +++ b/tests/bugs190/modules/aaa/module-info.java @@ -0,0 +1,3 @@ +module e.f.g { + exports com.foo1; +} diff --git a/tests/bugs190/modules/aspect1/Azpect1.java b/tests/bugs190/modules/aspect1/Azpect1.java new file mode 100644 index 000000000..6106916af --- /dev/null +++ b/tests/bugs190/modules/aspect1/Azpect1.java @@ -0,0 +1,5 @@ +public aspect Azpect1 { + before(): execution(* main(..)) { + System.out.println("Azpect1.before running"); + } +} diff --git a/tests/bugs190/modules/bbb/aaa/bbb/A.java b/tests/bugs190/modules/bbb/aaa/bbb/A.java new file mode 100644 index 000000000..09935dc54 --- /dev/null +++ b/tests/bugs190/modules/bbb/aaa/bbb/A.java @@ -0,0 +1,7 @@ +package aaa.bbb; + +public class A { + public static void main(String []argv) { + System.out.println("A running"); + } +} diff --git a/tests/bugs190/modules/bbb/module-info.java b/tests/bugs190/modules/bbb/module-info.java new file mode 100644 index 000000000..60e9fdc99 --- /dev/null +++ b/tests/bugs190/modules/bbb/module-info.java @@ -0,0 +1,3 @@ +module my.module { + exports aaa.bbb; +} diff --git a/tests/bugs190/modules/ccc/InvokeA.java b/tests/bugs190/modules/ccc/InvokeA.java new file mode 100644 index 000000000..5c07384e9 --- /dev/null +++ b/tests/bugs190/modules/ccc/InvokeA.java @@ -0,0 +1,6 @@ +import aaa.bbb.A; +public class InvokeA { + public static void main(String[] argv) { + A.main(argv); + } +} diff --git a/tests/bugs190/modules/ccc/aaa/bbb/A.java b/tests/bugs190/modules/ccc/aaa/bbb/A.java new file mode 100644 index 000000000..09935dc54 --- /dev/null +++ b/tests/bugs190/modules/ccc/aaa/bbb/A.java @@ -0,0 +1,7 @@ +package aaa.bbb; + +public class A { + public static void main(String []argv) { + System.out.println("A running"); + } +} diff --git a/tests/bugs190/modules/ccc/module-info.java b/tests/bugs190/modules/ccc/module-info.java new file mode 100644 index 000000000..60e9fdc99 --- /dev/null +++ b/tests/bugs190/modules/ccc/module-info.java @@ -0,0 +1,3 @@ +module my.module { + exports aaa.bbb; +} diff --git a/tests/bugs190/modules/cpl.sh b/tests/bugs190/modules/cpl.sh new file mode 100755 index 000000000..ca5f7b057 --- /dev/null +++ b/tests/bugs190/modules/cpl.sh @@ -0,0 +1,4 @@ +cd module1 +javac module-info.java Code.java -d . +jar -cvMf module-one.jar * +cd .. diff --git a/tests/bugs190/modules/ddd/InvokeA.java b/tests/bugs190/modules/ddd/InvokeA.java new file mode 100644 index 000000000..5c07384e9 --- /dev/null +++ b/tests/bugs190/modules/ddd/InvokeA.java @@ -0,0 +1,6 @@ +import aaa.bbb.A; +public class InvokeA { + public static void main(String[] argv) { + A.main(argv); + } +} diff --git a/tests/bugs190/modules/ddd/aaa/bbb/A.java b/tests/bugs190/modules/ddd/aaa/bbb/A.java new file mode 100644 index 000000000..09935dc54 --- /dev/null +++ b/tests/bugs190/modules/ddd/aaa/bbb/A.java @@ -0,0 +1,7 @@ +package aaa.bbb; + +public class A { + public static void main(String []argv) { + System.out.println("A running"); + } +} diff --git a/tests/bugs190/modules/ddd/module-info.java b/tests/bugs190/modules/ddd/module-info.java new file mode 100644 index 000000000..57dd04566 --- /dev/null +++ b/tests/bugs190/modules/ddd/module-info.java @@ -0,0 +1,2 @@ +module my.module { +} diff --git a/tests/bugs190/modules/eee/Azpect.java b/tests/bugs190/modules/eee/Azpect.java new file mode 100644 index 000000000..5dd4aa342 --- /dev/null +++ b/tests/bugs190/modules/eee/Azpect.java @@ -0,0 +1,7 @@ +package aspects; + +public aspect Azpect { + before(): execution(* main(..)) { + System.out.println("Azpect running"); + } +} diff --git a/tests/bugs190/modules/eee/aaa/bbb/A.java b/tests/bugs190/modules/eee/aaa/bbb/A.java new file mode 100644 index 000000000..09935dc54 --- /dev/null +++ b/tests/bugs190/modules/eee/aaa/bbb/A.java @@ -0,0 +1,7 @@ +package aaa.bbb; + +public class A { + public static void main(String []argv) { + System.out.println("A running"); + } +} diff --git a/tests/bugs190/modules/eee/module-info.java b/tests/bugs190/modules/eee/module-info.java new file mode 100644 index 000000000..60e9fdc99 --- /dev/null +++ b/tests/bugs190/modules/eee/module-info.java @@ -0,0 +1,3 @@ +module my.module { + exports aaa.bbb; +} diff --git a/tests/bugs190/modules/fff/aspects.jar b/tests/bugs190/modules/fff/aspects.jar Binary files differnew file mode 100644 index 000000000..246cab5f5 --- /dev/null +++ b/tests/bugs190/modules/fff/aspects.jar diff --git a/tests/bugs190/modules/fff/demo.jar b/tests/bugs190/modules/fff/demo.jar Binary files differnew file mode 100644 index 000000000..f00e0337d --- /dev/null +++ b/tests/bugs190/modules/fff/demo.jar diff --git a/tests/bugs190/modules/fff/extra/AnotherAzpect.java b/tests/bugs190/modules/fff/extra/AnotherAzpect.java new file mode 100644 index 000000000..16b8c16d6 --- /dev/null +++ b/tests/bugs190/modules/fff/extra/AnotherAzpect.java @@ -0,0 +1,7 @@ +package extra; + +public aspect AnotherAzpect { + before(): execution(* *(..)) && !within(*Azpect) { + System.out.println("AnotherAzpect running"); + } +} diff --git a/tests/bugs190/modules/fff/module-info.java b/tests/bugs190/modules/fff/module-info.java new file mode 100644 index 000000000..6f03752e8 --- /dev/null +++ b/tests/bugs190/modules/fff/module-info.java @@ -0,0 +1,4 @@ +module demo { + exports pkg; + requires org.aspectj.runtime; +} diff --git a/tests/bugs190/modules/fff/newdemo.jar b/tests/bugs190/modules/fff/newdemo.jar Binary files differnew file mode 100644 index 000000000..c32ca378a --- /dev/null +++ b/tests/bugs190/modules/fff/newdemo.jar diff --git a/tests/bugs190/modules/fff/otherpkg/Azpect.java b/tests/bugs190/modules/fff/otherpkg/Azpect.java new file mode 100644 index 000000000..af53fdf49 --- /dev/null +++ b/tests/bugs190/modules/fff/otherpkg/Azpect.java @@ -0,0 +1,7 @@ +package otherpkg; + +public aspect Azpect { + before(): execution(* *(..)) && !within(Azpect) { + System.out.println("Azpect running"); + } +} diff --git a/tests/bugs190/modules/fff/pkg/Demo.java b/tests/bugs190/modules/fff/pkg/Demo.java new file mode 100644 index 000000000..694595053 --- /dev/null +++ b/tests/bugs190/modules/fff/pkg/Demo.java @@ -0,0 +1,6 @@ +package pkg; +public class Demo { + public static void main(String[] argv) { + System.out.println("Demo running"); + } +} diff --git a/tests/bugs190/modules/module1/Code.java b/tests/bugs190/modules/module1/Code.java new file mode 100644 index 000000000..5cc9632d1 --- /dev/null +++ b/tests/bugs190/modules/module1/Code.java @@ -0,0 +1,6 @@ +package a.b.c; +public class Code { + public static void main(String []argv) { + System.out.println("Code.main running"); + } +} diff --git a/tests/bugs190/modules/module1/module-info.java b/tests/bugs190/modules/module1/module-info.java new file mode 100644 index 000000000..7edf5da1f --- /dev/null +++ b/tests/bugs190/modules/module1/module-info.java @@ -0,0 +1,2 @@ +module one { +} diff --git a/tests/bugs190/modules/module1/module-one.jar b/tests/bugs190/modules/module1/module-one.jar Binary files differnew file mode 100644 index 000000000..907678e9c --- /dev/null +++ b/tests/bugs190/modules/module1/module-one.jar diff --git a/tests/bugs190/modules/play/m b/tests/bugs190/modules/play/m new file mode 100644 index 000000000..54520da0a --- /dev/null +++ b/tests/bugs190/modules/play/m @@ -0,0 +1,11 @@ +module M.N { + requires A.B; + requires public C.D; + + exports P.Q; + exports R.S to T1.U1, T2.U2; + + uses V.W; + provides X.Y with Z1.Z2; + provides X.Y with Z3.Z4; +} diff --git a/tests/bugs190/modules/play/src/a/module-info.java b/tests/bugs190/modules/play/src/a/module-info.java new file mode 100644 index 000000000..5de28f635 --- /dev/null +++ b/tests/bugs190/modules/play/src/a/module-info.java @@ -0,0 +1,2 @@ +module a { +} diff --git a/tests/bugs190/modules/play/src/b/module-info.java b/tests/bugs190/modules/play/src/b/module-info.java new file mode 100644 index 000000000..d7a65f08e --- /dev/null +++ b/tests/bugs190/modules/play/src/b/module-info.java @@ -0,0 +1,2 @@ +module b { +} diff --git a/tests/bugs190/various/Code.java b/tests/bugs190/various/Code.java new file mode 100644 index 000000000..8285ca3d8 --- /dev/null +++ b/tests/bugs190/various/Code.java @@ -0,0 +1,11 @@ +public class Code { + public static void main(String []argv) { + System.out.println("running"); + } +} + +aspect X{ + before(): call(* println(..)) && !within(X) { + System.out.println(thisJoinPoint); + } +} diff --git a/tests/java5/annotations/itds/AtItd3.aj b/tests/java5/annotations/itds/AtItd3.aj index c3412cf56..8af19ed71 100644 --- a/tests/java5/annotations/itds/AtItd3.aj +++ b/tests/java5/annotations/itds/AtItd3.aj @@ -24,6 +24,7 @@ public class AtItd3 { if (!aa.toString().equals("@Ann(id=goodbye, anInt=4)")) // < Java8 order if (!aa.toString().equals("@Ann(anInt=4, id=goodbye)")) // Java8 order + if (!aa.toString().equals("@Ann(anInt=4, id=\"goodbye\")")) // Java9 quotes strings throw new RuntimeException("Incorrect output, expected:"+ "@Ann(id=goodbye, anInt=4) but got "+aa.toString()); diff --git a/tests/java5/ataspectj/ajc-ant.xml b/tests/java5/ataspectj/ajc-ant.xml index 0730d7b85..a9b215bf3 100644 --- a/tests/java5/ataspectj/ajc-ant.xml +++ b/tests/java5/ataspectj/ajc-ant.xml @@ -10,7 +10,7 @@ <target name="compile:javac"> <!-- compile only javac compilable stuff, exclude the one that needs other dependencies --> - <javac source="1.5" target="1.5" destdir="${aj.sandbox}" classpathref="aj.path" + <javac source="1.6" target="1.6" 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 source="1.5" target="1.5" destdir="${aj.sandbox}" classpathref="aj.path" + <javac source="1.6" target="1.6" 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 source="1.5" target="1.5" destdir="${aj.sandbox}" + <javac source="1.6" target="1.6" 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 source="1.5" target="1.5" destdir="${aj.sandbox}" + <javac source="1.6" target="1.6" destdir="${aj.sandbox}" srcdir="${basedir}" includes="ataspectj/DeclareParentsImplementsReweavableTestAspect.java" debug="true"> diff --git a/tests/src/org/aspectj/systemtest/AllTests19.java b/tests/src/org/aspectj/systemtest/AllTests19.java new file mode 100644 index 000000000..4835a6154 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/AllTests19.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013, 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial API and implementation + *******************************************************************************/ +package org.aspectj.systemtest; + +import org.aspectj.systemtest.ajc190.AllTestsAspectJ190; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class AllTests19 { + + public static Test suite() { + TestSuite suite = new TestSuite("AspectJ System Test Suite - 1.9"); + // $JUnit-BEGIN$ + suite.addTest(AllTestsAspectJ190.suite()); + suite.addTest(AllTests18.suite()); + // $JUnit-END$ + return suite; + } +} diff --git a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java index ff08047d1..907e3d7a5 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java +++ b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java @@ -781,8 +781,13 @@ public class GenericsTests extends XMLBasedAjcTestCase { public void testAfterReturningParameterizedAndWildcards() { runTest("after returning with parameterized type and wildcards"); } - + public void testAfterReturningWithWildcardVar() { + if (LangUtil.is19VMOrGreater()) { + // See ReferenceType.isCoerceableFrom comments + return; + } + // Something to investigate here. The implementation of isCoerceable runTest("after returning with generic wildcard"); } diff --git a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml index b368e77e0..d0da94ec9 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml @@ -2808,7 +2808,8 @@ <line text="@target(Classified) at call(Class java.lang.Object.getClass())"/> <line text="1 @Foo()"/> <line text="1 @Foo()"/> - <line text="1 @Classified(classification=TOP-SECRET)"/> + <line text="1 @Classified(classification=TOP-SECRET)" vm="1.5,1.6,1.7,1.8"/> + <line text="1 @Classified(classification="TOP-SECRET")" vm="9+"/> <line text="This information is TOP-SECRET"/> <line text="Entering critical join point with priority 3"/> <line text="Entering critical join point with reflectively obtained priority 3"/> @@ -3811,29 +3812,47 @@ <run class="GenericAspectRuntimePointcuts"> <stdout> <line text="target-ok an X execution(void X.foo())"/> - <line text="@this-ok @MyAnnotation(value=my-value) execution(void X.foo())"/> - <line text="@target-ok @MyAnnotation(value=my-value) execution(void X.foo())"/> - <line text="@within-ok @MyAnnotation(value=my-value) execution(void X.foo())"/> + <line text="@this-ok @MyAnnotation(value=my-value) execution(void X.foo())" vm="1.5,1.6,1.7,1.8"/> + <line text="@this-ok @MyAnnotation(value="my-value") execution(void X.foo())" vm="9+"/> + <line text="@target-ok @MyAnnotation(value=my-value) execution(void X.foo())" vm="1.5,1.6,1.7,1.8"/> + <line text="@target-ok @MyAnnotation(value="my-value") execution(void X.foo())" vm="9+"/> + <line text="@within-ok @MyAnnotation(value=my-value) execution(void X.foo())" vm="1.5,1.6,1.7,1.8"/> + <line text="@within-ok @MyAnnotation(value="my-value") execution(void X.foo())" vm="9+"/> <line text="cflow-ok an X a Y set(Y X.y)"/> - <line text="@annotation-ok-sub @MyAnnotation(value=bar) execution(void X.bar())"/> - <line text="@annotation-ok @MyAnnotation(value=bar) execution(void X.bar())"/> + <line text="@annotation-ok-sub @MyAnnotation(value=bar) execution(void X.bar())" vm="1.5,1.6,1.7,1.8"/> + <line text="@annotation-ok-sub @MyAnnotation(value="bar") execution(void X.bar())" vm="9+"/> + <line text="@annotation-ok @MyAnnotation(value=bar) execution(void X.bar())" vm="1.5,1.6,1.7,1.8"/> + <line text="@annotation-ok @MyAnnotation(value="bar") execution(void X.bar())" vm="9+"/> <line text="target-ok an X execution(void X.bar())"/> - <line text="@this-ok @MyAnnotation(value=my-value) execution(void X.bar())"/> - <line text="@target-ok @MyAnnotation(value=my-value) execution(void X.bar())"/> - <line text="@within-ok @MyAnnotation(value=my-value) execution(void X.bar())"/> - <line text="@args-ok @MyAnnotation(value=my-value) execution(void Y.foo(X))"/> + <line text="@this-ok @MyAnnotation(value=my-value) execution(void X.bar())" vm="1.5,1.6,1.7,1.8"/> + <line text="@this-ok @MyAnnotation(value="my-value") execution(void X.bar())" vm="9+"/> + <line text="@target-ok @MyAnnotation(value=my-value) execution(void X.bar())" vm="1.5,1.6,1.7,1.8"/> + <line text="@target-ok @MyAnnotation(value="my-value") execution(void X.bar())" vm="9+"/> + <line text="@within-ok @MyAnnotation(value=my-value) execution(void X.bar())" vm="1.5,1.6,1.7,1.8"/> + <line text="@within-ok @MyAnnotation(value="my-value") execution(void X.bar())" vm="9+"/> + <line text="@args-ok @MyAnnotation(value=my-value) execution(void Y.foo(X))" vm="1.5,1.6,1.7,1.8"/> + <line text="@args-ok @MyAnnotation(value="my-value") execution(void Y.foo(X))" vm="9+"/> <line text="args-ok an X execution(void Y.foo(X))"/> <line text="this-ok a Y execution(void Y.foo(X))"/> - <line text="@this-ok @MyAnnotation(value=on Y) execution(void Y.foo(X))"/> - <line text="@target-ok @MyAnnotation(value=on Y) execution(void Y.foo(X))"/> - <line text="@within-ok @MyAnnotation(value=on Y) execution(void Y.foo(X))"/> - <line text="@annotation-ok-sub @MyAnnotation(value=my-value) execution(X Y.bar())"/> - <line text="@annotation-ok @MyAnnotation(value=my-value) execution(X Y.bar())"/> + <line text="@this-ok @MyAnnotation(value=on Y) execution(void Y.foo(X))" vm="1.5,1.6,1.7,1.8"/> + <line text="@this-ok @MyAnnotation(value="on Y") execution(void Y.foo(X))" vm="9+"/> + <line text="@target-ok @MyAnnotation(value=on Y) execution(void Y.foo(X))" vm="1.5,1.6,1.7,1.8"/> + <line text="@target-ok @MyAnnotation(value="on Y") execution(void Y.foo(X))" vm="9+"/> + <line text="@within-ok @MyAnnotation(value=on Y) execution(void Y.foo(X))" vm="1.5,1.6,1.7,1.8"/> + <line text="@within-ok @MyAnnotation(value="on Y") execution(void Y.foo(X))" vm="9+"/> + <line text="@annotation-ok-sub @MyAnnotation(value=my-value) execution(X Y.bar())" vm="1.5,1.6,1.7,1.8"/> + <line text="@annotation-ok-sub @MyAnnotation(value="my-value") execution(X Y.bar())" vm="9+"/> + <line text="@annotation-ok @MyAnnotation(value=my-value) execution(X Y.bar())" vm="1.5,1.6,1.7,1.8"/> + <line text="@annotation-ok @MyAnnotation(value="my-value") execution(X Y.bar())" vm="9+"/> <line text="this-ok a Y execution(X Y.bar())"/> - <line text="@this-ok @MyAnnotation(value=on Y) execution(X Y.bar())"/> - <line text="@target-ok @MyAnnotation(value=on Y) execution(X Y.bar())"/> - <line text="@within-ok @MyAnnotation(value=on Y) execution(X Y.bar())"/> - <line text="@withincode-ok @MyAnnotation(value=my-value) get(X Y.x)"/> + <line text="@this-ok @MyAnnotation(value=on Y) execution(X Y.bar())" vm="1.5,1.6,1.7,1.8"/> + <line text="@this-ok @MyAnnotation(value="on Y") execution(X Y.bar())" vm="9+"/> + <line text="@target-ok @MyAnnotation(value=on Y) execution(X Y.bar())" vm="1.5,1.6,1.7,1.8"/> + <line text="@target-ok @MyAnnotation(value="on Y") execution(X Y.bar())" vm="9+"/> + <line text="@within-ok @MyAnnotation(value=on Y) execution(X Y.bar())" vm="1.5,1.6,1.7,1.8"/> + <line text="@within-ok @MyAnnotation(value="on Y") execution(X Y.bar())" vm="9+"/> + <line text="@withincode-ok @MyAnnotation(value=my-value) get(X Y.x)" vm="1.5,1.6,1.7,1.8"/> + <line text="@withincode-ok @MyAnnotation(value="my-value") get(X Y.x)" vm="9+"/> </stdout> </run> </ajc-test> @@ -4545,8 +4564,8 @@ </ajc-test> <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - M"> <compile files="GenericAspectM.aj" options="-1.5"> - <message kind="error" line="23" text="The method m0(Integer) in the type GenericAspect.SimpleI<Integer> is not applicable for the arguments (String)"/> - <message kind="error" line="24" text="The method m1(List<Integer>) in the type GenericAspect.SimpleI<Integer> is not applicable for the arguments (List<String>)"/> + <message kind="error" line="23" text="The method m0(Integer) in the type GenericAspect.SimpleI<Integer> is not applicable for the arguments (String)"/> + <message kind="error" line="24" text="The method m1(List<Integer>) in the type GenericAspect.SimpleI<Integer> is not applicable for the arguments (List<String>)"/> <message kind="error" line="25" text="Type mismatch: cannot convert from String to Integer"/> <message kind="error" line="26" text="Type mismatch: cannot convert from List<String> to List<Integer>"/> </compile> diff --git a/tests/src/org/aspectj/systemtest/ajc152/Ajc152Tests.java b/tests/src/org/aspectj/systemtest/ajc152/Ajc152Tests.java index d0ced6179..eef463214 100644 --- a/tests/src/org/aspectj/systemtest/ajc152/Ajc152Tests.java +++ b/tests/src/org/aspectj/systemtest/ajc152/Ajc152Tests.java @@ -367,7 +367,7 @@ public class Ajc152Tests extends org.aspectj.testing.XMLBasedAjcTestCase { IHierarchy top = AsmManager.lastActiveStructureModel.getHierarchy(); IProgramElement ipe = top.findElementForLabel(top.getRoot(), IProgramElement.Kind.METHOD, ipeLabel); assertNotNull("Couldn't find '" + ipeLabel + "' element in the tree", ipe); - List l = ipe.getParameterSignatures(); + List<char[]> l = ipe.getParameterSignatures(); boolean eq = CharOperation.equals(((char[]) l.get(0)), expectedParm.toCharArray()); assertTrue("expected parameter to be '" + expectedParm + "' but found '" + new String(((char[]) l.get(0))) + "'", eq); } diff --git a/tests/src/org/aspectj/systemtest/ajc154/Ajc154Tests.java b/tests/src/org/aspectj/systemtest/ajc154/Ajc154Tests.java index 7a025d796..ebba76303 100644 --- a/tests/src/org/aspectj/systemtest/ajc154/Ajc154Tests.java +++ b/tests/src/org/aspectj/systemtest/ajc154/Ajc154Tests.java @@ -275,7 +275,7 @@ public class Ajc154Tests extends org.aspectj.testing.XMLBasedAjcTestCase { // Should be 'rounded down' when transforming it into a MethodGen, new position will be '2' // This next line will go BANG with an NPE if we don't correctly round the start pc down to 2 - MethodGen toTransform = new MethodGen(oneWeWant, "A", cp, true); + new MethodGen(oneWeWant, "A", cp, true); } public void testGenericAspectGenericPointcut_pr174449() { diff --git a/tests/src/org/aspectj/systemtest/ajc154/ajc154.xml b/tests/src/org/aspectj/systemtest/ajc154/ajc154.xml index 6e897fdbd..9cb0eae87 100644 --- a/tests/src/org/aspectj/systemtest/ajc154/ajc154.xml +++ b/tests/src/org/aspectj/systemtest/ajc154/ajc154.xml @@ -27,7 +27,8 @@ </compile> <run class="c.d.DistantResource"> <stdout> - <line text="Annotation is @a.b.SimpleAnnotation(classname=oranges)"/> + <line text="Annotation is @a.b.SimpleAnnotation(classname=oranges)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="Annotation is @a.b.SimpleAnnotation(classname="oranges")" vm="9+"/> </stdout> </run> </ajc-test> @@ -39,7 +40,8 @@ </compile> <run class="c.d.DistantResource"> <stdout> - <line text="Annotation is @a.b.SimpleAnnotation(classname=oranges)"/> + <line text="Annotation is @a.b.SimpleAnnotation(classname=oranges)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="Annotation is @a.b.SimpleAnnotation(classname="oranges")" vm="9+"/> </stdout> </run> </ajc-test> @@ -51,7 +53,8 @@ </compile> <run class="c.d.DistantResource"> <stdout> - <line text="Annotation is @e.f.SimpleAnnotation2(classname=oranges)"/> + <line text="Annotation is @e.f.SimpleAnnotation2(classname=oranges)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="Annotation is @e.f.SimpleAnnotation2(classname="oranges")" vm="9+"/> </stdout> </run> </ajc-test> @@ -63,7 +66,8 @@ </compile> <run class="c.d.DistantResource"> <stdout> - <line text="Annotation is @e.f.SimpleAnnotation2(classname=oranges)"/> + <line text="Annotation is @e.f.SimpleAnnotation2(classname=oranges)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="Annotation is @e.f.SimpleAnnotation2(classname="oranges")" vm="9+"/> </stdout> </run> </ajc-test> @@ -76,7 +80,8 @@ </compile> <run class="c.d.DistantResource"> <stdout> - <line text="Annotation is @e.f.SimpleAnnotation2(classname=oranges)"/> + <line text="Annotation is @e.f.SimpleAnnotation2(classname=oranges)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="Annotation is @e.f.SimpleAnnotation2(classname="oranges")" vm="9+"/> </stdout> </run> </ajc-test> @@ -90,7 +95,8 @@ </compile> <run class="c.d.DistantResource"> <stdout> - <line text="Annotation is @e.f.SimpleAnnotation2(classname=oranges)"/> + <line text="Annotation is @e.f.SimpleAnnotation2(classname=oranges)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="Annotation is @e.f.SimpleAnnotation2(classname="oranges")" vm="9+"/> </stdout> </run> </ajc-test> diff --git a/tests/src/org/aspectj/systemtest/ajc1611/newfeatures-tests.xml b/tests/src/org/aspectj/systemtest/ajc1611/newfeatures-tests.xml index 7ba5316b5..914042633 100644 --- a/tests/src/org/aspectj/systemtest/ajc1611/newfeatures-tests.xml +++ b/tests/src/org/aspectj/systemtest/ajc1611/newfeatures-tests.xml @@ -109,7 +109,8 @@ <run class="WithValues"> <stdout> <line text="i does not have Anno"/> - <line text="j has Banno:@Banno(hoo=abc)"/> + <line text="j has Banno:@Banno(hoo=abc)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="j has Banno:@Banno(hoo="abc")" vm="9+"/> <line text="j does not have Anno"/> </stdout></run> </ajc-test> diff --git a/tests/src/org/aspectj/systemtest/ajc1612/ajc1612.xml b/tests/src/org/aspectj/systemtest/ajc1612/ajc1612.xml index 11746e122..38f46c7d6 100644 --- a/tests/src/org/aspectj/systemtest/ajc1612/ajc1612.xml +++ b/tests/src/org/aspectj/systemtest/ajc1612/ajc1612.xml @@ -257,8 +257,10 @@ <compile files="AnnoBinding2.java" options="-1.5"/> <run class="AnnoBinding2"> <stdout> -<line text="get(int AnnoBinding2.field1) @Marker(message=foo)"/> -<line text="get(int AnnoBinding2.field2) @Marker(message=bar)"/> +<line text="get(int AnnoBinding2.field1) @Marker(message=foo)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> +<line text="get(int AnnoBinding2.field1) @Marker(message="foo")" vm="9+"/> +<line text="get(int AnnoBinding2.field2) @Marker(message=bar)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> +<line text="get(int AnnoBinding2.field2) @Marker(message="bar")" vm="9+"/> <line text="2 ajc$anno$NNN fields"/> </stdout> </run> diff --git a/tests/src/org/aspectj/systemtest/ajc169/intertype.xml b/tests/src/org/aspectj/systemtest/ajc169/intertype.xml index 063bee514..75846b05c 100644 --- a/tests/src/org/aspectj/systemtest/ajc169/intertype.xml +++ b/tests/src/org/aspectj/systemtest/ajc169/intertype.xml @@ -70,7 +70,8 @@ <run class="a.b.c.Runner"> <stdout> <line text="wibble"/> - <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)"/> + <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@a.b.c.RelatedType(value=a.b.c.Vote$_$choice.class)" vm="9+"/> </stdout> </run> </ajc-test> @@ -80,7 +81,8 @@ <run class="a.b.c.Runner"> <stdout> <line text="wibble"/> - <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)"/> + <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@a.b.c.RelatedType(value=a.b.c.Vote$_$choice.class)" vm="9+"/> </stdout> </run> </ajc-test> @@ -90,7 +92,8 @@ <run class="a.b.c.Runner"> <stdout> <line text="wibble"/> - <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)"/> + <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@a.b.c.RelatedType(value=a.b.c.Vote$_$choice.class)" vm="9+"/> </stdout> </run> </ajc-test> @@ -100,7 +103,8 @@ <run class="a.b.c.Runner"> <stdout> <line text="wibble"/> - <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)"/> + <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@a.b.c.RelatedType(value=a.b.c.Vote$_$choice.class)" vm="9+"/> </stdout> </run> </ajc-test> @@ -110,7 +114,8 @@ <run class="a.b.c.Runner"> <stdout> <line text="wibble"/> - <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)"/> + <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@a.b.c.RelatedType(value=a.b.c.Vote$_$choice.class)" vm="9+"/> </stdout> </run> </ajc-test> @@ -120,7 +125,8 @@ <run class="a.b.c.Runner"> <stdout> <line text="wibble"/> - <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)"/> + <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_$choice)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@a.b.c.RelatedType(value=a.b.c.Vote$_$choice.class)" vm="9+"/> </stdout> </run> </ajc-test> @@ -130,7 +136,8 @@ <run class="a.b.c.Runner"> <stdout> <line text="wibble"/> - <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_)"/> + <line text="@a.b.c.RelatedType(value=class a.b.c.Vote$_)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@a.b.c.RelatedType(value=a.b.c.Vote$_.class)" vm="9+"/> </stdout> </run> </ajc-test> diff --git a/tests/src/org/aspectj/systemtest/ajc170/ajc170.xml b/tests/src/org/aspectj/systemtest/ajc170/ajc170.xml index 37963fc15..e379d6cab 100644 --- a/tests/src/org/aspectj/systemtest/ajc170/ajc170.xml +++ b/tests/src/org/aspectj/systemtest/ajc170/ajc170.xml @@ -182,12 +182,15 @@ <line text="Annotations on field1? true"/> <line text="Annotation count is 4"/> <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)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@AnnoClass(value=java.lang.Integer.class, ccc=java.lang.String.class)" vm="9+"/> <line text="@AnnoLong(value=999, jjj=111)"/> - <line text="@AnnoString(value=set from xml, sss=xyz)"/> + <line text="@AnnoString(value=set from xml, sss=xyz)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@AnnoString(value="set from xml", sss="xyz")" vm="9+"/> <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)"/> + <line text="@AnnoClass(value=class java.lang.String, ccc=class java.lang.String)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@AnnoClass(value=java.lang.String.class, ccc=java.lang.String.class)" vm="9+"/> </stdout> </run> </ajc-test> @@ -198,9 +201,11 @@ <stdout> <line text="Annotations on field1? true"/> <line text="Annotation count is 4"/> - <line text="@AnnoChar(value=z, ccc=a)"/> + <line text="@AnnoChar(value=z, ccc=a)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@AnnoChar(value='z', ccc='a')" vm="9+"/> <line text="@AnnoDouble(value=99.0, ddd=3.0)"/> - <line text="@AnnoFloat(value=6.0, fff=4.0)"/> + <line text="@AnnoFloat(value=6.0, fff=4.0)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@AnnoFloat(value=6.0f, fff=4.0f)" vm="9+"/> <line text="@AnnoShort(value=8, sss=3)"/> <line text="Annotations on field2? true"/> <line text="Annotation count is 2"/> @@ -216,7 +221,8 @@ <stdout> <line text="Annotations on field1? true"/> <line text="Annotation count is 1"/> - <line text="@Annot(a=a, fred=false, value=abc)"/> + <line text="@Annot(a=a, fred=false, value=abc)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@Annot(a='a', fred=false, value="abc")" vm="9+"/> </stdout> </run> </ajc-test> @@ -227,7 +233,8 @@ <stdout> <line text="Annotations on field1? true"/> <line text="Annotation count is 1"/> - <line text="@Annot(a=a, fred=false, value=abc)"/> + <line text="@Annot(a=a, fred=false, value=abc)" vm="1.4,1.5,1.6,1.7,1.8"/> + <line text="@Annot(a='a', fred=false, value="abc")" vm="9+"/> </stdout> </run> </ajc-test> diff --git a/tests/src/org/aspectj/systemtest/ajc173/ajc173.xml b/tests/src/org/aspectj/systemtest/ajc173/ajc173.xml index 7c2b88a54..398fae62f 100644 --- a/tests/src/org/aspectj/systemtest/ajc173/ajc173.xml +++ b/tests/src/org/aspectj/systemtest/ajc173/ajc173.xml @@ -9,7 +9,8 @@ </compile> <run class="Hello"> <stdout> - <line text="@MyAnnotation(dummy1=, dummy2=korte)"/> + <line text="@MyAnnotation(dummy1=, dummy2=korte)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="@MyAnnotation(dummy1="", dummy2="korte")" vm="9+"/> </stdout> </run> </ajc-test> diff --git a/tests/src/org/aspectj/systemtest/ajc1811/Ajc1811Tests.java b/tests/src/org/aspectj/systemtest/ajc1811/Ajc1811Tests.java index f354bd9e4..80729f894 100644 --- a/tests/src/org/aspectj/systemtest/ajc1811/Ajc1811Tests.java +++ b/tests/src/org/aspectj/systemtest/ajc1811/Ajc1811Tests.java @@ -56,13 +56,14 @@ public class Ajc1811Tests extends org.aspectj.testing.XMLBasedAjcTestCase { assertEquals("LOuter$Inner;",type.getSignature()); // public Inner m() { ... } - Method m3 = findMethod(jc,"m"); - System.out.println(m3); - System.out.println(">"+m3.getReturnType()); +// Method m = findMethod(jc,"m"); +// System.out.println(m); +// System.out.println(">"+m.getReturnType()); // assertNotNull(returnType); // public Outer<String>.Inner m2() { ... } } + // // public void testMultiArgs_509235() { // runTest("multiargs"); @@ -72,6 +73,12 @@ public class Ajc1811Tests extends org.aspectj.testing.XMLBasedAjcTestCase { // runTest("multiargs - no ellipsis"); // } + // 1.8.13: + + public void testAjcGenerics() { + runTest("generics"); + } + // --- public static Test suite() { diff --git a/tests/src/org/aspectj/systemtest/ajc1811/ajc1811.xml b/tests/src/org/aspectj/systemtest/ajc1811/ajc1811.xml index f4e321e5c..fe59c3595 100644 --- a/tests/src/org/aspectj/systemtest/ajc1811/ajc1811.xml +++ b/tests/src/org/aspectj/systemtest/ajc1811/ajc1811.xml @@ -6,6 +6,23 @@ <compile options="-1.8" files="Code.java"/> </ajc-test> + <ajc-test dir="bugs1813/generics" title="generics"> + <!-- this order works reliably --> + <compile options="-1.8 -showWeaveInfo" files="A.java AlreadyImplementsA.java BaseI.java BaseT.java BindInterfaceA.aj ConcreteIImpl.java ConcreteTImpl.java Runner.java"> + <message kind="weave" text="Extending interface set for type 'AlreadyImplementsA' (AlreadyImplementsA.java) to include 'A<ConcreteTImpl,ConcreteIImpl>' (BindInterfaceA.aj)"/> + </compile> + + <!-- this order was failing --> + <compile options="-1.8 -showWeaveInfo" files="AlreadyImplementsA.java BaseI.java BaseT.java BindInterfaceA.aj ConcreteIImpl.java ConcreteTImpl.java A.java Runner.java "> + <message kind="weave" text="Extending interface set for type 'AlreadyImplementsA' (AlreadyImplementsA.java) to include 'A<ConcreteTImpl,ConcreteIImpl>' (BindInterfaceA.aj)"/> + </compile> + <run class="Runner"> + <stdout> + <line text="ok"/> + </stdout> + </run> + </ajc-test> + <ajc-test dir="bugs1811/509235" title="multiargs"> <compile options="-1.8" files="Code.java"/> <run class="Code"> diff --git a/tests/src/org/aspectj/systemtest/ajc190/Ajc190Tests.java b/tests/src/org/aspectj/systemtest/ajc190/Ajc190Tests.java new file mode 100644 index 000000000..607f723fc --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc190/Ajc190Tests.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2016 Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial API and implementation + *******************************************************************************/ +package org.aspectj.systemtest.ajc190; + +import java.io.File; + +import org.aspectj.testing.XMLBasedAjcTestCase; + +import junit.framework.Test; + +/** + * @author Andy Clement + */ +public class Ajc190Tests extends org.aspectj.testing.XMLBasedAjcTestCase { + + public void testAnnotMethodHasMember_pr156962_1() { // From similar in Ajc153Tests + runTest("Test Annot Method Has Member 1"); + } + + public void testAnnotMethodHasMember_pr156962_2() { // From similar in Ajc153Tests + runTest("Test Annot Method Has Member 1"); + } + + public void testFunnySignature() { + runTest("funny signature with method reference"); + } + + // Weave a module with code that isn't in a module + public void testWeaveModule() throws Exception { + runTest("weave module"); + } + + // --- + + public static Test suite() { + return XMLBasedAjcTestCase.loadSuite(Ajc190Tests.class); + } + + @Override + protected File getSpecFile() { + return getClassResource("ajc190.xml"); + } + +} diff --git a/tests/src/org/aspectj/systemtest/ajc190/AllTestsAspectJ190.java b/tests/src/org/aspectj/systemtest/ajc190/AllTestsAspectJ190.java new file mode 100644 index 000000000..4f795f960 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc190/AllTestsAspectJ190.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial API and implementation + *******************************************************************************/ +package org.aspectj.systemtest.ajc190; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class AllTestsAspectJ190 { + + public static Test suite() { + TestSuite suite = new TestSuite("AspectJ 1.9.0 tests"); + // $JUnit-BEGIN$ + suite.addTest(Ajc190Tests.suite()); + suite.addTest(SanityTests19.suite()); + suite.addTest(ModuleTests.suite()); + suite.addTest(Annotations.suite()); + // $JUnit-END$ + return suite; + } +} diff --git a/tests/src/org/aspectj/systemtest/ajc190/Annotations.java b/tests/src/org/aspectj/systemtest/ajc190/Annotations.java new file mode 100644 index 000000000..b2f8c267e --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc190/Annotations.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2004, 2017 IBM + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.aspectj.systemtest.ajc190; + +import java.io.File; + +import junit.framework.Test; + +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.testing.XMLBasedAjcTestCase; + +/** + * A copy of the 1.5.0 Annotations test but with compliance set to 1.9 + * The testdata is referenced in the 150 test folder but the XML file indicates compliance of 1.9. + * + * @author Andy Clement + */ +public class Annotations extends XMLBasedAjcTestCase { + + public static Test suite() { + return XMLBasedAjcTestCase.loadSuite(Annotations.class); + } + + protected File getSpecFile() { + return new File("../tests/src/org/aspectj/systemtest/ajc190/ajc190_from150.xml"); + } + + public void testCompilingAnnotation() { + runTest("compiling an annotation"); + } + + public void testCompilingAnnotatedFile() { + runTest("compiling annotated file"); + } + + public void testCompilingUsingWithinAndAnnotationTypePattern() { + runTest("annotations and within (src)"); + } + + /** + * We had a bug where annotations were not present in the output class file for + * methods that got woven. This was due to unpacking bugs in LazyMethodGen. This + * test compiles a simple program then checks the annotations were copied + * across. + */ + public void testBugWithAnnotationsLostOnWovenMethods() throws ClassNotFoundException { + runTest("losing annotations..."); + if (getCurrentTest().canRunOnThisVM()) { + + JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), "Program"); + Method[] meths = jc.getMethods(); + for (int i = 0; i < meths.length; i++) { + Method method = meths[i]; + if (method.getName().equals("m1")) { + assertTrue("Didn't have annotations - were they lost? method=" + method.getName(), + method.getAnnotations().length == 1); + } + } + } + } + + public void testAnnotatedAnnotations() { + runTest("annotated annotations (@Target)"); + } + + public void testSimpleAnnotatedAspectMembers() { + runTest("simple annotated aspect members"); + } + + public void testAnnotatedAspectMembersWithWrongAnnotationType() { + runTest("simple annotated aspect members with bad target"); + } + + // more implementation work needed before this test passes + public void testAnnotatedITDs() { + runTest("annotated itds"); + } + + public void testAnnotatedITDs2() { + runTest("annotated public itds"); + } + + public void testAnnotatedITDs3() { + runTest("annotated public itds - values"); + } + + public void testAnnotatedITDs4() { + runTest("annotated public itds - multiple complex annotations"); + } + + public void testAnnotatedITDsWithWrongAnnotationType() { + runTest("annotated itds with bad target"); + } + + public void testAnnotatedAdvice() { + runTest("annotated advice"); + } + + public void testAnnotatedAdviceWithWrongAnnotationType() { + runTest("annotated advice with bad target"); + } + + public void testAnnotatedPointcut() { + runTest("annotated pointcut"); + } + + // FIXME asc uncomment this test when parser is opened up + // public void testAnnotatedDeclareStatements() { + // runTest("annotated declare statements"); + // } + + public void testBasicDeclareAnnotation() { + runTest("basic declare annotation parse test"); + } + + public void testAJDKAnnotatingAspects() { + runTest("ajdk: annotating aspects chapter"); + } + + public void testAJDKAnnotatingAspects2() { + runTest("ajdk: annotating aspects chapter, ex 2"); + } + + public void testAnnotationPatterns() { + runTest("ajdk: annotation pattern matching"); + } + + public void testAnnotationTypePatterns() { + runTest("ajdk: annotation type pattern matching"); + } + + public void testAnnotationSigPatterns() { + runTest("ajdk: annotations in sig patterns"); + } + + public void testAnnotationRuntimeMatching() { + runTest("ajdk: runtime annotations"); + } + + public void testAnnotationRetentionChecking() { + runTest("ajdk: @retention checking"); + } + + public void testAnnotationInheritance() { + runTest("ajdk: @inherited"); + } + + public void testAnnotationDEOW() { + runTest("ajdk: deow-ann"); + } + + public void testAnnotationDecp() { + runTest("ajdk: decp-ann"); + } + + public void testAnnotationDecPrecedence() { + runTest("ajdk: dec precedence"); + } + + public void testAnnotationDecAnnotation() { + runTest("ajdk: dec annotation"); + } + + public void testAnnotationsAndITDs() { + runTest("nasty annotation and itds test"); + } + + // helper methods..... + +}
\ No newline at end of file diff --git a/tests/src/org/aspectj/systemtest/ajc190/ModuleTests.java b/tests/src/org/aspectj/systemtest/ajc190/ModuleTests.java new file mode 100644 index 000000000..5b5efb15b --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc190/ModuleTests.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2017 Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.aspectj.systemtest.ajc190; + +import java.io.File; + +import junit.framework.Test; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.Code; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.testing.XMLBasedAjcTestCase; + +/** + * Building and weaving with modules in the picture... + * + * @author Andy Clement + * + */ +public class ModuleTests extends org.aspectj.testing.XMLBasedAjcTestCase { + + public void testBuildAModule() { + runTest("build a module"); + } + + public void testRunModuleClassPath() { + runTest("run a module - classpath"); + } + + public void testRunModuleModulePath() { + runTest("run a module - modulepath"); + } + + public void testPackageAndRunModuleFromModulePath() { + runTest("package and run a module - modulepath"); + } + + public void testBuildModuleIncludingAspects() { + runTest("compile module including aspects"); + } + + public void testBinaryWeavingAModuleJar() { + // Pass a module on inpath, does it weave ok with a source aspect, does it run afterwards? + runTest("binary weaving module"); + } + + // can't really write these tests now... pure jdt seems to allow type resolution against module path for types + // not in modules being compiled but javac does not + + public void xtestReferenceTypesFromModuleInBuildingSomeCode() { + runTest("compile regular code using module code"); + } + + public void xtestReferenceTypesFromModuleInBuildingSomeCodeButCantSeeThem() { + runTest("compile regular code using module code that isn't visible"); + } + + public void xtestBinaryWeavingInvolvingTypesOnModulePath() { + fail(); + } + + public void xtestLoadtimeWeavingWithModulePathContainingTypes() { + fail(); + } + + /* For the specified class, check that each method has a stackmap attribute */ + private void checkStackMapExistence(String classname, String toIgnore) throws ClassNotFoundException { + toIgnore = "_" + (toIgnore == null ? "" : toIgnore) + "_"; + JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), classname); + Method[] methods = jc.getMethods(); + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + if (toIgnore.contains("_" + method.getName() + "_")) { + continue; + } + boolean hasStackMapAttribute = findAttribute(method.getAttributes(), "StackMapTable"); + if (!hasStackMapAttribute) { + fail("Could not find StackMap attribute for method " + method.getName()); + } + } + } + + private boolean findAttribute(Attribute[] attrs, String attributeName) { + if (attrs == null) { + return false; + } + for (int i = 0; i < attrs.length; i++) { + Attribute attribute = attrs[i]; + if (attribute.getName().equals(attributeName)) { + return true; + } + // System.out.println(attribute.getName()); + if (attribute.getName().equals("Code")) { + Code c = (Code) attribute; + Attribute[] codeAttributes = c.getAttributes(); + for (int j = 0; j < codeAttributes.length; j++) { + Attribute codeAttribute = codeAttributes[j]; + if (codeAttribute.getName().equals(attributeName)) { + return true; + // System.out.println(codeAttribute.getName()); + } + } + } + } + return false; + } + + private void checkVersion(String classname, int major, int minor) throws ClassNotFoundException { + JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), classname); + if (jc.getMajor() != major) { + fail("Expected major version to be " + major + " but was " + jc.getMajor()); + } + if (jc.getMinor() != minor) { + fail("Expected minor version to be " + minor + " but was " + jc.getMinor()); + } + } + + // Check the stackmap stuff is removed when a method gets woven (for now...) + // public void testStackMapAttributesDeletedInWovenCode() { + // fail("Not implemented"); + // } + + // /////////////////////////////////////// + public static Test suite() { + return XMLBasedAjcTestCase.loadSuite(ModuleTests.class); + } + + protected File getSpecFile() { + return getClassResource("ajc190.xml"); + } + +} diff --git a/tests/src/org/aspectj/systemtest/ajc190/SanityTests19.java b/tests/src/org/aspectj/systemtest/ajc190/SanityTests19.java new file mode 100644 index 000000000..5544022c4 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc190/SanityTests19.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial API and implementation + *******************************************************************************/ +package org.aspectj.systemtest.ajc190; + +import java.io.File; + +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.testing.XMLBasedAjcTestCase; + +import junit.framework.Test; + +/* + * Some very trivial tests that help verify things are OK. + * These are a copy of the earlier Sanity Tests created for 1.6 but these supply the -1.9 option + * to check code generation and modification with that version specified. + */ +public class SanityTests19 extends org.aspectj.testing.XMLBasedAjcTestCase { + + // Incredibly trivial test programs that check the compiler works at all (these are easy-ish to debug) + public void testSimpleJava_A() { + runTest("simple - a"); + } + + public void testSimpleJava_B() { + runTest("simple - b"); + } + + public void testSimpleCode_C() { + runTest("simple - c"); + } + + public void testSimpleCode_D() { + runTest("simple - d"); + } + + public void testSimpleCode_E() { + runTest("simple - e"); + } + + public void testSimpleCode_F() { + runTest("simple - f"); + } + + public void testSimpleCode_G() { + runTest("simple - g"); + } + + public void testSimpleCode_H() { + runTest("simple - h", true); + } + + public void testSimpleCode_I() { + runTest("simple - i"); + } + + // Check the version number in the classfiles is correct when Java6 options specified + public void testVersionCorrect1() throws ClassNotFoundException { + runTest("simple - j"); + checkVersion("A", 53, 0); + } + + public void testVersionCorrect2() throws ClassNotFoundException { + runTest("simple - k"); + checkVersion("A", 53, 0); + } + + public void testVersionCorrect4() throws ClassNotFoundException { // check it is 49.0 when -1.5 is specified + runTest("simple - m"); + checkVersion("A", 49, 0); + } + + // Check the stackmap stuff appears for methods in a Java6 file + // public void testStackMapAttributesAppear() throws ClassNotFoundException { + // runTest("simple - n"); + // checkStackMapExistence("A","<init>_<clinit>"); + // checkStackMapExistence("X","<init>_<clinit>_ajc$pointcut$$complicatedPointcut$1fe"); + // } + + /* For the specified class, check that each method has a stackmap attribute */ +// private void checkStackMapExistence(String classname, String toIgnore) throws ClassNotFoundException { +// toIgnore = "_" + (toIgnore == null ? "" : toIgnore) + "_"; +// JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), classname); +// Method[] methods = jc.getMethods(); +// for (int i = 0; i < methods.length; i++) { +// Method method = methods[i]; +// if (toIgnore.contains("_" + method.getName() + "_")) { +// continue; +// } +// boolean hasStackMapAttribute = findAttribute(method.getAttributes(), "StackMapTable"); +// if (!hasStackMapAttribute) { +// fail("Could not find StackMap attribute for method " + method.getName()); +// } +// } +// } + +// private boolean findAttribute(Attribute[] attrs, String attributeName) { +// if (attrs == null) { +// return false; +// } +// for (int i = 0; i < attrs.length; i++) { +// Attribute attribute = attrs[i]; +// if (attribute.getName().equals(attributeName)) { +// return true; +// } +// // System.out.println(attribute.getName()); +// if (attribute.getName().equals("Code")) { +// Code c = (Code) attribute; +// Attribute[] codeAttributes = c.getAttributes(); +// for (int j = 0; j < codeAttributes.length; j++) { +// Attribute codeAttribute = codeAttributes[j]; +// if (codeAttribute.getName().equals(attributeName)) { +// return true; +// // System.out.println(codeAttribute.getName()); +// } +// } +// } +// } +// return false; +// } + + private void checkVersion(String classname, int major, int minor) throws ClassNotFoundException { + JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), classname); + if (jc.getMajor() != major) { + fail("Expected major version to be " + major + " but was " + jc.getMajor()); + } + if (jc.getMinor() != minor) { + fail("Expected minor version to be " + minor + " but was " + jc.getMinor()); + } + } + + // Check the stackmap stuff is removed when a method gets woven (for now...) + // public void testStackMapAttributesDeletedInWovenCode() { + // fail("Not implemented"); + // } + + // /////////////////////////////////////// + public static Test suite() { + return XMLBasedAjcTestCase.loadSuite(SanityTests19.class); + } + + protected File getSpecFile() { + return getClassResource("sanity-tests-19.xml"); + } + +} diff --git a/tests/src/org/aspectj/systemtest/ajc190/ajc190.xml b/tests/src/org/aspectj/systemtest/ajc190/ajc190.xml new file mode 100644 index 000000000..c2da5de60 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc190/ajc190.xml @@ -0,0 +1,110 @@ +<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]> + +<suite> + + <ajc-test dir="bugs190/modules/aaa" title="build a module"> + <compile files="module-info.java com/foo1/C1.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs190/modules/bbb" title="run a module - classpath"> + <compile files="module-info.java aaa/bbb/A.java" options="-1.9"/> + <run class="aaa.bbb.A"> + <stdout> + <line text="A running"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs190/modules/bbb" title="run a module - modulepath"> + <compile files="module-info.java aaa/bbb/A.java" options="-1.9"/> + <run modulepath="$sandbox" module="my.module/aaa.bbb.A"> + <stdout> + <line text="A running"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs190/modules/bbb" title="package and run a module - modulepath"> + <compile files="module-info.java aaa/bbb/A.java" options="-1.9" outjar="my.module.jar"/> + <file deletefile="module-info.java"/> + <file deletefile="aaa"/> + <run modulepath="my.module.jar" module="my.module/aaa.bbb.A"> + <stdout> + <line text="A running"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs190/modules/ccc" title="compile regular code using module code"> + <compile files="module-info.java aaa/bbb/A.java" options="-1.9" outjar="modules/my.module.jar"/> + <file deletefile="module-info.java"/> + <file deletefile="aaa"/> + <compile files="InvokeA.java" options="-1.9" modulepath="$sandbox/modules/my.module.jar"/> + </ajc-test> + + <ajc-test dir="bugs190/modules/ddd" title="compile regular code using module code that isn't visible"> + <compile files="module-info.java aaa/bbb/A.java" options="-1.9" outjar="modules/my.module.jar"/> + <compile files="InvokeA.java" options="-1.9" modulepath="$sandbox/modules/my.module.jar"> + <message kind="error" text="package aaa.bbb is not visible"/> + </compile> + </ajc-test> + + + <ajc-test dir="bugs190/modules/eee" title="binary weaving module"> + <compile files="module-info.java aaa/bbb/A.java" options="-1.9" outjar="my.module.jar"/> + <file deletefile="module-info.java"/> + <file deletefile="aaa"/> + <compile files="Azpect.java" inpath="my.module.jar" outjar="my.module.woven.jar"/> + <run modulepath="my.module.woven.jar" module="my.module/aaa.bbb.A"> + <stdout> + <line text="Azpect running"/> + <line text="A running"/> + </stdout> + </run> + </ajc-test> + + + <ajc-test dir="bugs190/520135" title="funny signature with method reference"> + <compile files="FailsApectJ.java" options="-1.8"/> + </ajc-test> + + <ajc-test dir="bugs190/modules/fff" title="compile module including aspects"> + <compile files="module-info.java pkg/Demo.java otherpkg/Azpect.java" modulepath="$runtime" outjar="demomodule.jar" options="-1.9"/> + <run modulepath="$runtime:demomodule.jar" module="demo/pkg.Demo"> + <stdout> + <line text="Azpect running"/> + <line text="Demo running"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs190/modules" title="weave module"> + <compile files="aspect1/Azpect1.java" inpath="module1/module-one.jar" outjar="runner.jar" options="-1.8"/> + <java classpath="runner.jar" class="a.b.c.Code"/> + </ajc-test> + + <ajc-test dir="bugs190/various" title="setting static final outside clinit"> + <compile files="Code.java" options="-1.9"/> + <run class="Code"> + <stdout> + <line text="call(void java.io.PrintStream.println(String))"/> + <line text="running"/> + </stdout> + </run> + </ajc-test> + + <!-- from ajc153 --> + <ajc-test dir="bugs153/pr156962" title="Test Annot Method Has Member 1"> + <compile files="Sample.java, LiftDeprecation.aj" options="-1.9 -XhasMember -showWeaveInfo -Xlint:ignore"> + <message kind="weave" text="'Sample' (Sample.java:1) is annotated with @Deprecated type annotation from 'LiftDeprecation' (LiftDeprecation.aj:2)"/> + </compile> + </ajc-test> + + <!-- from ajc153 --> + <ajc-test dir="bugs153/pr156962" title="Test Annot Method Has Member 2"> + <compile files="Sample.java, LiftDeprecation.aj" options="-1.8 -XhasMember -showWeaveInfo -Xlint:ignore"> + <message kind="weave" text="'Sample' (Sample.java:1) is annotated with @Deprecated type annotation from 'LiftDeprecation' (LiftDeprecation.aj:2)"/> + </compile> + </ajc-test> + +</suite> diff --git a/tests/src/org/aspectj/systemtest/ajc190/ajc190_from150.xml b/tests/src/org/aspectj/systemtest/ajc190/ajc190_from150.xml new file mode 100644 index 000000000..24d683928 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc190/ajc190_from150.xml @@ -0,0 +1,6290 @@ +<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]> + +<!-- AspectJ v1.5.0 Tests --> +<suite> + + <ajc-test dir="bugs150" title="abstract perthis in @AspectJ"> + <compile files="pr121197.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" title="different numbers of type vars"> + <compile files="pr121575.aj" options="-1.9"/> + <run class="pr121575"/> + </ajc-test> + + + <ajc-test dir="bugs150/pr121385" title="mixing aspect styles"> + <compile files="A.java" options="-1.9"/> + <run class="A"/> + </ajc-test> + + <ajc-test dir="java5/generics/tvars" title="different numbers of type vars - 2"> + <compile files="Case1.aj" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Join point 'method-execution(void MyClass.read(java.lang.String))' in Type 'MyClass' (Case1.aj:13) advised by before advice from 'MyAspect' (Case1.aj:5)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/tvars" title="different numbers of type vars - 3"> + <compile files="Case2.aj" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Join point 'method-execution(void MyClass.read(java.lang.Number))' in Type 'MyClass' (Case2.aj:13) advised by before advice from 'MyAspect' (Case2.aj:5)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/tvars" title="different numbers of type vars - 4"> + <compile files="Case3.aj" options="-1.9 -showWeaveInfo"> + <message kind="error" line="9" text="The type MyClass<T,E> must implement the inherited abstract method MyInterface<T>.read(T)"/> + </compile> + </ajc-test> + + + <ajc-test dir="bugs150" title="access to private ITD from nested type"> + <compile files="pr118698.aj"/> + <run class="pr118698"/> + </ajc-test> + + <ajc-test dir="bugs150" title="modifier overrides"> + <compile files="pr119749.aj" options="-1.9"> + <message kind="warning" line="26" text="C E.*()"/> + <message kind="warning" line="25" text="D E.*()"/> + <message kind="warning" line="17" text="aa @Me void m()"/> + <message kind="warning" line="17" text="aa void m() throws Exception"/> + <message kind="warning" line="17" text="aa * *(..) throws Exception"/> + <message kind="warning" line="37" text="aa call void m() throws Exception"/> + <message kind="warning" line="38" text="aa call void m() throws Exception"/> + </compile> + <run class="pr119749"> + <stdout> + <line text="execution(void pr119749.C.m()): execMe[Me]"/> + <line text="execution(void pr119749.C.m()): execEx"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr120826" pr="120826" title="varargs NPE"> + <compile files="TestVarargs.java" options="-1.9"/> + </ajc-test> + + + <ajc-test dir="bugs150/pr112476/case1" title="binary weaving decp broken"> + <compile files="lib/A.java,lib/B.java,lib/C.java" outjar="library.jar" options="-1.9"/> + <!-- library.jar on the aspectpath here just for resolution when compiling SuperC --> + <compile aspectpath="library.jar" files="weaved/SuperC.java" outjar="newsuper.jar" options="-1.9"/> + <compile inpath="library.jar;newsuper.jar" files="weaved/DeclareAspect.aj" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Setting superclass of type 'lib.C' (C.java) to 'weaved.SuperC' (DeclareAspect.aj)"/> + </compile> + <run class="weaved.SuperC"> + <stdout> + <line text="Is [class lib.C] subcass of [class weaved.SuperC]? true"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr114005" title="Annotated ITDFs - 1"> + <compile files="Declaration1.java" options="-1.9"/> + <run class="Declaration1"> + <stdout> + <line text="public java.lang.String Test.firstProperty has annotation:true"/> + <line text="public java.lang.String Test.secondProperty has annotation:true"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" pr="114495" title="parameterized pointcut and advice"> + <compile files="Pr114495.aj" options="-1.9"> + <message kind="warning" line="3" text="going()"/> + </compile> + <run class="Pr114495"> + <stdout> + <line text="A.going()"/> + <line text="AA.going()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" pr="112880" title="double parameter generic abstract type"> + <compile files="Pr112880.aj" options="-1.9"> + </compile> + <run class="Pr112880"> + <stdout> + <line text="method returning C1 or C2"/> + <line text="method returning C1 or C2"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr114005" title="Annotated ITDFs - 2"> + <compile files="Declaration2.java" options="-1.9"/> + <run class="Declaration2"> + <stdout> + <line text="public java.lang.String Test.firstProperty has annotation:true"/> + <line text="public java.lang.String Test.secondProperty has annotation:true"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" pr="114054" title="pertarget and negated pointcut"> + <compile files="Pr114054.aj" options=""/> + <run class="Pr114054"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="121385" title="mixing styles"> + <compile files="pr121385.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/decps" title="decps - 1"> + <compile files="Basic1.java" options="-1.9"/> + <run class="Basic1"/> + </ajc-test> + + <ajc-test dir="java5/decps" title="decps - 1b"> + <compile files="Basic1b.java" options="-1.9"/> + <run class="Basic1b"/> + </ajc-test> + + <ajc-test dir="java5/decps" title="decps - 2"> + <compile files="Basic2.java" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Join point 'method-execution(void X$I.m2())' in Type 'X' (Basic2.java:15) advised by before advice from 'X' (Basic2.java:23)"/> + <message kind="weave" text="Type 'X$I' (Basic2.java) has intertyped method from 'X' (Basic2.java:'void X$I.m2()')"/> + <message kind="weave" text="Extending interface set for type 'Basic2' (Basic2.java) to include 'X$I' (Basic2.java)"/> + <message kind="weave" text="Type 'Basic2' (Basic2.java) has intertyped method from 'X' (Basic2.java:'void X$I.m2()')"/> + <message kind="weave" text="Join point 'method-execution(void Basic2.main(java.lang.String[]))' in Type 'Basic2' (Basic2.java:2) advised by before advice from 'X' (Basic2.java:23)"/> + </compile> + <run class="Basic2"/> + </ajc-test> + + <ajc-test dir="java5/decps" title="decps - 2b"> + <compile files="Basic2b.java" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Join point 'method-execution(void X$IIimpl.m2())' in Type 'X$IIimpl' (Basic2b.java:18) advised by before advice from 'X' (Basic2b.java:27)"/> + <message kind="weave" text="Extending interface set for type 'Basic2b' (Basic2b.java) to include 'X$I' (Basic2b.java)"/> + <message kind="weave" text="Join point 'method-execution(void Basic2b.main(java.lang.String[]))' in Type 'Basic2b' (Basic2b.java:4) advised by before advice from 'X' (Basic2b.java:27)"/> + </compile> + <run class="Basic2b"/> + </ajc-test> + + <ajc-test dir="java5/decps" title="decps - 3"> + <compile files="Basic3.java" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Extending interface set for type 'Basic3' (Basic3.java) to include 'X$I' (Basic3.java)"/> + <message kind="weave" text="Type 'Basic3' (Basic3.java) has intertyped method from 'X' (Basic3.java:'void X$I.m2()')"/> + <message kind="weave" text="Type 'Basic3' (Basic3.java) has intertyped method from 'X' (Basic3.java:'void X$I.m3()')"/> + <message kind="weave" text="Type 'Basic3' (Basic3.java) has intertyped method from 'X' (Basic3.java:'void X$I.m4()')"/> + <message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3' (Basic3.java:7) advised by before advice from 'X' (Basic3.java:29)"/> + <message kind="weave" text="Join point 'method-call(void X$I.m3())' in Type 'Basic3' (Basic3.java:8) advised by before advice from 'X' (Basic3.java:29)"/> + <message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3' (Basic3.java:9) advised by before advice from 'X' (Basic3.java:29)"/> + <message kind="weave" text="Join point 'method-call(void X$I.m4())' in Type 'Basic3' (Basic3.java:10) advised by before advice from 'X' (Basic3.java:29)"/> + <message kind="weave" text="Type 'X$I' (Basic3.java) has intertyped method from 'X' (Basic3.java:'void X$I.m2()')"/> + <message kind="weave" text="Type 'X$I' (Basic3.java) has intertyped method from 'X' (Basic3.java:'void X$I.m3()')"/> + <message kind="weave" text="Type 'X$I' (Basic3.java) has intertyped method from 'X' (Basic3.java:'void X$I.m4()')"/> + </compile> + <run class="Basic3"/> + </ajc-test> + + <ajc-test dir="java5/decps" title="decps - 3b"> + <compile files="Basic3b.java" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Extending interface set for type 'Basic3b' (Basic3b.java) to include 'X$I' (Basic3b.java)"/> + <message kind="weave" text="Type 'Basic3b' (Basic3b.java) has intertyped method from 'X' (Basic3b.java:'void X$I.m2()')"/> + <message kind="weave" text="Type 'Basic3b' (Basic3b.java) has intertyped method from 'X' (Basic3b.java:'void X$I.m3()')"/> + <message kind="weave" text="Type 'Basic3b' (Basic3b.java) has intertyped method from 'X' (Basic3b.java:'void X$I.m4()')"/> + <message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3b' (Basic3b.java:7) advised by before advice from 'X' (Basic3b.java:35)"/> + <message kind="weave" text="Join point 'method-call(void X$I.m3())' in Type 'Basic3b' (Basic3b.java:8) advised by before advice from 'X' (Basic3b.java:35)"/> + <message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3b' (Basic3b.java:9) advised by before advice from 'X' (Basic3b.java:35)"/> + <message kind="weave" text="Join point 'method-call(void X$I.m4())' in Type 'Basic3b' (Basic3b.java:10) advised by before advice from 'X' (Basic3b.java:35)"/> + </compile> + <run class="Basic3b"/> + </ajc-test> + + <ajc-test dir="java5/decps" title="decps - 3c"> + <compile files="Basic3c.java" options="-1.9"> + <message kind="error" text="@DeclareParents: defaultImpl="X$IImpl" has a no argument constructor, but it is of incorrect visibility"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr119570" pr="119570" title="spurious override method warning"> + <compile files="NodeImpl.java,INode.java,ParameterizedDP.java" options="-1.9"/> + <run class="bugs.ParameterizedDP"/> + </ajc-test> + + <ajc-test dir="bugs150/pr119570" pr="119570" title="spurious override method warning - 2"> + <compile files="ParameterizedDP.java,NodeImpl.java,INode.java" options="-1.9"/> + <run class="bugs.ParameterizedDP"/> + </ajc-test> + + <ajc-test dir="bugs150/pr119570" pr="119570" title="spurious override method warning - 3"> + <compile files="SimpleTest.java" options="-1.9"/> + <run class="SimpleTest"/> + </ajc-test> + + <ajc-test dir="bugs150/pr120521" pr="120521" title="named pointcut not resolved in pertarget pointcut"> + <compile files="PerTargetSubaspectError.java"/> + </ajc-test> + + <ajc-test dir="bugs150/pr119210" pr="119210" title="autoboxing around advice - 1"> + <compile files="TestLib.java,ThreadAspectLib.java" options="-1.9"/> + <run class="TestLib"> + <stderr> + <line text="obtaining five, got 3"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr119210" pr="119210" title="autoboxing around advice - 2"> + <compile files="TestLib2.java,ThreadAspectLib2.java" options="-1.9"/> + <run class="TestLib2"> + <stderr> + <line text="obtaining five, got 3"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr119210" pr="119210" title="autoboxing around advice - 3"> + <compile files="TestLib2.java,ThreadAspectLib2.java"> + <message kind="error" line="16" text="incompatible return type applying to method-call(java.lang.Integer TestLib2.getFive())"/> + <message kind="error" line="4" text="incompatible return type applying to method-call(java.lang.Integer TestLib2.getFive())"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr119539" pr="119539" title="generic pertypewithin aspect - 1"> + <compile files="GenericPerTypeWithin.java" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Join point 'constructor-execution(void bugs.C.<init>())' in Type 'bugs.C' (GenericPerTypeWithin.java:10) advised by before advice from 'bugs.A' (GenericPerTypeWithin.java:21)"/> + <message kind="weave" text="Join point 'constructor-execution(void bugs.C.<init>())' in Type 'bugs.C' (GenericPerTypeWithin.java:10) advised by before advice from 'bugs.A' (GenericPerTypeWithin.java:20)"/> + </compile> + <run class="bugs.GenericPerTypeWithin"/> + </ajc-test> + + <ajc-test dir="bugs150/pr119539" pr="119539" title="generic pertypewithin aspect - 2"> + <compile files="GenericPerTypeWithin2.java" options="-1.9 -showWeaveInfo"> + <message kind="error" line="24" text="a generic super-aspect must be fully parameterized in an extends clause"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr119539" pr="119539" title="generic pertypewithin aspect - 3"> + <compile files="GenericPerTypeWithin3.java" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Join point 'constructor-execution(void bugs.GenericPerTypeWithin3$C.<init>())' in Type 'bugs.GenericPerTypeWithin3$C' (GenericPerTypeWithin3.java:15) advised by before advice from 'bugs.GenericPerTypeWithin3$A' (GenericPerTypeWithin3.java:10)"/> + <message kind="warning" line="15" text="Singleton.creation()"/> + </compile> + <run class="bugs.GenericPerTypeWithin3"/> + </ajc-test> + + <ajc-test dir="bugs150/pr117854" pr="117854" title="broken switch transform"> + <compile files="BrokenSwitch.java" options=""/> + <run class="BrokenSwitch"/> + </ajc-test> + + <ajc-test dir="bugs150/pr119749" pr="119749" title="incorrect exception signature matching"> + <compile files="InheritedThrows.java" options="-showWeaveInfo"> + <message kind="weave" text="Join point 'method-execution(void InheritedThrows$NestedClassBoth.m())' in Type 'InheritedThrows$NestedClassBoth' (InheritedThrows.java:24) advised by afterThrowing advice from 'InheritedThrows$A' (InheritedThrows.java:4)"/> + <message kind="weave" text="Join point 'method-execution(void InheritedThrows$NestedClass1.m())' in Type 'InheritedThrows$NestedClass1' (InheritedThrows.java:16) advised by afterThrowing advice from 'InheritedThrows$A' (InheritedThrows.java:4)"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr118599" pr="118599" title="ambiguous method when binary weaving - 1"> + <!-- separate compilation was failing --> + <compile files="Attributable.java" outjar="foo.jar" options="-1.9"/> + <compile files="AnAttributedClass.java" aspectpath="foo.jar" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr118599" pr="118599" title="ambiguous method when binary weaving - 2"> + <!-- complete compilation works --> + <compile files="Attributable.java,AnAttributedClass.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="104220" title="adviceexecution join point toString forms"> + <compile files="Pr104220.aj"/> + <run class="Pr104220"> + <stdout> + <line text="adviceexecution"/> + <line text="adviceexecution(void SomeAspect.before())"/> + <line text="adviceexecution(SomeAspect.before())"/> + <line text="adviceexecution(void SomeAspect.before())"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" pr="112756" title="pointcut expression containing 'assert'"> + <compile files="Pr112756.aj" options="-warn:assertIdentifier -Xdev:Pinpoint"/> + </ajc-test> + + <ajc-test dir="bugs150/pr118781" pr="118781" title="verify error with around advice array sigs"> + <compile files="MyMain.java,MyAspect.java,MyClass.java" options="-XnoInline"/> + <run class="blah.MyMain"/> + </ajc-test> + + <ajc-test dir="bugs150/pr117681" pr="117681" title="at declare parents"> + <compile files="Test.java,TestAspect.java,Audit.java,AuditImpl.java" options="-1.9"/> + <run class="Test"/> + </ajc-test> + + <ajc-test dir="bugs150/pr120474" pr="120474" title="Dollar classes"> + <compile files="$ProxyPr120474.java"/> + <compile files="X.aj" options="-outxml"/> + <run class="$ProxyPr120474" ltw="aop.xml"> + <stdout> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr111667" pr="111667" title="lint for advice sorting"> + <compile files="A.java,X.java,Y.java" options="-1.9 -Xlint:warning"> + <message kind="warning" line="9" text="at this shadow method-execution(void A.m1()) no precedence is specified between advice applying from aspect X and aspect Y [Xlint:unorderedAdviceAtShadow]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr118326" pr="118326" title="illegal initialization - 1"> + <compile files="Foo.java,Bar.java"> + <message kind="error" line="2" text="Type mismatch: cannot convert from null to int"/> + <message kind="error" line="6" text="Type mismatch: cannot convert from Integer to int"/> + <message kind="error" line="8" text="Type mismatch: cannot convert from String to int"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr118326" pr="118326" title="illegal initialization - 2"> + <compile files="Foo.java,Bar.java" options="-1.9"> + <message kind="error" line="2" text="Type mismatch: cannot convert from null to int"/> + <message kind="error" line="8" text="Type mismatch: cannot convert from String to int"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr117296" pr="117296" title="self bounding generic types"> + <compile files="PropertySupport.java" options="-1.9"/> + <run class="PropertySupport"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="113368" title="thisJoinPointStaticPart in if test"> + <compile files="Pr113368.aj"/> + <run class="Pr113368"> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr87525" pr="87525" title="privilege problem with switch"> + <compile files="A.java,B.java"> + <message kind="error" line="5" text="Fields accessible due to an aspect being privileged can not be used in switch statements"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/reflection" title="pointcut parsing with ajc compiled pointcut references"> + <compile files="PointcutLibrary.aj,ReflectOnAjcCompiledPointcuts.java" options="-1.9"></compile> + <run class="ReflectOnAjcCompiledPointcuts" classpath="../lib/bcel/bcel.jar"/> + </ajc-test> + + <ajc-test dir="java5/reflection" title="reflection on itds"> + <compile files="InterTypeDeclarations.aj,ReflectOnCodeStyleITDs.java" options="-1.9 -Xlint:ignore -makeAjReflectable"></compile> + <run class="ReflectOnCodeStyleITDs" classpath="../lib/bcel/bcel.jar"> + <stdout> + <line text="public C.new(int, int, int)"/> + <line text="C.new(int, int)"/> + <line text="private C.new(int)"/> + <line text="private C.new(int)"/> + <line text="public C.new(int, int, int)"/> + <line text="public C.new(int, int, int)"/> + <line text="int C.getY()"/> + <line text="int I.getY()"/> + <line text="public int C.getZ()"/> + <line text="public int I.getZ()"/> + <line text="private int C.getX()"/> + <line text="private int I.getX()"/> + <line text="private int C.getX()"/> + <line text="public int C.getZ()"/> + <line text="public int I.getZ()"/> + <line text="public int C.getZ()"/> + <line text="int C.y"/> + <line text="int I.y"/> + <line text="public int C.z"/> + <line text="public int I.z"/> + <line text="private int C.x"/> + <line text="private int I.x"/> + <line text="private int C.x"/> + <line text="public int C.z"/> + <line text="public int I.z"/> + <line text="public int C.z"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/reflection" title="reflection on @DeclareParents"> + <compile files="AtAspectJDeclareParents.aj,ReflectOnAtAspectJDeclareParents.java" options="-1.9 -Xlint:ignore"></compile> + <run class="ReflectOnAtAspectJDeclareParents" classpath="../lib/bcel/bcel.jar"> + <stdout> + <line text="declare parents : C implements I"/> + <line text="public int I.getX()"/> + <line text="public void I.setX(int)"/> + <line text="public int I.getX()"/> + <line text="public int I.getX()"/> + <line text="public void I.setX(int)"/> + <line text="public int I.getX()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="compatibility/case1" title="generating code for a 1.2.1 runtime - 1"> + <compile files="Simple.java" options="-Xajruntimetarget:1.2"/> + <run class="Simple" classpath="../lib/aspectj/lib/aspectjrt121.jar"/> + </ajc-test> + + <ajc-test dir="compatibility/case2" title="generating code for a 1.2.1 runtime - 2"> + <compile files="TrackingErrors.aj,A.java" options="-Xajruntimetarget:1.2 -Xlint:ignore"/> + <run class="A" classpath="../lib/aspectj/lib/aspectjrt121.jar"/> + </ajc-test> + + <ajc-test dir="java5/reflection" title="arg names in advice annotations"> + <compile files="AdviceWithArgs.aj" options="-1.9"></compile> + <run class="AdviceWithArgs"/> + </ajc-test> + + + <ajc-test dir="java5/reflection" pr="114322" title="reflection on abstract ITDs (Billing example)"> + <compile files="ReflectBilling.java,Billing.aj" options="-1.9 -makeAjReflectable"/> + <run class="ReflectBilling"> + <stdout> + <line text="public void Customer.addCharge(long)"/> + <line text="public long Local.callRate()"/> + <line text="public long LongDistance.callRate()"/> + <line text="public abstract long Connection.callRate()"/> + <line text="public Customer Connection.payer"/> + <line text="public long Customer.totalCharge"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" pr="103157" title="returning(Object) binding"> + <compile files="Pr103157.aj"/> + <run class="Pr103157"> + <stdout> + <line text="returning from staticinit"/> + <line text="returning from preinit"/> + <line text="returning from set"/> + <line text="returning from cons exe"/> + <line text="returning from init"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" title="declare soft and adviceexecution" pr="103051"> + <compile files="Pr103051.aj" options="-Xdev:Pinpoint"/> + </ajc-test> + + <ajc-test dir="bugs150" title="declare soft and exclusions" pr="103097"> + <compile files="Pr103097.aj" options="-Xlint:ignore"/> + <run class="Pr103097"/> + </ajc-test> + + + <ajc-test dir="bugs150" title="Range problem"> + <compile files="pr109614.java"/> + <run class="pr109614"/> + </ajc-test> + + <ajc-test dir="bugs150/pr114436" title="ClassFormatError binary weaving perthis"> + <compile files="SimpleTrace.aj,ConcreteSimpleTracing.aj" outjar="aspects.jar"/> + <compile files="TestClass.java" aspectpath="aspects.jar"/> + <run class="TestClass"/> + </ajc-test> + + <ajc-test dir="bugs150/pr113066" title="possible static imports bug - 1"> + <compile files="Consts.java,TestNPE.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" title="parameterized type and around advice"> + <compile files="pr115250.aj" options="-1.9 -Xlint:ignore"> + <!-- this first error happens twice, once for each piece of around advice --> + <message kind="error" line="10" text="incompatible return type applying to constructor-execution(void pr115250$C.<init>())"/> + <message kind="error" line="17" text="incompatible return type applying to constructor-execution(void pr115250$C.<init>())"/> + <message kind="error" line="27" text="incompatible return type applying to constructor-execution(void pr115250$C.<init>())"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="parameterized type and around advice - 2"> + <compile files="pr115250_2.aj" options="-1.9 -Xlint:ignore -showWeaveInfo"> + <message kind="weave" text="Join point 'method-execution(pr115250_2$C pr115250_2$C.foo())' in Type 'pr115250_2$C' (pr115250_2.aj:7) advised by around advice from 'pr115250_2$A' (pr115250_2.aj:22)"/> + <message kind="weave" text="Join point 'method-execution(pr115250_2$C pr115250_2$C.foo())' in Type 'pr115250_2$C' (pr115250_2.aj:7) advised by around advice from 'pr115250_2$Normal' (pr115250_2.aj:12)"/> + </compile> + <run class="pr115250_2"> + <stderr> + <line text="funky advice running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr115788" title="parser exception"> + <compile files="AAA.java"> + <message kind="warning" line="3" text="no match for this type name: Screen"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr113066" title="possible static imports bug - 2"> + <compile files="Consts2.java,TestNPE2.java" options="-1.9"> + <message kind="error" line="2" text="The field Consts2.a.Consts2.A_CONST is not visible"/> + <!-- message has changed with 3.3 compiler upgrade, it used to be this: --> + <!-- message kind="error" line="2" text="The import a.Consts2.A_CONST cannot be resolved"/--> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr113066" title="possible static imports bug - 3"> + <compile files="Consts3.java,TestNPE3.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/staticImports" title="import static java.lang.System.out"> + <compile files="StaticImport.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" title="Problem with constructor ITDs"> + <compile files="pr112783.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" title="NPE in ensureScopeSetup"> + <compile files="pr115038.aj" options="-1.9"> + <message kind="error" line="2" text="Cannot make inter-type declarations on type variables"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="ITDC with no explicit cons call"> + <compile files="Pr62606.aj" options="-1.9"> + <message kind="warning" line="6" text="[Xlint:noExplicitConstructorCall]"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/bugs" title="using same type variable in ITD"> + <compile files="SameTypeVariable.aj" options="-1.9"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="capturebinding wildcard problem"> + <compile files="pr114744.aj" options="-1.9"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="Anonymous types and nome matching"> + <compile files="Pr73050.aj" outjar="jar1.jar"> + <message kind="warning" line="16" text="anonymous types should be matched by a * wild card"/> + </compile> + <compile inpath="jar1.jar"> + <message kind="warning" line="0" text="anonymous types should be matched by a * wild card"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr86903" title="bcelrenderer bad"> + <compile files="GenericService.java,Service.java,Main.java,BadWormhole.java"/> + <run class="Main"/> + </ajc-test> + + <ajc-test dir="bugs150/pr114343" title="field-get, generics and around advice"> + <compile files="Test.java,Test1.java,Test2.java,TestAspect.aj" options="-1.9"> + <message kind="warning" line="7" text="unchecked conversion when advice applied at shadow field-get(java.util.Set Test1.intsSet), expected java.util.Set<java.lang.Integer> but advice uses java.util.Set"/> + <message kind="warning" line="8" text="unchecked conversion when advice applied at shadow field-get(java.util.Set Test2.doubSet), expected java.util.Set<java.lang.Double> but advice uses java.util.Set"/> + </compile> + <run class="TestAspect"/> + </ajc-test> + + <ajc-test dir="bugs150/pr113947/case1" title="maws generic aspect - 1"> + <compile files="AbstractListSupport.java,AnotherItem.java,Item.java,LinkedList.java,LinkedListItem.java,ListItem.java,StringList.java" options="-1.9"> + <message kind="error" line="6" text="Cannot make inter-type declarations on type variables"/> + <message kind="error" line="8" text="Cannot make inter-type declarations on type variables"/> + <message kind="error" line="12" text="Cannot make inter-type declarations on type variables"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="aspectOf and generic aspects"> + <compile files="pr115237.aj" options="-1.9"/> + <run class="pr115237"/> + </ajc-test> + + <ajc-test dir="bugs150/pr114343/case2" title="field-get, generics and around advice - 2"> + <compile files="Test.java,TTT.java,TestAspect.java" options="-1.9"/> + <run class="TestAspect"> + <stderr> + <line text="TestAspect.main: Calling foo"/> + <line text="Creating Test<Integer> instance"/> + <line text="Calling toArray"/> + <line text="In around advice"/> + <line text="In toArray()"/> + <line text="done"/> + <line text="TestAspect.main: done"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr114343/case3" title="field-get, generics and around advice - 3"> + <compile files="Test.java,TTT.java,TestAspect.java" options="-1.9"/> + <run class="TestAspect"> + <stderr> + <line text="TestAspect.main: Calling foo"/> + <line text="Creating Test<Integer> instance"/> + <line text="Calling toArray"/> + <line text="In around advice"/> + <line text="In toArray()"/> + <line text="done"/> + <line text="Creating Test<Integer> instance"/> + <line text="Calling getFirst"/> + <line text="around on getFirstExec(): running"/> + <line text="done"/> + <line text="TestAspect.main: done"/> + </stderr> + </run> + </ajc-test> + + + <ajc-test dir="bugs150/pr113947/case2" title="maws generic aspect - 2"> + <compile files="AbstractListSupport.java,AnotherItem.java,Item.java,LinkedList.java,LinkedListItem.java,ListItem.java,StringList.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr113861" title="field-get problems with generic field"> + <compile files="Test.java,TestAspect.java" options="-1.9"/> + <run class="com.Test"/> + </ajc-test> + + + <ajc-test dir="bugs150/pr99191" title="declare annotation on non existent type - 1"> + <compile files="pr99191_1.java" options="-1.9"> + <message kind="error" line="4" text="The field 'int C.noSuchField' does not exist"/> + <message kind="error" line="5" text="The field 'int B.noSuchField' does not exist"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/bugs/lists/case1" title="generics and ITD overrides - 1"> + <compile files="Identifiable.java,Bean.java,LongIdentifiable.java,IdentifiableAspect.java" options="-1.9"> + </compile> + <run class="IdentifiableAspect"/> + </ajc-test> + + <ajc-test dir="java5/generics/bugs/lists/case2" title="generics and ITD overrides - 2"> + <compile files="Identifiable.java,Bean.java,LongIdentifiable.java,IdentifiableAspect.java" options="-1.9"> + </compile> + <run class="IdentifiableAspect"/> + </ajc-test> + + <ajc-test dir="java5/generics/bugs/lists/case3" title="generics and ITD overrides - 3"> + <compile files="Identifiable.java,Bean.java,LongIdentifiable.java,IdentifiableAspect.java" options="-1.9"> + </compile> + <run class="IdentifiableAspect"/> + </ajc-test> + + <ajc-test dir="java5/generics/bugs/lists/case4" title="generics and ITD overrides - 4"> + <compile files="Identifiable.java,Bean.java,LongIdentifiable.java,IdentifiableAspect.java" options="-1.9"> + </compile> + <run class="IdentifiableAspect"/> + </ajc-test> + + <!-- Currently a warning doesn't occur if the annotation is already on the field + (see bug 113029). If this is fixed, need to add check for this warning to this + test as in test "declare annotation on non existent type - 4" --> + <ajc-test dir="bugs150/pr99191" title="declare annotation on non existent type - 2"> + <compile files="pr99191_2.java" options="-1.9"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr99191" title="declare annotation on non existent type - 3"> + <compile files="pr99191_3.java" options="-1.9"> + <message kind="error" line="4" text="The method 'public * C.noSuchMethod(..)' does not exist"/> + <message kind="error" line="5" text="The method '* B.noSuchMethod(..)' does not exist"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr99191" title="declare annotation on non existent type - 4"> + <compile files="pr99191_4.java" options="-1.9"> + <message kind="warning" text="void C.amethod() - already has an annotation of type Annotation, cannot add a second instance [Xlint:elementAlreadyAnnotated]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr99191" title="declare annotation on non existent type - 5"> + <compile files="pr99191_5.java" options="-1.9"> + <message kind="error" line="4" text="The method 'C.new(java.lang.String)' does not exist"/> + <message kind="error" line="5" text="The method 'B.new(int)' does not exist"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr99191" title="declare annotation on non existent type - 6"> + <compile files="pr99191_6.java" options="-1.9"> + <message kind="warning" text="void C.<init>(int) - already has an annotation of type Annotation, cannot add a second instance [Xlint:elementAlreadyAnnotated]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr113630/case1" title="IncompatibleClassChangeError - errorscenario"> + <compile files="Bean.java,BeanTestCase.java,javaBean.java,propertyChanger.java,PropertySupportAspect5.aj" options="-1.9"> + <message kind="warning" line="9" text="Failing match because annotation 'javaBean' on type 'Bean' has SOURCE retention. Matching allowed when RetentionPolicy is CLASS or RUNTIME"/> + <message kind="error" line="18" text="The method addPropertyChangeListener(String, BeanTestCase) is undefined for the type Bean"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr113630/case2" title="IncompatibleClassChangeError - workingscenario"> + <compile files="Bean.java,BeanTestCase.java,javaBean.java,propertyChanger.java,PropertySupportAspect5.aj" options="-1.9"/> + <run class="BeanTestCase"/> + </ajc-test> + + <ajc-test dir="bugs150" title="Generics ClassCastException"> + <compile files="pr113445.aj" options="-1.9,-emacssym"/> + </ajc-test> + + <ajc-test dir="bugs150" title="test illegal change to pointcut declaration"> + <compile files="pr111915.java" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Join point 'method-execution(void SomeClass.doSomething())' in Type 'SomeClass' (pr111915.java:4) advised by around advice from 'DoesntCompile' (pr111915.java:15)"/> + <message kind="weave" text="Extending interface set for type 'SomeClass' (pr111915.java) to include 'java.io.Serializable' (pr111915.java)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/bridgeMethods" pr="72766" title="Ignore bridge methods"> + <compile files="AspectX.aj" inpath="testcode.jar" options="-showWeaveInfo"> + <!-- <message kind="warning" line="7" text="pointcut did not match on the method call to a bridge method."/> + <message kind="warning" line="7" text="does not match because declaring type is Number"/>--> + <message kind="weave" text="(AspectX.aj:18) advised by before advice from 'AspectX'"/> + <message kind="weave" text="(AspectX.aj:19) advised by before advice from 'AspectX'"/> + <message kind="weave" text="(Number.java:5) advised by before advice from 'AspectX'"/> + </compile> + </ajc-test> + + <ajc-test title="intermediate annotation matching" dir="bugs150"> + <compile files="AnnotationPlusPatternMatchingError.aj" options="-1.9"> + <message kind="warning" line="28" text="matched"/> + </compile> + <run class="AnnotationPlusPatternMatchingError"> + <stdout> + <line text="In advice"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="migration" title="load aspectj 1.2.1 aspects in aspectj 5"> + <compile files="Program.java" aspectpath="aspects121.jar"> + </compile> + <run class="Program"/> + </ajc-test> + + <ajc-test dir="bugs/java5/arrayCloning" pr="72150" vm="1.5" + title="AJC possible bug with static nested classes"> + <compile files="A.java,C.java" options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'C' (C.java:14) advised by around advice from 'A' (A.java:2)"/> + </compile> + <run class="C"/> + </ajc-test> + + <ajc-test dir="java5/pseudoKeywords" + title="method called around in class"> + <compile files="MethodCalledAround.java"> + </compile> + </ajc-test> + + <ajc-test dir="java5/pseudoKeywords" + title="method called around in aspect"> + <compile files="MethodCalledAroundAspect.java"> + <message kind="error" line="2"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="64568" title="clear error message on itd with type pattern"> + <compile files="pr64568.aj"> + <message line="4" kind="error" text="Syntax error on token "*", delete this token"/> + <message line="4" kind="error" text="foo cannot be resolved to a type"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="74562" title="before and after are valid identifiers in classes"> + <compile files="pr74562.aj"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="107486" title="anonymous inner classes"> + <compile files="pr107486.aj"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="102210" title="NullPointerException trying to compile"> + <compile files="PR102210.java"/> + <run class="PR102210"> + <stderr> + <line text="List size is 1"/> + <line text="m1 running"/> + <line text="List size is 2"/> + <line text="m2 running"/> + <line text="List size is 3"/> + <line text="m3 running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="bugs150" pr="107486" title="multiple anonymous inner classes"> + <compile files="pr107486part2.aj"> + </compile> + <run class="pr107486part2"> + <stdout> + <line text="[advised] f"/> + <line text="[advised] g"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/compliance" title="java 5 pointcuts and declares at pre-java 5 compliance levels"> + <compile files="AJ5FeaturesAtJ14.aj" options="-1.4"> + <message kind="error" line="3" text="the @annotation pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="11" text="the @within pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="13" text="the @withincode pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="5" text="the @this pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="7" text="the @target pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="9" text="the @args pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="15" text="declare @type is only supported at Java 5 compliance level or above"/> + <message kind="error" line="15" text="annotations are only available if source level is 1.5 or greater"/> + <message kind="error" line="15" text="cannot convert from Foo to Annotation"/> + <message kind="error" line="17" text="declare @method is only supported at Java 5 compliance level or above"/> + <message kind="error" line="17" text="annotations are only available if source level is 1.5 or greater"/> + <message kind="error" line="17" text="cannot convert from Foo to Annotation"/> + <message kind="error" line="19" text="declare @field is only supported at Java 5 compliance level or above"/> + <message kind="error" line="19" text="annotations are only available if source level is 1.5 or greater"/> + <message kind="error" line="19" text="cannot convert from Foo to Annotation"/> + <message kind="error" line="21" text="declare @constructor is only supported at Java 5 compliance level or above"/> + <message kind="error" line="21" text="annotations are only available if source level is 1.5 or greater"/> + <message kind="error" line="21" text="cannot convert from Foo to Annotation"/> + <message kind="error" line="25" text="annotation type patterns are only supported at Java 5 compliance level or above"/> + <message kind="error" line="27" text="annotation type patterns are only supported at Java 5 compliance level or above"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/compliance" title="java 5 pointcuts and declares at pre-java 5 compliance levels - 1.7"> + <compile files="AJ5FeaturesAtJ14.aj" options="-1.4"> + <message kind="error" line="3" text="the @annotation pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="11" text="the @within pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="13" text="the @withincode pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="5" text="the @this pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="7" text="the @target pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="9" text="the @args pointcut expression is only supported at Java 5 compliance level or above"/> + <message kind="error" line="15" text="declare @type is only supported at Java 5 compliance level or above"/> + <message kind="error" line="15" text="annotations are only available if source level is 1.5 or greater"/> + <message kind="error" line="15" text="Foo is not an annotation type"/> + <message kind="error" line="17" text="declare @method is only supported at Java 5 compliance level or above"/> + <message kind="error" line="17" text="annotations are only available if source level is 1.5 or greater"/> + <message kind="error" line="17" text="Foo is not an annotation type"/> + <message kind="error" line="19" text="declare @field is only supported at Java 5 compliance level or above"/> + <message kind="error" line="19" text="annotations are only available if source level is 1.5 or greater"/> + <message kind="error" line="19" text="Foo is not an annotation type"/> + <message kind="error" line="21" text="declare @constructor is only supported at Java 5 compliance level or above"/> + <message kind="error" line="21" text="annotations are only available if source level is 1.5 or greater"/> + <message kind="error" line="21" text="Foo is not an annotation type"/> + <message kind="error" line="25" text="annotation type patterns are only supported at Java 5 compliance level or above"/> + <message kind="error" line="27" text="annotation type patterns are only supported at Java 5 compliance level or above"/> + </compile> + </ajc-test> + + + <ajc-test dir="bugs150" pr="91114" title="before and after are valid identifiers in classes, part 2"> + <compile files="pr91114.aj"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="78621" title="void field type in pointcut expression"> + <compile files="pr78261.aj"> + <message line="3" kind="error" text="fields cannot have a void type"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="86057" title="overriding final pointcut from super-aspect"> + <compile files="pr86057.aj"> + <message line="9" kind="error" text="can't override final pointcut Base.foo()"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="78707" title="before returning advice not allowed!"> + <compile files="pr78707.aj"> + <message line="3" kind="error" text="Syntax error on token "returning", delete this token"/> + <message line="3" kind="error" text="Syntax error on token "throwing", delete this token"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="104529" title="@SuppressWarnings should suppress"> + <compile files="pr104529.aj" options = "-1.9 -warn:+unchecked"> + <message line="11" kind="warning" text="needs unchecked conversion"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="79523" title="declare warning : foo(str) : ...;"> + <compile files="pr79523.aj"> + <message line="4" kind="warning" text="no match for this type name: str"/> + <message line="4" kind="error" text="bad parameter"/> + <message line="4" kind="error" text="args() pointcut designator cannot be used in declare statement"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="107059" title="parser crashes on call(void (@a *)(..)"> + <compile files="pr107059.aj"> + <message line="3" kind="error" text="Syntax error on token "(", "name pattern" expected"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="107059" title="target(@Foo *)"> + <compile files="pr107059_2.aj" options="-1.9"> + <message kind="error" line="4" text="wildcard type pattern not allowed"></message> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="varargs with type variable"> + <compile files="ParameterizedVarArgMatch.aj" options="-1.9"> + </compile> + </ajc-test> + + + <ajc-test dir="bugs150" pr="108104" title="multiple anonymous inner classes 2"> + <compile files="pr108104.aj" options="-1.9"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="108050" title="signature matching in override scenario"> + <compile files="pr108050.aj" options="-1.9"> + <message kind="warning" line = "2" text="servlet request"></message> + <message kind="warning" line = "7" text="servlet request"></message> + <message kind="warning" line = "21" text="servlet request"></message> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr108425" pr="108245" title="wildcard annotation matching - pr108245"> + <compile files="package1/Bean.java,package2/Bean.java,package2/propertyChanger.java,package3/pr108425.aj" options="-1.9 -Xlint:ignore"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/" pr="108104" title="inner types and type variables"> + <compile files="ShapeCommandMap.java" options="-1.9"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/" pr="107953" title="@AfterThrowing with no formal specified"> + <compile files="pr107953.java" options="-1.9"> + <message kind="error" line="8" text="throwing formal 'RuntimeException' must be declared as a parameter in the advice signature"></message> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr106130" pr="106130" title="test weaving with > 256 locals"> + <compile files="AroundLotsOfVars.java LotsOfVars.java" options="-preserveAllLocals"/> + <run class="LotsOfVars"> + <stdout> + <line text="hello"/> + <line text="2"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr87376" title="structure model npe on type not found"> + <compile files="I.java,NPE.aj" options="-emacssym"> + <message kind="error" line="8" text="I cannot be resolved to a type"/> + <message kind="error" line="10" text="I cannot be resolved to a type"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="83311" title="overriding/polymorphism error on interface method introduction"> + <compile files="pr83311.aj"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="103266" title="NPE on syntax error"> + <compile files="pr103266.aj"> + <message kind="error" line="41" text="ConnectionRequestContext cannot be resolved to a type"/> + <!-- this next message is new in e37 --> + <message kind="error" line="41" text="Type mismatch: cannot convert from new ConnectionRequestContext(){} to WorkerExample.RequestContext"/> + </compile> + </ajc-test> + + <ajc-test title="itd override with no exception clause" dir="bugs150"> + <compile files="pr83377.aj"></compile> + </ajc-test> + + <ajc-test dir="bugs150/pr84260" vm="1.5" title="static import failures"> + <compile files="A.java,I1.java,I2.java" options="-1.9"/> + <run class="I1"> + <stderr> + <line text="static method running"/> + </stderr> + </run> + <run class="I2"> + <stderr> + <line text="static method running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test title="anonymous inner class with method returning type parameter" pr="107898" dir="bugs150"> + <compile files="pr107898.aj" options="-1.9"></compile> + </ajc-test> + + <ajc-test title="matching against Object[]" pr="72668" dir="bugs150"> + <compile files="pr72668.aj" options="-1.9"> + <message kind="error" line="3" text="incompatible return type applying to method-execution(java.lang.Number[] pr72668.getThoseInts())"></message> + <message kind="error" line="10" text="incompatible return type applying to method-execution(java.lang.Number[] pr72668.getThoseInts())"></message> + </compile> + </ajc-test> + + <ajc-test dir="decp" pr="80249" title="Order of types passed to compiler determines weaving behavior"> + <compile files="A.java,B.java,AspectX.java"/> + <run class="B"/> + <compile files="B.java,A.java,AspectX.java"/> + <run class="B"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="99228" vm="1.5" title="ITD of a field into a generic class"> + <compile files="PR99228.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="98320" vm="1.5" title="intertype with nested generic type"> + <compile files="PR98320.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="decs" pr="42743" title="declare soft of runtime exception"> + <compile files="DeclareSoftRuntimeException.aj"> + <message kind="warning" line="3" text="MyRuntimeException will not be softened as it is already a RuntimeException"/> + </compile> + <run class="DeclareSoftRuntimeException"> + <stdout> + <line text="MyRuntimeException"/> + <line text="org.aspectj.lang.SoftException"/> + <line text="MyRuntimeException"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="decs" pr="42743" title="declare soft w. catch block"> + <compile files="VerifyError.aj" options="-Xlint:ignore"> + </compile> + <run class="VerifyError"/> + </ajc-test> + + <ajc-test dir="bugs" pr="61568" title="Various kinds of ambiguous bindings"> + <compile files="AmbiguousBindings.aj"> + <message line="17" text="ambiguous binding of parameter(s) foo across '||' in pointcut"></message> + <message line="19" text="ambiguous binding of parameter(s) foo across '||' in pointcut"></message> + <message line="21" text="ambiguous binding of parameter(s) foo across '||' in pointcut"></message> + <message line="23" text="ambiguous binding of parameter(s) x across '||' in pointcut"></message> + <message line="25" text="ambiguous binding of parameter(s) foo across '||' in pointcut"></message> + </compile> + </ajc-test> + + <ajc-test dir="bugs" pr="61658" title="ambiguous args"> + <compile files="PR61658.java"> + <message line="17" text="ambiguous binding of parameter(s) a, b across '||' in pointcut"></message> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="78021" title="Injecting exception into while loop with break statement causes catch block to be ignored"> + <compile files="PR78021.java"/> + <run class="PR78021"/> + </ajc-test> + + <ajc-test dir="bugs150/pr99089" vm="1.5" pr="99089" title="ArrayIndexOutOfBoundsException - Generics in privileged aspects"> + <compile files="DataClass.java,TracingAspect.java" options="-1.9"/> + <run class="DataClass"> + <stderr> + <line text="before:Length of v=1"/> + <line text="after:Length of v=2"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="bugs150" pr="79554" title="Return in try-block disables catch-block if final-block is present"> + <compile files="PR79554.java"/> + <run class="PR79554"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="82570" title="Weaved code does not include debug lines"> + <compile files="PR82570_1.java"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="83303" title="compiler error when mixing inheritance, overriding and polymorphism"> + <compile files="PR83303.java"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="83563" title="pertypewithin() handing of inner classes (1)"> + <compile files="PR83563_1.java"/> + <run class="PR83563_1"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="83563" title="pertypewithin() handing of inner classes (2)"> + <compile files="PR83563_2.java"/> + <run class="PR83563_2"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="83645" title="pertypewithin({interface}) illegal field modifier"> + <compile files="PR83645.java" options="-Xlint:ignore"/> + <run class="PR83645"/> + </ajc-test> + + <ajc-test dir="bugs150" title="bad asm for enums" vm="1.5"> + <compile files="Rainbow.java" options="-emacssym,-1.9,-Xset:minimalModel=false"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="10461" title="missing name pattern"> + <compile files="PR106461.aj"> + <message kind="error" line="3" text="Syntax error on token "(", "name pattern" expected"/> + <message kind="error" line="5" text="Syntax error on token ")", "name pattern" expected"/> + <message kind="error" line="7" text="Syntax error on token ".", "name pattern" expected"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="106634" title="IllegalStateException unpacking signature of nested parameterized type"> + <compile files="pr106634.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" title="(@Foo *)+ type pattern parse error"> + <compile files="AnnotationPlusPatternParseError.aj" options="-1.9"/> + <!-- next line needs the change for inherited anno matching... --> + <!--compile files="AnnotationPlusPatternParseError.aj" options="-1.9"> + <message kind="warning" line="19"/> + </compile--> + </ajc-test> + + <ajc-test dir="bugs150" pr="80571" title="around advice on interface initializer"> + <compile files="pr80571.aj"> + <message kind="warning" text="The joinpoint 'constructor-call(void pr80571.<init>())' cannot be advised"/> + </compile> + <run class="pr80571"> + <stdout> + <line text="before"/> + <line text="after"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" pr="78314" title="good error message for unmatched member syntax"> + <compile files="pr78314.aj" options="-1.9"> + <message kind="error" line="5" text="Syntax error on token "foo", no accurate correction available"/> + </compile> + <compile files="pr78314.aj"> + <message kind="error" line="5" text="Syntax error on token "foo", no accurate correction available"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="108377" title="itd field access inside itd method"> + <compile files="pr108377.aj"/> + <run class="pr108377"/> + </ajc-test> + + <ajc-test dir="bugs150/pr108054" pr="108054" title="type variable with type variable bound"> + <compile files="pr108054.aj" options="-1.9"/> + <compile files="ISequence.java,ICounter.java,ASequence.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr108370" pr="108370" title="switch on enum inside ITD method"> + <compile files="et/Q.java" options="-1.9"/> + <compile files="EnumTest.aj" options="-1.9 -inpath et"/> + <run class="EnumTest"> + <stdout> + <line text="B!"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" pr="95992" title="inner type of generic interface reference from parameterized type"> + <compile files="pr95992.aj" options="-1.9"/> + </ajc-test> + + + <ajc-test dir="bugs150" pr="104024" title="inner class passed as argument to varargs method"> + <compile files="pr104024.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="107858" title="inlined field access in proceed call"> + <compile files="pr107858.aj" options="-1.9"> + <message kind="error" line="9" text="too many arguments to proceed, expected 0"></message> + <message kind="error" line="10" text="too many arguments to proceed, expected 0"></message> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr71159" pr="71159" title="visibility in signature matching with overrides - 1"> + <compile files="pr71159.aj"> + <message kind="warning" line="26" text="should match"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr71159" pr="71159" title="visibility in signature matching with overrides - 2"> + <compile files="PrivateITD.aj"> + <message kind="warning" line="28" text="should match"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr71159" pr="71159" title="visibility in signature matching with overrides - 3"> + <compile files="pkg1/A.java,pkg1/B.java,pkg1/C.java,pkg2/ITDInDiffPackage.aj"> + <message kind="warning" line="10" text="should match"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="59196" title="args generated correctly for advice execution join point"> + <compile files="pr59196.aj" options="-XnoInline -1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="74048" title="no unused warnings on aspect types"> + <compile files="pr74048.aj" options="-warn:unusedPrivate"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="59397" title="synthetic arguments on itd cons are not used in matching"> + <compile files="pr59397.aj"> + <message line="6" kind="warning" text="should match"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="108602" title="parse generic type signature with parameterized type in interface"> + <compile files="pr108602.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="105479" title="declare parents introducing override with covariance"> + <compile files="pr105479.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="105479" title="override and covariance with decp - runtime"> + <compile files="pr105479part2.aj" options="-1.9"/> + <run class="pr105479part2"> + <stdout> + <line text="in Test.hashCode()"/> + <line text="in Test.hashCode()"/> + <line text="id"/> + <line text="in Test.hashCode()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr105479/case1" pr="105479" title="override and covariance with decp - runtime separate files"> + <compile files="ReturnTypeTest.aj,ReturnTypeTester.java,Driver.java" options="-1.9"/> + <run class="Driver"> + <stdout> + <line text="in Test.hashCode()"/> + <line text="in Test.hashCode()"/> + <line text="id"/> + <line text="in Test.hashCode()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr105479/case2" pr="105479" title="override and covariance with decp - binary weaving"> + <compile files="ReturnTypeTest.java" outjar="jar1.jar" options="-1.9 -Xlint:ignore"/> + <compile files="ReturnTypeTester.java" outjar="jar2.jar" options="-1.9"/> + <compile inpath="jar1.jar;jar2.jar" options="-1.9"/> + <run class="ReturnTypeTester"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="102212" title="abstract synchronized itdms not detected"> + <compile files="pr102212.aj"> + <message line="7" kind="error" text="The abstract method _abstract in type Parent can only set a visibility modifier, one of public or protected"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="102212" title="synchronized itd interface methods"> + <compile files="SynchronizedInterfaceMethods.aj" options="-1.9"> + </compile> + <run class="SynchronizedInterfaceMethods"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="101606" title="unused private pointcuts"> + <compile files="pr101606.aj" options="-warn:unusedPrivate"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr99125" pr="99125" title="itd interface method already existing on interface"> + <compile files="p/pr99125.aj,p/I.java,p/J.java" options="-1.9"> + </compile> + <compile files="Aspects.aj" options="-inpath p"/> + <run class="p.pr99125"/> + <compile files="p2/pr99125.aj,p/I.java,p/J.java"/> <!-- actually in package p, introduces incompatible change --> + <compile files="Aspects.aj" options="-inpath p"> + <message kind="error" line="7" text="inter-type declaration from X conflicts with existing member"/> + <!-- 275032 - new error at affected member location too --> + <message kind="error" line="10" text="inter-type declaration from X conflicts with existing member"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr87530" pr="87530" title="final itd methods on interfaces"> + <compile files="FinalITDMOnInterface.aj"> + <message kind="error" line="12" text="Cannot override the final method from A.TestInterface"></message> + </compile> + <compile files="FinalITDMOnInterface2.aj"> + <!--message kind="error" line="8" text="Cannot override the final method from A.TestInterface"></message--> + <message kind="error" line="8" text="can't override final void A$TestInterface.m()"></message> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="108818" title="can't override private pointcut in abstract aspect"> + <compile files="PrivatePointcutOverriding.aj"> + <message kind="warning" line="19" text="matched join point from super advice"/> + <message kind="warning" line="21" text="matched join point from sub advice"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="108816" title="advising cflow advice execution"> + <compile files="pr108816.aj" > + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr108902" pr="108902" title="no type mismatch on generic types in itds"> + <compile files="Subject.java,Observer.java,ObserverProtocol.aj" > + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="108903" title="super call in ITD"> + <compile files="pr108903.aj" > + <message kind="error" line="14" text="The method print() is undefined for the type Object"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="109042" title="no unused parameter warnings for synthetic advice args"> + <compile files="pr109042.aj" options="-warn:+unusedArgument -warn:+unusedPrivate -warn:+unusedImport -1.9"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="109486" title="Internal compiler error (ClassParser.java:242)"> + <compile files="PR109486.java" > + <message kind="error" line="1" text="The class PR109486 can be either abstract or final, not both"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="109124" title="no verify error with set on inner type"> + <compile files="VerifyErrorOnSet.aj" options="-1.9" > + </compile> + <run class="test.VerifyErrorOnSet"/> + <compile files="pr106874.aj" options="-1.9" > + </compile> + <run class="pr106874"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="108826" title="cant find type error with generic return type or parameter"> + <compile files="pr108826.aj" options="-1.9 -emacssym" > + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="105181" title="no verify error on generic collection member access"> + <compile files="pr105181.aj" options="-1.9"> + </compile> + <run class="pr105181"/> + </ajc-test> + + <ajc-test dir="bugs150/pr108903" pr="108903" title="super call in ITD - part 2"> + <compile files="com/designpattern/decorator/HeaderDecorator.aj,com/designpattern/decorator/Main.java,com/designpattern/decorator/Order.java,com/designpattern/decorator/OrderDecorator.aj,com/designpattern/decorator/SalesOrder.java" options="-1.9" > + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr103740" pr="103740" title="Compiler failure on at_annotation"> + <compile files="AroundAdvice.aj" options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Join point 'method-execution(void C.m1())' in Type 'C' (AroundAdvice.aj:12) advised by before advice from 'ErrorHandling' (AroundAdvice.aj:8)"/> + <message kind="weave" text="Join point 'method-execution(void C.m3())' in Type 'C' (AroundAdvice.aj:14) advised by before advice from 'ErrorHandling' (AroundAdvice.aj:8)"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr106554" pr="106554" title="Problem in staticinitialization with pertypewithin aspect"> + <compile files="A.aj" options="-showWeaveInfo"> + <message kind="weave" text="Join point 'staticinitialization(void A.<clinit>())' in Type 'A' (A.aj:1) advised by before advice from 'StopsInit' (A.aj:21)"/> + </compile> + <run class="A"> + <stdout> + <line text="test = 1"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/SimpleInsuranceFailure" title="raw and generic type conversion with itd cons"> + <compile files="" options=" -emacssym, -sourceroots ." > + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="@annotation binding with around advice"> + <compile files="AnnotationBinding.aj" options="-1.9"/> + <run class="AnnotationBinding"/> + </ajc-test> + + <ajc-test dir="bugs150" title="declare parents on a missing type"> + <compile files="Pr76374.aj" options="-1.9"> + <message kind="warning" line="3" text="no match for this type name"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="parameterized generic methods"> + <compile files="Pr109283.aj" options="-1.9 -warn:indirectStatic"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="call join points in anonymous inner classes"> + <compile files="pr104229.aj" options="-1.9"> + <message kind="warning" line="54" text="bingo"/> + <message kind="warning" line="115" text="bingo"/> + <message kind="warning" line="130" text="bingo"/> + </compile> + <run class="pr104229"> + <stdout> + <line text="call match class pr104229"/> + <line text="OK it worked!"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" title="default impl of Runnable"> + <compile files="pr88900.aj" options="-Xdev:Pinpoint"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="array clone call join points in 1.4 vs 1.3"> + <compile files="pr102933.aj" options="-1.3"> + <message kind="warning" line="7" text="a call within pr102933"/> + </compile> + <compile files="pr102933.aj" options="-1.4"> + <message kind="warning" line="7" text="a call within pr102933"/> + </compile> + <compile files="pr102933.aj" options="-1.9"> + <message kind="warning" line="7" text="a call within pr102933"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" pr="100195" title="debug info in around advice inlining"> + <compile files="pr100195.aj"> + </compile> + <run class="pr100195"/> + </ajc-test> + + <ajc-test dir="bugs150" title="weaveinfo message for declare at method on an ITDd method"> + <compile files="pr113073.java" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Type 'C' (pr113073.java) has intertyped method from 'D' (pr113073.java:'void C.anotherMethod()')"/> + <message kind="weave" text="'public void C.anotherMethod()' (pr113073.java) is annotated with @Annotation method annotation from 'B' (pr113073.java:3)"/> + <message kind="weave" text="Type 'C' (pr113073.java) has intertyped method from 'D' (pr113073.java:'void C.anotherMethod(java.lang.String)')"/> + <message kind="weave" text="'public void C.anotherMethod(String)' (pr113073.java) is annotated with @Annotation method annotation from 'B' (pr113073.java:3)"/> + <message kind="weave" text="Type 'C' (pr113073.java) has intertyped constructor from 'D' (pr113073.java:'void C."/> + <message kind="weave" text="'public void C.new(String)' (pr113073.java) is annotated with @Annotation constructor annotation from 'B' (pr113073.java:4)"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr113447" title="no verify error with two this pcds"> + <compile files="PR113447.java"> + </compile> + <run class="PR113447"/> + </ajc-test> + + <ajc-test dir="bugs150/pr113447" title="no verify error with two at this pcds"> + <compile files="PR113447a.java" options="-1.9"> + </compile> + <run class="PR113447a"/> + </ajc-test> + + <ajc-test dir="bugs150/pr113447" title="no verify error with at within pcds"> + <compile files="PR113447b.java" options="-1.9"> + </compile> + <run class="PR113447b"/> + </ajc-test> + + <ajc-test dir="bugs150/pr113447" title="no verify error with at withincode pcds"> + <compile files="PR113447c.java" options="-1.9"> + </compile> + <run class="PR113447c"/> + </ajc-test> + + <ajc-test dir="bugs150/pr113447" title="no verify error with at annotation pcds"> + <compile files="PR113447d.java" options="-1.9"> + </compile> + <run class="PR113447d"/> + </ajc-test> + + <ajc-test dir="bugs150/pr113447" title="no verify error with two args pcds"> + <compile files="PR113447e.java" options="-1.9"> + </compile> + <run class="PR113447e"/> + </ajc-test> + + <ajc-test dir="bugs150" title="no StackOverflowError with circular pcd in generic aspect"> + <compile files="pr115235.aj" options="-1.9"> + <message kind="warning" line="3" text="advice defined in GenericAbstractAspect has not been applied [Xlint:adviceDidNotMatch]"/> + <message kind="error" text="circular pointcut declaration involving: pc()"/> + <message kind="error" line="20" text="circular pointcut declaration involving: pc2()"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="no StackOverflowError with circular pcd in generic aspect - 2"> + <compile files="pr115235b.aj" options="-1.9"> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr115252" title="xlint message for improper exact annotation type"> + <compile files="ExactAnnotationTypePattern.java" options="-1.9"> + <message kind="warning" line="20" text="field blah"/> + <message kind="warning" line="28" text="does not match because annotation @TypeAnnotation has @Target{ElementType.TYPE} [Xlint:unmatchedTargetKind]"/> + <message kind="warning" line="37" text="does not match because annotation @FieldAnnotation has @Target{ElementType.FIELD} [Xlint:unmatchedTargetKind]"/> + <message kind="warning" line="46" text="does not match because annotation @MethodAnnotation has @Target{ElementType.METHOD} [Xlint:unmatchedTargetKind]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr115252" title="xlint message for improper annotation type inside OR"> + <compile files="OrTypePattern.java" options="-1.9"> + <message kind="warning" line="26" text="does not match because annotation @FieldAnnotation has @Target{ElementType.FIELD} [Xlint:unmatchedTargetKind]"/> + <message kind="warning" line="31" text="does not match because annotation @TypeAnnotation has @Target{ElementType.TYPE} [Xlint:unmatchedTargetKind]"/> + <message kind="warning" line="31" text="does not match because annotation @FieldAnnotation has @Target{ElementType.FIELD} [Xlint:unmatchedTargetKind]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr115252" title="xlint message for improper annotation type inside AND"> + <compile files="AndTypePattern.java" options="-1.9"> + <message kind="warning" line="23" text="does not match because annotation @FieldAnnotation has @Target{ElementType.FIELD} [Xlint:unmatchedTargetKind]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr115252" title="xlint message for improper annotated return type"> + <compile files="AnnotationReturnType.java" options="-1.9"> + <!-- warnings coming from matching pointcuts and corresponding declare warnings --> + <message kind="warning" line="12" text="(@TypeAnnotation *) *(..)"/> + <message kind="warning" line="12" text="(@(TypeAnnotation || MethodAnnotation) *) *(..)"/> + <!-- xlint warnings that were put in as part of fix for pr115252 --> + <message kind="warning" line="32" text="does not match because annotation @MethodAnnotation has @Target{ElementType.METHOD} [Xlint:unmatchedTargetKind]"/> + <message kind="warning" line="37" text="does not match because annotation @MethodAnnotation has @Target{ElementType.METHOD} [Xlint:unmatchedTargetKind]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr115252" title="xlint message for improper annotated declaring type"> + <compile files="AnnotationDeclaringType.java" options="-1.9"> + <!-- warning coming from matching pointcuts and corresponding declare warnings --> + <message kind="warning" line="13" text="* (@TypeAnnotation *).*(..)"/> + <!-- xlint warning that was put in as part of fix for pr115252 --> + <message kind="warning" line="27" text="does not match because annotation @MethodAnnotation has @Target{ElementType.METHOD} [Xlint:unmatchedTargetKind]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr115252" title="xlint message for improper annotated parameter type"> + <compile files="AnnotationParameterType.java" options="-1.9"> + <!-- warning coming from matching pointcuts and corresponding declare warnings --> + <message kind="warning" line="12" text="* *(@TypeAnnotation *)"/> + <!-- xlint warning that was put in as part of fix for pr115252 --> + <message kind="warning" line="31" text="does not match because annotation @MethodAnnotation has @Target{ElementType.METHOD} [Xlint:unmatchedTargetKind]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr115252" title="xlint message for improper annotated throws pattern"> + <compile files="AnnotationThrowsPattern.java" options="-1.9"> + <!-- warnings coming from matching pointcuts and corresponding declare warnings --> + <message kind="warning" line="12" text="(* *.*(..) throws (@TypeAnnotation *))"/> + <message kind="warning" line="12" text="* *.*(..) throws !(@MethodAnnotation *)"/> + <message kind="warning" line="14" text="(* *.*(..) throws !(@TypeAnnotation *))"/> + <message kind="warning" line="14" text="* *.*(..) throws !(@MethodAnnotation *)"/> + <!-- xlint warnings that were put in as part of fix for pr115252 --> + <message kind="warning" line="40" text="does not match because annotation @MethodAnnotation has @Target{ElementType.METHOD} [Xlint:unmatchedTargetKind]"/> + <message kind="warning" line="46" text="does not match because annotation @MethodAnnotation has @Target{ElementType.METHOD} [Xlint:unmatchedTargetKind]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr115252" title="xlint message for more than one improper annotated parameter type"> + <compile files="MoreThanOneTargetAnnotation.java" options="-1.9"> + <!-- xlint warning that was put in as part of fix for pr115252 --> + <message kind="warning" line="28" text="does not match because annotation @MethodAndFieldAnnotation has @Target{ElementType.FIELD,ElementType.METHOD} [Xlint:unmatchedTargetKind]"/> + <message kind="warning" line="38" text="does not match because annotation @TypeAndMethodAnnotation has @Target{ElementType.METHOD,ElementType.TYPE} [Xlint:unmatchedTargetKind]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr119019" title="no NPE when inaccessible method is called within itd"> + <compile files="bar/TargetITDClass.java,foo/ITDWithACall.aj"/> + <run class="foo.ITDWithACall"/> + </ajc-test> + + <ajc-test dir="bugs150" title="no NPE with or pointcut and more than one args"> + <compile files="PR118149.aj"/> + </ajc-test> + + <ajc-test dir="bugs150" title="no StringOutOfBoundsException with generic inner aspects"> + <compile files="PR119543.java" options="-1.9"> + <message kind="warning" line="8" text="advice defined in PR119543$A has not been applied [Xlint:adviceDidNotMatch]"/> + </compile> + </ajc-test> + + <!-- ============================================================================ --> + <!-- ============================================================================ --> + + <!-- atOverride tests with ITDs --> + + <ajc-test dir="java5/generics/itds" pr="106630" title="atOverride used with ITDs"> + <compile files="AtOverride.aj" options="-1.9"/> + </ajc-test> + <ajc-test dir="java5/generics/itds" pr="106630" title="atOverride used with ITDs - 1"> + <compile files="AtOverride1.aj" options="-1.9"> + <message kind="error" line="9" text="The method method() of type Child must override a superclass method"/> + </compile> + </ajc-test> + <ajc-test dir="java5/generics/itds" pr="106630" title="atOverride used with ITDs - 2"> + <compile files="AtOverride2.aj" options="-1.9"/> + </ajc-test> + <ajc-test dir="java5/generics/itds" pr="106630" title="atOverride used with ITDs - 3"> + <compile files="AtOverride3.aj" options="-1.9"/> + </ajc-test> + <ajc-test dir="java5/generics/itds" pr="106630" title="atOverride used with ITDs - 4"> + <compile files="AtOverride4.aj" options="-1.9"/> + </ajc-test> + <ajc-test dir="java5/generics/itds" pr="106630" title="atOverride used with ITDs - 5"> + <compile files="AtOverride5.aj" options="-1.9"> + <message kind="error" line="11" text="The method method() of type Child must override a superclass method"/> + </compile> + </ajc-test> + <ajc-test dir="java5/generics/itds" pr="106630" title="atOverride used with ITDs - 6"> + <compile files="AtOverride6.aj" options="-1.9"/> + </ajc-test> + <ajc-test dir="java5/generics/itds" pr="106630" title="atOverride used with ITDs - 7"> + <compile files="AtOverride7.aj" options="-1.9"/> + </ajc-test> + + <!-- end of atOverride tests with ITDs --> + + <ajc-test dir="../docs/dist/doc/examples/introduction" title="introduction sample" vm="1.5"> + <compile files="CloneablePoint.java,ComparablePoint.java,HashablePoint.java,Point.java" options="-1.9 -Xlint:ignore"/> + </ajc-test> + + <ajc-test dir="java5/varargs" title="varargs in constructor sig" vm="1.5"> + <compile files="Pr88652.aj" options="-1.9"> + <message kind="warning" line="8" text="should match"/> + <message kind="warning" line="9" text="should match"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/varargs" title="Varargs with .. in pointcut" vm="1.5"> + <compile files="pr93356.aj" options="-1.9"> + <message kind="warning" line="5" text="a"/> + <message kind="warning" line="5" text="b"/> + <message kind="warning" line="5" text="c"/> + <message kind="warning" line="5" text="d"/> + <message kind="warning" line="5" text="e"/> + <message kind="warning" line="5" text="k"/> + <message kind="warning" line="5" text="l"/> + + <message kind="warning" line="4" text="f"/> + <message kind="warning" line="4" text="g"/> + <message kind="warning" line="4" text="h"/> + <message kind="warning" line="4" text="i"/> + <message kind="warning" line="4" text="j"/> + + <message kind="warning" line="7" text="f"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/varargs" title="star varargs pattern" vm="1.5"> + <compile files="StarVarargsPattern.aj" options="-1.9"> + <message kind="warning" line="5" text="you used a varargs signature"/> + <message kind="warning" line="7" text="you used a varargs signature"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations" title="invalid cons syntax" vm="1.5"> + <compile files="SyntaxError.aj" options="-1.9"> + <message kind="error" line="3" text="Syntax error on token "new", "method name (not constructor)" expected"/> + </compile> + </ajc-test> + + <!-- hasmethod / hasfield tests --> + + <ajc-test title="declare parents : hasmethod(..) - 1" dir="hasmember"> + <compile files="HasMethod.aj"> + <message kind="error" line="5" text="the type pattern hasmethod(* print(..)) can only be used when the -XhasMember option is set"/> + </compile> + </ajc-test> + + <ajc-test title="declare parents : hasmethod(..) - 1" dir="hasmember"> + <compile files="HasMethod.aj" options="-XhasMember"> + </compile> + <run class="HasMethod"></run> + </ajc-test> + + <ajc-test title="declare parents : hasmethod(..) - 2" dir="hasmember"> + <compile files="HasMethodInherited.aj" options="-XhasMember"> + </compile> + <run class="HasMethodInherited"></run> + </ajc-test> + + <ajc-test title="declare parents : hasmethod(..) - 3" dir="hasmember"> + <compile files="HasPrivateMethodInherited.aj" options="-XhasMember"> + </compile> + <run class="HasPrivateMethodInherited"></run> + </ajc-test> + + <ajc-test title="declare parents : hasmethod(..) - 4" dir="hasmember"> + <compile files="HasMethodViaITD.aj" options="-XhasMember"> + <message kind="warning" line="15" text="hasmethod matched on ITD ok"/> + </compile> + </ajc-test> + + <ajc-test title="declare parents : hasfield(..) - 1" dir="hasmember"> + <compile files="HasField.aj" options="-XhasMember"> + </compile> + <run class="HasField"></run> + </ajc-test> + + <ajc-test title="declare parents : hasfield(..) - 2" dir="hasmember"> + <compile files="HasFieldInherited.aj" options="-XhasMember"> + </compile> + <run class="HasFieldInherited"></run> + </ajc-test> + + <ajc-test title="declare parents : hasfield(..) - 3" dir="hasmember"> + <compile files="HasPrivateFieldInherited.aj" options="-XhasMember"> + </compile> + <run class="HasPrivateFieldInherited"></run> + </ajc-test> + + <!-- Annotation binding tests --> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="call annotation binding 1"> + <compile files="CallAnnBinding.aj" options="-1.9"/> + <run class="CallAnnBinding"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="call annotation binding 2"> + <compile files="CallAnnBinding2.aj" options="-1.9"/> + <run class="CallAnnBinding2"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="call annotation binding 3"> + <compile files="CallAnnBinding3.aj" options="-1.9"/> + <run class="CallAnnBinding3"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="call annotation binding 4"> + <compile files="CallAnnBinding4.aj" options="-1.9"/> + <run class="CallAnnBinding4"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="call annotation binding 5"> + <compile files="CallAnnBinding5.aj" options="-1.9"/> + <run class="CallAnnBinding5"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="call annotation binding 6"> + <compile files="CallAnnBinding6.aj" options="-1.9"/> + <run class="CallAnnBinding6"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="call annotation binding 7"> + <compile files="CallAnnBinding7.aj" options="-1.9"/> + <run class="CallAnnBinding7"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@target annotation binding 1"> + <compile files="AtTarget1.aj" options="-1.9"/> + <run class="AtTarget1"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@target annotation binding 2"> + <compile files="AtTarget2.aj" options="-1.9"/> + <run class="AtTarget2"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@target annotation binding 3"> + <compile files="AtTarget3.aj" options="-1.9"/> + <run class="AtTarget3"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@target annotation binding 4"> + <compile files="AtTarget4.aj" options="-1.9"/> + <run class="AtTarget4"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding/usingPackageNames" vm="1.5" title="@target annotation binding 5"> + <compile files="MyAspect.aj,MyAnnotation.java,MyClass.java" options="-1.9"/> + <run class="test.MyClass"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@this annotation binding 1"> + <compile files="AtThis1.aj" options="-1.9"/> + <run class="AtThis1"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@this annotation binding 2"> + <compile files="AtThis2.aj" options="-1.9"/> + <run class="AtThis2"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@this annotation binding 3"> + <compile files="AtThis3.aj" options="-1.9"/> + <run class="AtThis3"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@this annotation binding 4"> + <compile files="AtThis4.aj" options="-1.9"/> + <run class="AtThis4"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@this annotation binding 5"> + <compile files="AtThis5.aj" options="-1.9"/> + <run class="AtThis5"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@args annotation binding 1"> + <compile files="AtArgs1.aj" options="-1.9"/> + <run class="AtArgs1"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@args annotation binding 2"> + <compile files="AtArgs2.aj" options="-1.9"/> + <run class="AtArgs2"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@args annotation binding 3"> + <compile files="AtArgs3.aj" options="-1.9"/> + <run class="AtArgs3"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@args annotation binding 4"> + <compile files="AtArgs4.aj" options="-1.9"/> + <run class="AtArgs4"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@args annotation binding 5"> + <compile files="AtArgs5.aj" options="-1.9"/> + <run class="AtArgs5"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="execution and @annotation"> + <compile files="ExecutionAnnBinding1.aj" options="-1.9"/> + <run class="ExecutionAnnBinding1"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="set and @annotation"> + <compile files="FieldAnnBinding1.aj" options="-1.9"/> + <run class="FieldAnnBinding1"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="get and @annotation"> + <compile files="FieldAnnBinding2.aj" options="-1.9"/> + <run class="FieldAnnBinding2"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="get and @annotation with arrays"> + <compile files="FieldAnnBinding3.aj" options="-1.9"/> + <run class="FieldAnnBinding3"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="cons call and @annotation"> + <compile files="CtorAnnBinding1.aj" options="-1.9"/> + <run class="CtorAnnBinding1"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="cons exe and @annotation"> + <compile files="CtorAnnBinding2.aj" options="-1.9"/> + <run class="CtorAnnBinding2"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="staticinit and @annotation"> + <compile files="StaticInitBinding.aj" options="-1.9"/> + <run class="StaticInitBinding"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="preinit and @annotation"> + <compile files="PreInitBinding.aj" options="-1.9"/> + <run class="PreInitBinding"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="init and @annotation"> + <compile files="InitBinding.aj" options="-1.9"/> + <run class="InitBinding"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="adviceexecution and @annotation"> + <compile files="AdviceExecBinding.aj" options="-1.9"/> + <run class="AdviceExecBinding"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="handler and @annotation"> + <compile files="HandlerBinding.aj" options="-1.9"/> + <run class="HandlerBinding"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@withincode() and call(* println(..))"> + <compile files="WithinCodeBinding1.aj" options="-1.9"/> + <run class="WithinCodeBinding1"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@within"> + <compile files="WithinBinding1.aj" options="-1.9"/> + <run class="WithinBinding1"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="@within - multiple types"> + <compile files="WithinBinding2.aj" options="-1.9"/> + <run class="WithinBinding2"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding/complexExample" vm="1.5" title="packages and no binding"> + <compile files="A.java,B.java,Color.java,X.java" options="-1.9"/> + <run class="a.b.c.A"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding/complexExample" vm="1.5" title="packages and binding"> + <compile files="A.java,B.java,Color.java,X2.java" options="-1.9"/> + <run class="a.b.c.A"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" vm="1.5" title="binding with static methods"> + <compile files="StaticMethods.java" options="-1.9"/> + <run class="StaticMethods"/> + </ajc-test> + + <ajc-test dir="java5/annotations" vm="1.5" title="annotation matching on call"> + <weave classesFiles="AnnotatedType.java,SimpleAnnotation.java,SimpleAnnotation2.java" + aspectsFiles="AnnotationAspect02.aj" + options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'AnnotatedType' (AnnotatedType.java:3) advised by before advice from 'AnnotationAspect02' (aspects.jar!AnnotationAspect02.class:4(from AnnotationAspect02.aj))"/> + <message kind="weave" text="Type 'AnnotatedType' (AnnotatedType.java:3) advised by before advice from 'AnnotationAspect02' (aspects.jar!AnnotationAspect02.class:2(from AnnotationAspect02.aj))"/> + <message kind="weave" text="Type 'AnnotatedType' (AnnotatedType.java:4) advised by before advice from 'AnnotationAspect02' (aspects.jar!AnnotationAspect02.class:4(from AnnotationAspect02.aj))"/> + </weave> + </ajc-test> + + <ajc-test dir="java5/annotations" vm="1.5" title="at annotation matching"> + <weave classesFiles="AnnotatedType.java,SimpleAnnotation.java,SimpleAnnotation2.java" + aspectsFiles="AnnotationAspect03.aj" + options="-1.9,-showWeaveInfo"> + <message kind="warning" line="8" text="@annotation matched here"/> + </weave> + </ajc-test> + + <ajc-test dir="java5/annotations/within_code" vm="1.5" title="annotations and within(code)"> + <weave classesFiles="TestingAnnotations.java" + aspectsFiles="WithinAndWithinCodeTests.java" + options="-1.9,-showWeaveInfo"> + <message kind="warning" line="31" text="@within match on non-inherited annotation"/> + <message kind="warning" line="39" text="@within match on non-inherited annotation"/> + <message kind="warning" line="39" text="@within match on inheritable annotation"/> + <message kind="warning" line="43" text="@within match on inheritable annotation"/> + <message kind="warning" line="32" text="@withincode match"/> + </weave> + </ajc-test> + + <ajc-test dir="java5/annotations/within" vm="1.5" title="annotations and within"> + <weave classesFiles="PlainWithin.java" + aspectsFiles="PlainWithinTests.java" + options="-1.9,-showWeaveInfo"> + <message kind="warning" line="21" text="positive within match on annotation"/> + <message kind="warning" line="25" text="negative within match on annotation"/> + </weave> + </ajc-test> + + <ajc-test dir="java5/annotations/thisOrtarget" vm="1.5" title="must have runtime retention"> + <compile options="-1.9" files="NotRuntimeRetention.aj"> + <message kind="error" line="20" text="Annotation type MySourceAnnotation does not have runtime retention"/> + <message kind="error" line="21" text="Annotation type MyClassAnnotation does not have runtime retention"/> + <message kind="error" line="22" text="Annotation type MyAnnotation does not have runtime retention"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/thisOrtarget" vm="1.5" title="inheritable or not"> + <compile options="-1.9" files="TestingAnnotations.java,ThisOrTargetTests.aj"> + </compile> + <run class="TestingAnnotations"/> + </ajc-test> + + <ajc-test dir="java5/annotations/thisOrtarget" vm="1.5" title="use of @this/target in deow"> + <compile options="-1.9" files="TestingAnnotations.java,DeclareEoW.java"> + <message kind="error" line="3" text="this() pointcut designator cannot be used in declare statement"/> + <message kind="error" line="5" text="target() pointcut designator cannot be used in declare statement"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/args" vm="1.5" title="@args tests"> + <compile options="-1.9" files="TestingArgsAnnotations.java,AtArgsAspect.java"> + </compile> + <run class="TestingArgsAnnotations"/> + </ajc-test> + + <ajc-test dir="java5/annotations/args" vm="1.5" title="use of @args in deow"> + <compile options="-1.9" files="TestingArgsAnnotations.java,DeclareEoW.java"> + <message kind="error" line="3" text="args() pointcut designator cannot be used in declare statement"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations" vm="1.5" title="compiling an annotation"> + <compile options="-1.9" files="SimpleAnnotation.java"> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations" vm="1.5" title="compiling annotated file"> + <compile options="-1.9" files="SimpleAnnotation.java,AnnotatedType.java"> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/within" vm="1.5" title="annotations and within (src)"> + <compile files="PlainWithin.java,PlainWithinTests.java" + aspectsFiles="PlainWithinTests.java" + options="-1.9"> + <message kind="warning" line="21" text="positive within match on annotation"/> + <message kind="warning" line="25" text="negative within match on annotation"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/attarget" vm="1.5" title="losing annotations..."> + <compile options="-1.9" files="Program.java,AtTargetAspect.java"> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations" vm="1.5" title="no itds on annotation types"> + <compile files="AnnotatedType.java,SimpleAnnotation.java,SimpleAnnotation2.java,AnnotationAspect01.aj" + options="-1.9"> + <message kind="error" line="4" text="can't make inter-type constructor declarations"/> + <message kind="error" line="8" text="can't make inter-type method declarations"/> + <message kind="error" line="13" text="can't make inter-type field declarations"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations" vm="1.5" title="no declare parents on annotation types"> + <compile files="AnnotatedType.java,SimpleAnnotation.java,SimpleAnnotation2.java,AnnotationAspect04.aj" + options="-1.9"> + <message kind="error" line="7" text="can't use declare parents to alter supertype of annotation type SimpleAnnotation"/> + <message kind="error" line="10" text="can't use declare parents to make 'java.lang.annotation.Annotation' the parent of type"/> + <message kind="error" line="4" text="can't use declare parents to make annotation type SimpleAnnotation implement an interface"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations" vm="1.5" title="declare parents wildcards matching annotation types"> + <compile files="AnnotatedType.java,SimpleAnnotation.java,SimpleAnnotation2.java,AnnotationAspect05.aj" + options="-1.9"> + <message kind="warning" line="4" text="annotation type SimpleAnnotation2 matches a declare parents type pattern but is being ignored"/> + <message kind="warning" line="4" text="annotation type SimpleAnnotation matches a declare parents type pattern but is being ignored"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/binding/complexExample" vm="1.5" title="annotated any pattern"> + <compile files="A.java,B.java,C.java,Color.java,X3.java" + options="-1.9"> + </compile> + <run class="g.h.i.C"/> + <run class="a.b.c.A"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding/complexExample" vm="1.5" title="annotation not imported"> + <compile files="A.java,B.java,C.java,Color.java,X4.java" + options="-1.9"> + <message kind="warning" line="6" text="no match for this type name: Color"/> + </compile> + <run class="a.b.c.A"/> + </ajc-test> + + <ajc-test dir="java5/annotations/itds" vm="1.5" title="annotated public itds"> + <compile files="AtItd2.aj" options="-1.9"/> + <run class="AtItd2"/> + </ajc-test> + + <ajc-test dir="java5/annotations/itds" vm="1.5" title="annotated public itds - values"> + <compile files="AtItd3.aj" options="-1.9"/> + <run class="AtItd3"/> + </ajc-test> + + <ajc-test dir="java5/annotations/itds" vm="1.5" title="annotated public itds - multiple complex annotations"> + <compile files="AtItd4.aj" options="-1.9"/> + <run class="AtItd4"/> + </ajc-test> + + + <ajc-test dir="java5/annotations/itds" vm="1.5" title="nasty annotation and itds test"> + <compile files="AnnotationsAndITDs.aj" options="-1.9"> + <!-- first two are ITCs, second two are ITCs annotated via declare @ctor, third is default ctor --> + <message kind="warning" line="17" text="execution(@SomeAnnotation ...new(..)"/> + <message kind="warning" line="20" text="execution(@SomeAnnotation ...new(..)"/> + <message kind="warning" line="45" text="execution(@SomeAnnotation ...new(..)"/> + <message kind="warning" line="46" text="execution(@SomeAnnotation ...new(..)"/> + <message kind="warning" line="180" text="execution(@SomeAnnotation ...new(..)"/> + + <!-- first four are fields annotated via declare, last two are directly annotated ITDs --> + <message kind="warning" line="59" text="set(@SomeAnnotation...)"/> + <message kind="warning" line="60" text="set(@SomeAnnotation...)"/> + <message kind="warning" line="70" text="set(@SomeAnnotation...)"/> + <message kind="warning" line="71" text="set(@SomeAnnotation...)"/> + <message kind="warning" line="76" text="set(@SomeAnnotation...)"/> + <message kind="warning" line="77" text="set(@SomeAnnotation...)"/> + + <!-- annotations added via declare --> + <message kind="warning" line="175" text="si(@SomeAnnotation...)"/> + <message kind="warning" line="180" text="si(@SomeAnnotation...)"/> + + <message kind="warning" line="25" text="execution(@SomeAnnotation ...)"/> + <message kind="warning" line="28" text="execution(@SomeAnnotation ...)"/> + <message kind="warning" line="52" text="execution(@SomeAnnotation ...)"/> + <message kind="warning" line="53" text="execution(@SomeAnnotation ...)"/> + <!--message kind="warning" line="70" text="set(@SomeAnnotation...)"/> + <message kind="warning" line="71" text="set(@SomeAnnotation...)"/--> + </compile> + <run class="AnnotationsAndITDs"> + <stderr> + <line text="@type java.lang.System (AnnotationsAndITDs.aj:0)"/> + <line text="hello AnnotationsAndITDs (AnnotationsAndITDs.aj:17)"/> + <line text="goodbye java.lang.String (AnnotationsAndITDs.aj:20)"/> + <line text="goodbye java.lang.String (AnnotationsAndITDs.aj:20)"/> + <line text="y java.lang.Integer (AnnotationsAndITDs.aj:28)"/> + <line text="d java.lang.Double (AnnotationsAndITDs.aj:70)"/> + <line text="f java.lang.Double (AnnotationsAndITDs.aj:71)"/> + <line text="@type java.lang.System (AnnotationsAndITDs.aj:0)"/> + <line text="@field ITDMe2 (AnnotationsAndITDs.aj:59)"/> + <line text="@field ITDMe2 (AnnotationsAndITDs.aj:60)"/> + <line text="@cons java.lang.String (AnnotationsAndITDs.aj:45)"/> + <line text="@field ITDMe2 (AnnotationsAndITDs.aj:59)"/> + <line text="@field ITDMe2 (AnnotationsAndITDs.aj:60)"/> + <line text="@cons java.lang.String (AnnotationsAndITDs.aj:46)"/> + <line text="@cons java.lang.String (AnnotationsAndITDs.aj:46)"/> + <line text="@method ITDMe2 (AnnotationsAndITDs.aj:53)"/> + <line text="@field ITDMe2 (AnnotationsAndITDs.aj:76)"/> + <line text="@field ITDMe2 (AnnotationsAndITDs.aj:77)"/> + + <!-- + <line text="method bar has 1 params, first param annotation is @ParamAnnotation"/> + --> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" pr="91858" title="declare @Type (should be @type)"> + <compile files="DeathByPoorSpelling.aj" options="-1.9"> + <message kind="error" line="6" text="Syntax error on token ":", "one of type, method, field, constructor" expected"/> + </compile> + </ajc-test> + + <!-- ======================================================================================= --> + <!-- Autoboxing tests --> + <!-- ======================================================================================= --> + + <ajc-test dir="java5/autoboxing" vm="1.5" title="simple boxing test"> + <compile files="AutoboxingB.java,AutoboxingC.java,AutoboxingD.java,AutoboxingF.java,AutoboxingI.java,AutoboxingJ.java,AutoboxingS.java,AutoboxingZ.java,SimpleAutoboxing.java,SimpleAutoboxingAspect.aj" + options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'SimpleAutoboxing' (SimpleAutoboxing.java:7) advised by before advice from 'SimpleAutoboxingAspect' (SimpleAutoboxingAspect.aj:8)"/> + <message kind="weave" text="Type 'SimpleAutoboxing' (SimpleAutoboxing.java:7) advised by before advice from 'SimpleAutoboxingAspect' (SimpleAutoboxingAspect.aj:4)"/> + </compile> + <run class="SimpleAutoboxing"> + <stderr> + <line text="Matching by Integer:20000"/> + <line text="Matching by int:20000"/> + <line text="method_takes_Integer=20000"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/autoboxing" vm="1.5" title="integer boxing"> + <compile files="AutoboxingB.java,AutoboxingC.java,AutoboxingD.java,AutoboxingF.java,AutoboxingI.java,AutoboxingJ.java,AutoboxingS.java,AutoboxingZ.java,SimpleAutoboxing.java,AspectInteger.aj" + options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'AutoboxingI' (AutoboxingI.java:11) advised by before advice from 'AspectInteger' (AspectInteger.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingI' (AutoboxingI.java:11) advised by before advice from 'AspectInteger' (AspectInteger.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingI' (AutoboxingI.java:12) advised by before advice from 'AspectInteger' (AspectInteger.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingI' (AutoboxingI.java:12) advised by before advice from 'AspectInteger' (AspectInteger.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingI' (AutoboxingI.java:13) advised by before advice from 'AspectInteger' (AspectInteger.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingI' (AutoboxingI.java:13) advised by before advice from 'AspectInteger' (AspectInteger.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingI' (AutoboxingI.java:14) advised by before advice from 'AspectInteger' (AspectInteger.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingI' (AutoboxingI.java:14) advised by before advice from 'AspectInteger' (AspectInteger.aj:4)"/> + </compile> + <run class="AutoboxingI"> + <stderr> + <line text="Matching by Integer:10000"/> + <line text="Matching by int:10000"/> + <line text="method_takes_Integer=10000"/> + <line text="Matching by Integer:20000"/> + <line text="Matching by int:20000"/> + <line text="method_takes_Integer=20000"/> + <line text="Matching by Integer:30000"/> + <line text="Matching by int:30000"/> + <line text="method_takes_int=30000"/> + <line text="Matching by Integer:40000"/> + <line text="Matching by int:40000"/> + <line text="method_takes_int=40000"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/autoboxing" vm="1.5" title="char boxing"> + <compile files="AutoboxingB.java,AutoboxingC.java,AutoboxingD.java,AutoboxingF.java,AutoboxingI.java,AutoboxingJ.java,AutoboxingS.java,AutoboxingZ.java,SimpleAutoboxing.java,AspectChar.aj" + options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'AutoboxingC' (AutoboxingC.java:11) advised by before advice from 'AspectChar' (AspectChar.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingC' (AutoboxingC.java:11) advised by before advice from 'AspectChar' (AspectChar.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingC' (AutoboxingC.java:12) advised by before advice from 'AspectChar' (AspectChar.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingC' (AutoboxingC.java:12) advised by before advice from 'AspectChar' (AspectChar.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingC' (AutoboxingC.java:13) advised by before advice from 'AspectChar' (AspectChar.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingC' (AutoboxingC.java:13) advised by before advice from 'AspectChar' (AspectChar.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingC' (AutoboxingC.java:14) advised by before advice from 'AspectChar' (AspectChar.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingC' (AutoboxingC.java:14) advised by before advice from 'AspectChar' (AspectChar.aj:4)"/> + </compile> + <run class="AutoboxingC"> + <stderr> + <line text="Character:1"/> + <line text="char:1"/> + <line text="method_takes_Character=1"/> + <line text="Character:2"/> + <line text="char:2"/> + <line text="method_takes_Character=2"/> + <line text="Character:3"/> + <line text="char:3"/> + <line text="method_takes_char=3"/> + <line text="Character:4"/> + <line text="char:4"/> + <line text="method_takes_char=4"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/autoboxing" vm="1.5" title="double boxing"> + <compile files="AutoboxingB.java,AutoboxingC.java,AutoboxingD.java,AutoboxingF.java,AutoboxingI.java,AutoboxingJ.java,AutoboxingS.java,AutoboxingZ.java,SimpleAutoboxing.java,AspectDouble.aj" + options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'AutoboxingD' (AutoboxingD.java:11) advised by before advice from 'AspectDouble' (AspectDouble.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingD' (AutoboxingD.java:11) advised by before advice from 'AspectDouble' (AspectDouble.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingD' (AutoboxingD.java:12) advised by before advice from 'AspectDouble' (AspectDouble.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingD' (AutoboxingD.java:12) advised by before advice from 'AspectDouble' (AspectDouble.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingD' (AutoboxingD.java:13) advised by before advice from 'AspectDouble' (AspectDouble.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingD' (AutoboxingD.java:13) advised by before advice from 'AspectDouble' (AspectDouble.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingD' (AutoboxingD.java:14) advised by before advice from 'AspectDouble' (AspectDouble.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingD' (AutoboxingD.java:14) advised by before advice from 'AspectDouble' (AspectDouble.aj:4)"/> + </compile> + <run class="AutoboxingD"> + <stderr> + <line text="Double:100.0"/> + <line text="double:100.0"/> + <line text="method_takes_Double=100.0"/> + <line text="Double:200.0"/> + <line text="double:200.0"/> + <line text="method_takes_Double=200.0"/> + <line text="Double:300.0"/> + <line text="double:300.0"/> + <line text="method_takes_double=300.0"/> + <line text="Double:400.0"/> + <line text="double:400.0"/> + <line text="method_takes_double=400.0"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/autoboxing" vm="1.5" title="float boxing"> + <compile files="AutoboxingB.java,AutoboxingC.java,AutoboxingD.java,AutoboxingF.java,AutoboxingI.java,AutoboxingJ.java,AutoboxingS.java,AutoboxingZ.java,SimpleAutoboxing.java,AspectFloat.aj" + options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'AutoboxingF' (AutoboxingF.java:11) advised by before advice from 'AspectFloat' (AspectFloat.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingF' (AutoboxingF.java:11) advised by before advice from 'AspectFloat' (AspectFloat.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingF' (AutoboxingF.java:12) advised by before advice from 'AspectFloat' (AspectFloat.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingF' (AutoboxingF.java:12) advised by before advice from 'AspectFloat' (AspectFloat.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingF' (AutoboxingF.java:13) advised by before advice from 'AspectFloat' (AspectFloat.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingF' (AutoboxingF.java:13) advised by before advice from 'AspectFloat' (AspectFloat.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingF' (AutoboxingF.java:14) advised by before advice from 'AspectFloat' (AspectFloat.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingF' (AutoboxingF.java:14) advised by before advice from 'AspectFloat' (AspectFloat.aj:4)"/> + </compile> + <run class="AutoboxingF"> + <stderr> + <line text="Float:100.0"/> + <line text="float:100.0"/> + <line text="method_takes_Float=100.0"/> + <line text="Float:200.0"/> + <line text="float:200.0"/> + <line text="method_takes_Float=200.0"/> + <line text="Float:300.0"/> + <line text="float:300.0"/> + <line text="method_takes_float=300.0"/> + <line text="Float:400.0"/> + <line text="float:400.0"/> + <line text="method_takes_float=400.0"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/autoboxing" vm="1.5" title="short boxing"> + <compile files="AutoboxingB.java,AutoboxingC.java,AutoboxingD.java,AutoboxingF.java,AutoboxingI.java,AutoboxingJ.java,AutoboxingS.java,AutoboxingZ.java,SimpleAutoboxing.java,AspectShort.aj" + options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'AutoboxingS' (AutoboxingS.java:11) advised by before advice from 'AspectShort' (AspectShort.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingS' (AutoboxingS.java:11) advised by before advice from 'AspectShort' (AspectShort.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingS' (AutoboxingS.java:12) advised by before advice from 'AspectShort' (AspectShort.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingS' (AutoboxingS.java:12) advised by before advice from 'AspectShort' (AspectShort.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingS' (AutoboxingS.java:13) advised by before advice from 'AspectShort' (AspectShort.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingS' (AutoboxingS.java:13) advised by before advice from 'AspectShort' (AspectShort.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingS' (AutoboxingS.java:14) advised by before advice from 'AspectShort' (AspectShort.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingS' (AutoboxingS.java:14) advised by before advice from 'AspectShort' (AspectShort.aj:4)"/> + </compile> + <run class="AutoboxingS"> + <stderr> + <line text="Short:100"/> + <line text="short:100"/> + <line text="method_takes_Short=100"/> + <line text="Short:200"/> + <line text="short:200"/> + <line text="method_takes_Short=200"/> + <line text="Short:300"/> + <line text="short:300"/> + <line text="method_takes_short=300"/> + <line text="Short:400"/> + <line text="short:400"/> + <line text="method_takes_short=400"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/autoboxing" vm="1.5" title="long boxing"> + <compile files="AutoboxingB.java,AutoboxingC.java,AutoboxingD.java,AutoboxingF.java,AutoboxingI.java,AutoboxingJ.java,AutoboxingS.java,AutoboxingZ.java,SimpleAutoboxing.java,AspectLong.aj" + options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'AutoboxingJ' (AutoboxingJ.java:11) advised by before advice from 'AspectLong' (AspectLong.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingJ' (AutoboxingJ.java:11) advised by before advice from 'AspectLong' (AspectLong.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingJ' (AutoboxingJ.java:12) advised by before advice from 'AspectLong' (AspectLong.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingJ' (AutoboxingJ.java:12) advised by before advice from 'AspectLong' (AspectLong.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingJ' (AutoboxingJ.java:13) advised by before advice from 'AspectLong' (AspectLong.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingJ' (AutoboxingJ.java:13) advised by before advice from 'AspectLong' (AspectLong.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingJ' (AutoboxingJ.java:14) advised by before advice from 'AspectLong' (AspectLong.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingJ' (AutoboxingJ.java:14) advised by before advice from 'AspectLong' (AspectLong.aj:4)"/> + </compile> + <run class="AutoboxingJ"> + <stderr> + <line text="Long:1000000"/> + <line text="long:1000000"/> + <line text="method_takes_Long=1000000"/> + <line text="Long:2000000"/> + <line text="long:2000000"/> + <line text="method_takes_Long=2000000"/> + <line text="Long:3000000"/> + <line text="long:3000000"/> + <line text="method_takes_long=3000000"/> + <line text="Long:4000000"/> + <line text="long:4000000"/> + <line text="method_takes_long=4000000"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/autoboxing" vm="1.5" title="boolean boxing"> + <compile files="AutoboxingB.java,AutoboxingC.java,AutoboxingD.java,AutoboxingF.java,AutoboxingI.java,AutoboxingJ.java,AutoboxingS.java,AutoboxingZ.java,SimpleAutoboxing.java,AspectBoolean.aj" + options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'AutoboxingZ' (AutoboxingZ.java:9) advised by before advice from 'AspectBoolean' (AspectBoolean.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingZ' (AutoboxingZ.java:9) advised by before advice from 'AspectBoolean' (AspectBoolean.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingZ' (AutoboxingZ.java:10) advised by before advice from 'AspectBoolean' (AspectBoolean.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingZ' (AutoboxingZ.java:10) advised by before advice from 'AspectBoolean' (AspectBoolean.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingZ' (AutoboxingZ.java:11) advised by before advice from 'AspectBoolean' (AspectBoolean.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingZ' (AutoboxingZ.java:11) advised by before advice from 'AspectBoolean' (AspectBoolean.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingZ' (AutoboxingZ.java:12) advised by before advice from 'AspectBoolean' (AspectBoolean.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingZ' (AutoboxingZ.java:12) advised by before advice from 'AspectBoolean' (AspectBoolean.aj:4)"/> + </compile> + <run class="AutoboxingZ"> + <stderr> + <line text="Boolean:false"/> + <line text="boolean:false"/> + <line text="method_takes_Boolean=false"/> + <line text="Boolean:false"/> + <line text="boolean:false"/> + <line text="method_takes_Boolean=false"/> + <line text="Boolean:false"/> + <line text="boolean:false"/> + <line text="method_takes_boolean=false"/> + <line text="Boolean:false"/> + <line text="boolean:false"/> + <line text="method_takes_boolean=false"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/autoboxing" vm="1.5" title="byte boxing"> + <compile files="AutoboxingB.java,AutoboxingC.java,AutoboxingD.java,AutoboxingF.java,AutoboxingI.java,AutoboxingJ.java,AutoboxingS.java,AutoboxingZ.java,SimpleAutoboxing.java,AspectByte.aj" + options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'AutoboxingB' (AutoboxingB.java:11) advised by before advice from 'AspectByte' (AspectByte.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingB' (AutoboxingB.java:11) advised by before advice from 'AspectByte' (AspectByte.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingB' (AutoboxingB.java:12) advised by before advice from 'AspectByte' (AspectByte.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingB' (AutoboxingB.java:12) advised by before advice from 'AspectByte' (AspectByte.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingB' (AutoboxingB.java:13) advised by before advice from 'AspectByte' (AspectByte.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingB' (AutoboxingB.java:13) advised by before advice from 'AspectByte' (AspectByte.aj:4)"/> + <message kind="weave" text="Type 'AutoboxingB' (AutoboxingB.java:14) advised by before advice from 'AspectByte' (AspectByte.aj:8)"/> + <message kind="weave" text="Type 'AutoboxingB' (AutoboxingB.java:14) advised by before advice from 'AspectByte' (AspectByte.aj:4)"/> + </compile> + <run class="AutoboxingB"> + <stderr> + <line text="Byte:1"/> + <line text="byte:1"/> + <line text="method_takes_Byte=1"/> + <line text="Byte:50"/> + <line text="byte:50"/> + <line text="method_takes_Byte=50"/> + <line text="Byte:3"/> + <line text="byte:3"/> + <line text="method_takes_byte=3"/> + <line text="Byte:52"/> + <line text="byte:52"/> + <line text="method_takes_byte=52"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/autoboxing" vm="1.5" title="boxing in after returning"> + <compile files="AutoboxingB.java,AutoboxingC.java,AutoboxingD.java,AutoboxingF.java,AutoboxingI.java,AutoboxingJ.java,AutoboxingS.java,AutoboxingZ.java,SimpleAutoboxing.java,AspectAfterReturning.aj" + options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'AspectAfterReturning' (AspectAfterReturning.aj:18) advised by afterReturning advice from 'AspectAfterReturning' (AspectAfterReturning.aj:4)"/> + <message kind="weave" text="Type 'AspectAfterReturning' (AspectAfterReturning.aj:18) advised by afterReturning advice from 'AspectAfterReturning' (AspectAfterReturning.aj:8)"/> + <message kind="weave" text="Type 'AspectAfterReturning' (AspectAfterReturning.aj:18) advised by afterReturning advice from 'AspectAfterReturning' (AspectAfterReturning.aj:12)"/> + <message kind="weave" text="Type 'AspectAfterReturning' (AspectAfterReturning.aj:19) advised by afterReturning advice from 'AspectAfterReturning' (AspectAfterReturning.aj:4)"/> + <message kind="weave" text="Type 'AspectAfterReturning' (AspectAfterReturning.aj:19) advised by afterReturning advice from 'AspectAfterReturning' (AspectAfterReturning.aj:8)"/> + <message kind="weave" text="Type 'AspectAfterReturning' (AspectAfterReturning.aj:19) advised by afterReturning advice from 'AspectAfterReturning' (AspectAfterReturning.aj:12)"/> + </compile> + <run class="AspectAfterReturning"> + <stderr> + <line text="Returning I=5"/> + <line text="Returning Integer=5"/> + <line text="Returning Object=5"/> + <line text="Returning I=10"/> + <line text="Returning Integer=10"/> + <line text="Returning Object=10"/> + </stderr> + </run> + </ajc-test> + + <!-- ======================================================================================= --> + <!-- Covariance tests --> + <!-- ======================================================================================= --> + + <ajc-test dir="java5/covariance" vm="1.5" title="covariance 1"> + <compile options="-1.9,-showWeaveInfo" files="CovBaseProgram01.java,CovAspect01.aj"> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:26) advised by before advice from 'CovAspect01' (CovAspect01.aj:5)"/> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:27) advised by before advice from 'CovAspect01' (CovAspect01.aj:5)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/covariance" vm="1.5" title="covariance 2"> + <compile options="-1.9,-showWeaveInfo" files="CovBaseProgram01.java,CovAspect02.aj"> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:26) advised by before advice from 'CovAspect02' (CovAspect02.aj:5)"/> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:27) advised by before advice from 'CovAspect02' (CovAspect02.aj:5)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/covariance" vm="1.5" title="covariance 3"> + <compile options="-1.9,-showWeaveInfo" files="CovBaseProgram01.java,CovAspect03.aj"> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:26) advised by before advice from 'CovAspect03' (CovAspect03.aj:5)"/> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:27) advised by before advice from 'CovAspect03' (CovAspect03.aj:5)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/covariance" vm="1.5" title="covariance 4"> + <compile options="-1.9,-showWeaveInfo" files="CovBaseProgram02.java,CovAspect04.aj"> + <message kind="weave" text="Type 'CovBaseProgram02' (CovBaseProgram02.java:30) advised by before advice from 'CovAspect04' (CovAspect04.aj:5)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/covariance" vm="1.5" title="covariance 5"> + <compile options="-1.9,-showWeaveInfo" files="CovBaseProgram01.java,CovAspect05.aj"> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:26) advised by before advice from 'CovAspect05' (CovAspect05.aj:5)"/> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:27) advised by before advice from 'CovAspect05' (CovAspect05.aj:5)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/covariance" vm="1.5" title="covariance 6"> + <compile options="-1.9,-showWeaveInfo" files="CovBaseProgram01.java,CovAspect06.aj"> + <message kind="warning" line="3" text="does not match because declaring type is Super"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/covariance" vm="1.5" title="covariance 7"> + <compile options="-1.9,-showWeaveInfo" files="CovBaseProgram01.java,CovAspect07.aj"> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:27) advised by before advice from 'CovAspect07' (CovAspect07.aj:5)"/> + <message kind="warning" line="3" text="does not match because declaring type is Super"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/covariance" vm="1.5" title="covariance 8"> + <compile options="-1.9,-showWeaveInfo" files="CovBaseProgram01.java,CovAspect08.aj"> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:27) advised by before advice from 'CovAspect08' (CovAspect08.aj:11)"/> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:27) advised by before advice from 'CovAspect08' (CovAspect08.aj:5)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/covariance" vm="1.5" title="covariance 9"> + <compile options="-1.9,-showWeaveInfo" files="CovBaseProgram01.java,CovAspect09.aj"> + </compile> + </ajc-test> + + <ajc-test dir="java5/covariance" vm="1.5" title="covariance 10"> + <compile options="-1.9,-showWeaveInfo" files="CovBaseProgram01.java,CovAspect10.aj"> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:26) advised by before advice from 'CovAspect10' (CovAspect10.aj:5)"/> + <message kind="weave" text="Type 'CovBaseProgram01' (CovBaseProgram01.java:27) advised by before advice from 'CovAspect10' (CovAspect10.aj:5)"/> + </compile> + </ajc-test> + + <!-- ======================================================================================= --> + <!-- Enum tests --> + <!-- ======================================================================================= --> + + <ajc-test dir="java5/enums" vm="1.5" title="cant itd constructor on enum"> + <compile files="SimpleEnum.java,SimpleEnum2.java,EnumAspect01.aj" options="-1.9"> + <message kind="error" line="2" text="can't make inter-type constructor declarations on enum types"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/enums" vm="1.5" title="cant itd field or method on enum"> + <compile files="SimpleEnum.java,SimpleEnum2.java,EnumAspect02.aj" options="-1.9"> + <message kind="error" line="2" text="can't make inter-type method declarations on enum types"/> + <message kind="error" line="6" text="can't make inter-type field declarations on enum types"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/enums" vm="1.5" title="declare parents and enums"> + <compile files="SimpleEnum.java,SimpleEnum2.java,EnumAspect03.aj" options="-1.9"> + <message kind="error" line="5" text="can't use declare parents to make enum type SimpleEnum implement an interface"/> + <message kind="error" line="8" text="can't use declare parents to alter supertype of enum type SimpleEnum"/> + <message kind="error" line="11" text="can't use declare parents to make 'java.lang.Enum' the parent of type EnumAspect03$D"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/enums" vm="1.5" title="wildcard enum match in itd"> + <compile files="SimpleEnum.java,SimpleEnum2.java,EnumAspect04.aj" options="-1.9"> + <message kind="warning" line="5" text="enum type SimpleEnum2 matches a declare parents type pattern but is being ignored"/> + <message kind="warning" line="5" text="enum type SimpleEnum matches a declare parents type pattern but is being ignored"/> + </compile> + </ajc-test> + + <!-- ======================================================================================= --> + <!-- pertypewithin tests --> + <!-- ======================================================================================= --> + + <ajc-test dir="java5/pertypewithin" title="basic ptw test"> + <compile files="A.java,B.java,C.java,D.java,Main.java,X.java" options="-Xlint:ignore"/> + <run class="p.A"> + <stderr> + <line text="hi from A"/> + <line text="after() returning from a method call to sayhi()"/> + <line text="hi from A"/> + <line text="after() returning from a method call to sayhi()"/> + <line text="Tests in A have passed"/> + <line text="callcount = 2"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/pertypewithin" title="ptw hasAspect"> + <compile files="A.java,B.java,C.java,D.java,Main.java,X.java" options="-Xlint:ignore"/> + <run class="p.B"> + <stderr> + <line text="hi from B"/> + <line text="after() returning from a method call to sayhi()"/> + <line text="hi from B"/> + <line text="after() returning from a method call to sayhi()"/> + <line text="hi from B"/> + <line text="after() returning from a method call to sayhi()"/> + <line text="callcount = 3"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/pertypewithin" title="ptw aspectOf"> + <compile files="A.java,B.java,C.java,D.java,Main.java,X.java" options="-Xlint:ignore"/> + <run class="p.C"/> + </ajc-test> + + <ajc-test dir="java5/pertypewithin" title="ptw multi-aspects"> + <compile files="P.java,Q.java,R.java"/> + <run class="P"> + <stderr> + <line text="Q reporting 2"/> + <line text="R reporting 3"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/pertypewithin" title="ptw binary"> + <weave classesFiles="G.java" aspectsFiles="H.java"/> + <run class="G"> + <stderr> + <line text="advice running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/pertypewithin" title="ptw binary aspect"> + <compile files="H.java" outjar="aspects.jar"> + <message kind="warning" line="1" text="no match for this type name: G"/> + </compile> + <compile files="G.java" aspectpath="aspects.jar"/> + <run class="G"> + <stderr> + <line text="advice running"/> + </stderr> + </run> + </ajc-test> + + <!-- ======================================================================================= --> + <!-- varargs tests --> + <!-- ======================================================================================= --> + + <ajc-test dir="java5/varargs" vm="1.5" title="varargs not matched by Object[] (call)"> + <compile files="SimpleVarargs.java,VarargsAspect01.aj" options="-1.9,-showWeaveInfo"> + </compile> + </ajc-test> + + <ajc-test dir="java5/varargs" vm="1.5" title="varargs not matched by Object[] (exe)"> + <compile files="SimpleVarargs.java,VarargsAspect02.aj" options="-1.9,-showWeaveInfo"> + </compile> + </ajc-test> + + <ajc-test dir="java5/varargs" vm="1.5" title="varargs not matched by Object[] (init)"> + <compile files="SimpleVarargs.java,VarargsAspect03.aj" options="-1.9,-showWeaveInfo"> + </compile> + </ajc-test> + + <ajc-test dir="java5/varargs" vm="1.5" title="varargs not matched by Object[] (withincode)"> + <compile files="SimpleVarargs.java,VarargsAspect04.aj" options="-1.9,-showWeaveInfo"> + </compile> + </ajc-test> + + <ajc-test dir="java5/varargs" vm="1.5" title="call with varargs signature"> + <compile files="SimpleVarargs.java,VarargsAspect05.aj" options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'SimpleVarargs' (SimpleVarargs.java:20) advised by before advice from 'VarargsAspect05' (VarargsAspect05.aj:3)"/> + <message kind="weave" text="Type 'SimpleVarargs' (SimpleVarargs.java:21) advised by before advice from 'VarargsAspect05' (VarargsAspect05.aj:3)"/> + <message kind="weave" text="Type 'SimpleVarargs' (SimpleVarargs.java:22) advised by before advice from 'VarargsAspect05' (VarargsAspect05.aj:3)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/varargs" vm="1.5" title="call with varargs multi-signature"> + <compile files="SimpleVarargs.java,VarargsAspect06.aj" options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'SimpleVarargs' (SimpleVarargs.java:25) advised by before advice from 'VarargsAspect06' (VarargsAspect06.aj:3)"/> + <message kind="weave" text="Type 'SimpleVarargs' (SimpleVarargs.java:26) advised by before advice from 'VarargsAspect06' (VarargsAspect06.aj:3)"/> + <message kind="weave" text="Type 'SimpleVarargs' (SimpleVarargs.java:27) advised by before advice from 'VarargsAspect06' (VarargsAspect06.aj:3)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/suppressedWarnings" vm="1.5" title="suppressing non-matching advice warnings"> + <compile files="Suppression1.aj" options="-1.9,-showWeaveInfo"> + <message kind="warning" line="13"/> + <message kind="warning" line="21"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/suppressedWarnings" vm="1.5" title="suppressing non-matching advice warnings when multiple source files involved"> + <compile files="A.java,A1.aj,A2.aj,A3.aj" options="-1.9,-showWeaveInfo"> + <message kind="warning" line="4" file="A1.aj"/> + <message kind="warning" line="4" file="A2.aj"/> + <message kind="warning" line="11" file="A2.aj"/> + <message kind="warning" line="4" file="A3.aj"/> + <message kind="warning" line="11" file="A3.aj"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="XLint warning for advice not applied with cflow(execution)" pr="93345"> + <compile options="-Xlint,-1.9" files="PR93345.aj" > + <message kind="warning" line="9" text="advice defined in AnAspect has not been applied [Xlint:adviceDidNotMatch]"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150" title="NPE in reflect implementation" pr="94167"> + <compile files="PR94167.java"/> + <run class="reflect.PR94167"/> + </ajc-test> + + <!-- ======================================================================================= --> + <!-- annotated aspect members --> + <!-- ======================================================================================= --> + + <ajc-test dir="java5/annotations/aspectMembers" title="annotated annotations (@Target)"> + <compile files="a/Annotations.java,a/Foo.java" options="-1.9"> + <message kind="error" line="16" text="The annotation @MethodAnnotation is disallowed for this location"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/aspectMembers" title="simple annotated aspect members"> + <compile files="a/Annotations.java,a/AnnotatedAspect.aj" options="-1.9"> + <message kind="warning" line="4" text="annotated type"/> + <message kind="warning" line="6" text="annotated field"/> + <message kind="warning" line="8" text="annotated method"/> + <message kind="warning" line="11" text="annotated constructor"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/aspectMembers" title="simple annotated aspect members with bad target"> + <compile files="a/Annotations.java,a/AnnotatedAspect02.aj" options="-1.9"> + <message kind="error" line="3" text="The annotation @MethodAnnotation is disallowed for this location"/> + <message kind="error" line="6" text="The annotation @TypeAnnotation is disallowed for this location"/> + <message kind="error" line="8" text="The annotation @FieldAnnotation is disallowed for this location"/> + <message kind="error" line="10" text="The annotation @AnnotationAnnotation is disallowed for this location"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/aspectMembers" title="annotated itds"> + <compile files="a/Annotations.java,a/AnnotatedAspect03.aj" options="-1.9"> + <message kind="warning" line="4" text="annotated type"/> + <message kind="warning" line="6" text="annotated field"/> + <message kind="warning" line="8" text="annotated field"/> + <message kind="warning" line="10" text="annotated method"/> + <message kind="warning" line="12" text="annotated constructor"/> + <message kind="warning" line="12" text="annotated field"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/aspectMembers" title="annotated itds with bad target"> + <compile files="a/Annotations.java,a/AnnotatedAspect04.aj" options="-1.9"> + <message kind="error" line="6" text="The annotation @ConstructorAnnotation is disallowed for this location"/> + <message kind="error" line="8" text="The annotation @FieldAnnotation is disallowed for this location"/> + <message kind="error" line="10" text="The annotation @TypeAnnotation is disallowed for this location"/> + <!-- known limitation... + <message kind="error" line="12" text="The annotation @MethodAnnotation is disallowed for this location"/> + --> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/aspectMembers" title="annotated advice"> + <compile files="a/Annotations.java,a/AnnotatedAspect05.aj" options="-1.9"> + <message kind="warning" line="17"/> + </compile> + <run class="a.AnnotatedAspect05"/> + </ajc-test> + + <ajc-test dir="java5/annotations/aspectMembers" title="annotated advice with bad target"> + <compile files="a/Annotations.java,a/AnnotatedAspect06.aj" options="-1.9"> + <message kind="error" line="6" text="The annotation @ConstructorAnnotation is disallowed for this location"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/aspectMembers" title="annotated pointcut"> + <compile files="a/Annotations.java,a/AnnotatedAspect07.aj" options="-1.9"> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/aspectMembers" title="annotated declare statements"> + <compile files="a/Annotations.java,a/AnnotatedAspect08.aj" options="-1.9"> + </compile> + </ajc-test> + + <!-- ======================================================================================= --> + <!-- ajdk examples --> + <!-- ======================================================================================= --> + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: annotating aspects chapter"> + <compile files="AnnotatingAspects.aj" options="-1.9"> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: annotating aspects chapter, ex 2"> + <compile files="SuppressAj.aj" options="-1.9"> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: annotation pattern matching"> + <compile files="AnnotationPatternMatching.aj,org/xyz/OrgXYZAnnotation.java" options="-1.9"> + <message kind="warning" line="25" text="@Immutable"/> + <message kind="warning" line="25" text="!@Persistent"/> + <message kind="warning" line="29" text="!@Persistent"/> + <message kind="warning" line="31" text="!@Persistent"/> + <message kind="warning" line="33" text="!@Persistent"/> + <message kind="warning" line="29" text="@Foo @Goo"/> + <message kind="warning" line="29" text="@(Foo || Goo)"/> + <message kind="warning" line="31" text="@(Foo || Goo)"/> + <message kind="warning" line="33" text="@(org.xyz..*)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: annotation type pattern matching"> + <compile files="AnnotationsInTypePatterns.aj,org/xyz/OrgXYZAnnotation.java,org/xyz/Types.java,org/abc/Types.java,anns/Immutable.java,anns/NonPersistent.java" options="-1.9"> + <message kind="warning" line="23" text="(@Immutable *)"/> + <message kind="warning" line="32" text="(@Immutable *)"/> + <message kind="warning" line="3" text="(@Immutable *)"/> + <message kind="warning" line="5" text="(@Immutable *)"/> + <message kind="warning" line="8" text="(@Immutable *)"/> + <message kind="warning" line="25" text="(!@Immutable *)"/> + <message kind="warning" line="27" text="(!@Immutable *)"/> + <message kind="warning" line="29" text="(!@Immutable *)"/> + <message kind="warning" line="5" text="(!@Immutable *)"/> + <message kind="warning" line="6" text="(!@Immutable *)"/> + <message kind="warning" line="2" text="(!@Immutable *)"/> + <message kind="warning" line="2" text="(!@Immutable *)"/> + <message kind="warning" line="5" text="(!@Immutable *)"/> + <message kind="warning" line="3" text="@Immutable (org.xyz.* || org.abc.*)"/> + <message kind="warning" line="5" text="@Immutable (org.xyz.* || org.abc.*)"/> + <message kind="warning" line="8" text="@Immutable (org.xyz.* || org.abc.*)"/> + <message kind="warning" line="32" text="((@Immutable Foo+) || Goo)"/> + <message kind="warning" line="27" text="((@Immutable Foo+) || Goo)"/> + <message kind="warning" line="3" text="@(Immutable || NonPersistent) org.xyz..*"/> + <message kind="warning" line="6" text="@(Immutable || NonPersistent) org.xyz..*"/> + <message kind="warning" line="8" text="@(Immutable || NonPersistent) org.xyz..*"/> + <message kind="warning" line="8" text="@Immutable @NonPersistent org.xyz..*"/> + <message kind="warning" line="6" text="@(@Inherited *) org.xyz..*"/> + <message kind="warning" line="8" text="@(@Inherited *) org.xyz..*"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: annotations in sig patterns"> + <compile files="AnnotationsInSignaturePatterns.aj,anns/Cachable.java,anns/SensitiveData.java,anns/Persisted.java,Classified.java,anns/Immutable.java,Secure.java,Catastrophic.java,Oneway.java,anns/Transaction.java,org/xyz/SignatureTypes.java" options="-1.9"> + <message kind="warning" line="32" text="@SensitiveData * *"/> + <message kind="warning" line="7" text="@SensitiveData * *"/> + <message kind="warning" line="13" text="@SensitiveData * *"/> + <message kind="warning" line="7" text="@SensitiveData List org.xyz..*.*"/> + <message kind="warning" line="11" text="(@SensitiveData *) org.xyz..*.*"/> + <message kind="warning" line="13" text="(@SensitiveData *) org.xyz..*.*"/> + <message kind="warning" line="50" text="@Foo (@Goo *) (@Hoo *).*"/> + <message kind="warning" line="38" text="@Persisted @Classified * *"/> + + <message kind="warning" line="44" text="@Oneway * *(..)"/> + <message kind="warning" line="18" text="@Transaction * (@Persisted org.xyz..*).*(..)"/> + <message kind="warning" line="52" text="* *.*(@Immutable *,..)"/> + <message kind="warning" line="53" text="* *.*(@Immutable *,..)"/> + <message kind="warning" line="54" text="* *.*(@Immutable *,..)"/> + + <message kind="warning" line="62" text="within(@Secure *)"/> + <message kind="warning" line="63" text="within(@Secure *)"/> + <message kind="warning" line="66" text="staticinitialization(@Persisted *)"/> + <message kind="warning" line="17" text="staticinitialization(@Persisted *)"/> + <message kind="warning" line="56" text="call(@Oneway * *(..))"/> + <message kind="warning" line="28" text="execution(public (@Immutable *) org.xyz..*.*(..))"/> + <message kind="warning" line="26" text="set(@Cachable * *)"/> + <message kind="warning" line="80" text="handler(!@Catastrophic *)"/> + + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: runtime annotations"> + <compile files="RuntimeTypeMatching.aj" options="-1.9"> + <message kind="warning" line="121" text="@within(Foo)"/> + <message kind="warning" line="122" text="@within(Foo)"/> + </compile> + <run class="RuntimeTypeMatching"> + <stdout> + <line text="This information is TOP-SECRET"/> + <line text="@target(Classified) at call(void A.a())"/> + <line text="@this(Foo) at execution(void B.b())"/> + <line text="Classified data being passed at call(void B.callA(A))"/> + <line text="Classified data being passed at execution(void B.callA(A))"/> + <line text="This information is TOP-SECRET"/> + <line text="@target(Classified) at call(Class java.lang.Object.getClass())"/> + <line text="1 @Foo()"/> + <line text="1 @Foo()"/> + <line text="1 @Classified(classification=TOP-SECRET)" vm="1.2,1.3,1.4,1.5,1.6,1.7,1.8"/> + <line text="1 @Classified(classification="TOP-SECRET")" vm="9+"/> + <line text="This information is TOP-SECRET"/> + <line text="Entering critical join point with priority 3"/> + <line text="Entering critical join point with reflectively obtained priority 3"/> + <line text="@target(Classified) at call(void A.a())"/> + <line text="@this(Foo) at execution(void B.callA(A))"/> + <line text="(Class) Transaction required at execution(void ByeByeEJB.method1())"/> + <line text="(Method) Transaction required at execution(void ByeByeEJB.method1())"/> + <line text="(Class) Transaction required at execution(void ByeByeEJB.method2())"/> + <line text="(Method) Transaction required at execution(void ByeByeEJB.method2())"/> + <line text="(Class) Transaction required at execution(void ByeByeEJB.method3())"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: @retention checking"> + <compile files="RetentionTime.aj" options="-1.9"> + <message kind="error" line="8" text="Annotation type Goo does not have runtime retention"/> + <message kind="error" line="13" text="Annotation type Goo does not have runtime retention"/> + <message kind="error" line="18" text="Annotation type Goo does not have runtime retention"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: @inherited"> + <compile files="AnnotationInheritance.aj" options="-1.9"> + <message kind="warning" line="16" text="annotatedMethodCall()"/> + <!-- <message kind="warning" line="17" text="annotatedMethodCall()"/> --> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: deow-ann"> + <compile files="DeclaresWithAnnotations.aj,org/xyz/model/Model.java" options="-1.9"> + <message kind="warning" line="27" text="Expensive operation called from within performance critical section"/> + <message kind="error" line="26" text="Untrusted code should not call the model classes directly"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: decp-ann"> + <compile files="DecpAnnotations.aj" options="-1.9"> + </compile> + <run class="DecpAnnotations"> + <stdout> + <line text="Test Foo is not secured: PASS"/> + <line text="Test Goo is secured: PASS"/> + <line text="goo credentials: none"/> + <line text="Test BankAccount is not secured: PASS"/> + <line text="Test PrivateBankAccount is not secured: PASS"/> + <line text="Test BusinessBankAccount is secured: PASS"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: dec precedence"> + <compile files="PrecedenceAnnotations.aj" options="-1.9"> + </compile> + <run class="PrecedenceAnnotations"> + <stdout> + <line text="@Security S2"/> + <line text="S1"/> + <line text="@Performance P2"/> + <line text="P1"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: dec annotation"> + <compile files="DeclareAnnotation.aj,org/xyz/model/Model.java" options="-1.9"> + <message kind="warning" line="3" text="@BusinessDomain"/> + <message kind="warning" line="43" text="@Secured"/> + <message kind="warning" line="44" text="@Secured"/> + <message kind="warning" line="55" text="@Secured"/> + <message kind="warning" line="62" text="@Persisted"/> + <message kind="warning" line="68" text="@Persisted"/> + <message kind="warning" line="41" text="@Secured"/> + <message kind="warning" line="51" text="@Secured"/> + </compile> + <run class="DeclareAnnotation"/> + </ajc-test> + + <ajc-test dir="java5/covariance/ajdk" title="ajdk: covariance"> + <compile files="AJDKExamples.aj" options="-1.9"> + <message kind="warning" line="43" text="call(* whoAreYou())"/> + <message kind="warning" line="44" text="call(* whoAreYou())"/> + <message kind="warning" line="43" text="call(* A.whoAreYou())"/> + <message kind="warning" line="44" text="call(* A.whoAreYou())"/> + <message kind="warning" line="43" text="call(A whoAreYou())"/> + <message kind="warning" line="44" text="call(A whoAreYou())"/> + <message kind="warning" line="44" text="call(A+ B.whoAreYou())"/> + <message kind="warning" line="44" text="call(B whoAreYou())"/> + <message kind="warning" line="44" text="call(B B.whoAreYou())"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/varargs/ajdk" title="ajdk: varargs"> + <compile files="AJDKExamples.aj,org/xyz/Foo.java,org/xyz/Goo.java,org/xyz/Hoo.java" options="-1.9"> + <message kind="warning" line="8" text="call vararg match"/> + <message kind="warning" line="14" text="execution vararg match"/> + <message kind="warning" line="5" text="init vararg match"/> + <message kind="warning" line="6" text="init vararg match"/> + <message kind="warning" line="27" text="single vararg"/> + <message kind="warning" line="28" text="single String[]"/> + <message kind="warning" line="18" text="single String[]"/> + </compile> + <run class="AJDKExamples"> + <stdout> + <line text="Matched at call(void X.foo(int, String[]))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/pertypewithin/ajdk" title="ajdk: ptw"> + <compile files="AJDKExamples.aj" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Join point 'constructor-execution(void org.xyz.foo.B.<init>())' in Type 'org.xyz.foo.B' (AJDKExamples.aj:38) advised by afterReturning advice from 'org.xyz.foo.AJDKExamples' (AJDKExamples.aj:11)"/> + <message kind="weave" text="Join point 'constructor-execution(void org.xyz.foo.A.<init>())' in Type 'org.xyz.foo.A' (AJDKExamples.aj:36) advised by afterReturning advice from 'org.xyz.foo.AJDKExamples' (AJDKExamples.aj:11)"/> + </compile> + <run class="org.xyz.foo.AJDKExamples"> + <stdout> + <line text="Aspect instance constructed"/> + <line text="Aspect instance constructed"/> + <line text="true"/> + <line text="true"/> + <line text="There are 2 As"/> + <line text="There are 3 Bs"/> + </stdout> + </run> + </ajc-test> + + <!-- ======================================================================================= --> + <!-- declare annotation --> + <!-- ======================================================================================= --> + + <ajc-test dir="java5/annotations/declare" title="basic declare annotation parse test"> + <compile files="BasicParseTest.aj" options="-1.9"> + </compile> + </ajc-test> + + <!-- ======================================================================================= --> + <!-- declare annotation (@type) --> + <!-- ======================================================================================= --> + + <ajc-test dir="java5/annotations/declare" title="declare @type 1"> + <compile files="DecaType1.java" options="-1.9"/> + <run class="DecaType1"> + <stderr> + <line text="annotation is @MyAnnotation()"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type 2"> + <compile files="DecaType2.java" options="-1.9,-Xlint:ignore" > + </compile> + <run class="DecaType2"> + <stderr> + <line text="annotation on DecaType2 is @MyAnnotation()"/> + <line text="annotation on X is @MyAnnotation()"/> + <line text="annotation on MyAnnotation is @MyAnnotation()"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - with matching pointcut"> + <compile files="DecaType3.java" options="-1.9"/> + <run class="DecaType3"> + <stderr> + <line text="hello world"/> + <line text="advice running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - binary weaving"> + <weave classesFiles="BaseTypes.java" + aspectsFiles="DecaTypeBin1.aj,Colored.java" + options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + </weave> + <run class="BaseTypes"> + <stderr> + <line text="Color identified on class X"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - complex annotation - binary weaving"> + <weave classesFiles="BaseTypes.java" aspectsFiles="DecaTypeBin2.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="BaseTypes"> + <stderr> + <line text="ComplexAnnotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - complex annotation - source weaving"> + <compile files="BaseTypes.java,DecaTypeBin2.aj" options="-1.9"/> + <run class="BaseTypes"> + <stderr> + <line text="ComplexAnnotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - two annotations hit one type - source weaving"> + <compile files="BaseTypes.java,DecaTypeBin3.aj" options="-1.9"/> + <run class="BaseTypes"> + <stderr> + <line text="Color identified on execution(void A.m())"/> + <line text="Fruit identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - two annotations hit one type - binary weaving"> + <weave classesFiles="BaseTypes.java" aspectsFiles="DecaTypeBin3.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="BaseTypes"> + <stderr> + <line text="Color identified on execution(void A.m())"/> + <line text="Fruit identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - declare parents interactions (order 1) - binary weaving"> + <weave classesFiles="BaseTypes.java" aspectsFiles="DecaDecpInteractions1.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="BaseTypes"> + <stderr> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + <ajc-test dir="java5/annotations/declare" title="declare @type - declare parents interactions (order 1) - source weaving"> + <compile files="BaseTypes.java,DecaDecpInteractions1.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="BaseTypes"> + <stderr> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + + + <ajc-test dir="java5/annotations/declare" title="declare @type - declare parents interactions (order 2) - binary weaving"> + <weave classesFiles="BaseTypes.java" aspectsFiles="DecaDecpInteractions2.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="BaseTypes"> + <stderr> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + <ajc-test dir="java5/annotations/declare" title="declare @type - declare parents interactions (order 2) - source weaving"> + <compile files="BaseTypes.java,DecaDecpInteractions2.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="BaseTypes"> + <stderr> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - declare parents interactions (order 3) - binary weaving"> + <weave classesFiles="BaseTypes.java" aspectsFiles="DecaDecpInteractions3.aj" options="-1.9,-Xlint:ignore"/> + <run class="BaseTypes"> + <stderr> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + <ajc-test dir="java5/annotations/declare" title="declare @type - declare parents interactions (order 3) - source weaving"> + <compile files="BaseTypes.java,DecaDecpInteractions3.aj" options="-1.9,-Xlint:ignore"/> + <run class="BaseTypes"> + <stderr> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - declare parents interactions (order 4) - binary weaving"> + <weave classesFiles="BaseTypes.java" aspectsFiles="DecaDecpInteractions4.aj" options="-1.9,-Xlint:ignore"/> + <run class="BaseTypes"> + <stderr> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + <ajc-test dir="java5/annotations/declare" title="declare @type - declare parents interactions (order 4) - source weaving"> + <compile files="BaseTypes.java,DecaDecpInteractions4.aj" options="-1.9,-Xlint:ignore"/> + <run class="BaseTypes"> + <stderr> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Marker interface identified on execution(void A.m())"/> + <line text="Color annotation identified on execution(void A.m())"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - annotating an already annotated type - binary weaving"> + <weave classesFiles="AnnotatedType.java" aspectsFiles="DecaTypeBin4.aj" options="-1.9,-Xlint:ignore"/> + <run class="AnnotatedType"> + <stderr> + <line text="Color identified on execution(void AnnotatedType.m())"/> + <line text="Fruit identified on execution(void AnnotatedType.m())"/> + <line text="m() running"/> + </stderr> + </run> + </ajc-test> + <ajc-test dir="java5/annotations/declare" title="declare @type - annotating an already annotated type - source weaving"> + <compile files="AnnotatedType.java,DecaTypeBin4.aj" options="-1.9,-Xlint:ignore"/> + <run class="AnnotatedType"> + <stderr> + <line text="Color identified on execution(void AnnotatedType.m())"/> + <line text="Fruit identified on execution(void AnnotatedType.m())"/> + <line text="m() running"/> + </stderr> + </run> + </ajc-test> + + + <!--ajc-test dir="java5/annotations/declare" title="declare @type - annotations with different targets - binary weaving"> + <weave classesFiles="BaseTypes.java" aspectsFiles="DecaTypeBin5.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="error" line="15" text="The annotation @ColorM is disallowed for this location"/> + <message kind="error" line="16" text="The annotation @ColorC is disallowed for this location"/> + <message kind="error" line="18" text="The annotation @ColorF is disallowed for this location"/> + <message kind="error" line="19" text="The annotation @ColorP is disallowed for this location"/> + <message kind="error" line="20" text="The annotation @ColorL is disallowed for this location"/> + <message kind="error" line="21" text="The annotation @ColorPkg is disallowed for this location"/> + </weave> + <run class="BaseTypes"> + <stderr> + <line text="ColorT identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test--> + + <ajc-test dir="java5/annotations/declare" title="declare @type - annotations with different targets - source weaving"> + <compile files="BaseTypes.java,DecaTypeBin5.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="error" line="15" text="The annotation @ColorM is disallowed for this location"/> + <message kind="error" line="16" text="The annotation @ColorC is disallowed for this location"/> + <message king="error" line="17" text="A is not a valid target for annotation ColorA"/> + <message kind="error" line="18" text="The annotation @ColorF is disallowed for this location"/> + <message kind="error" line="19" text="The annotation @ColorP is disallowed for this location"/> + <message kind="error" line="20" text="The annotation @ColorL is disallowed for this location"/> + <message kind="error" line="21" text="The annotation @ColorPkg is disallowed for this location"/> + </compile> + </ajc-test> + + <!--ajc-test dir="java5/annotations/declare" title="declare @type - annotations with different targets (using type patterns) - binary weaving"> + <weave classesFiles="BaseTypes.java" aspectsFiles="DecaTypeBin6.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="warning" line="15" text="A is not a valid target for annotation ColorM"/> + <message kind="warning" line="16" text="A is not a valid target for annotation ColorC"/> + <message kind="warning" line="17" text="A is not a valid target for annotation ColorL"/> + <message kind="warning" line="17" text="B is not a valid target for annotation ColorL"/> + <message kind="warning" line="17" text="C is not a valid target for annotation ColorL"/> + </weave> + <run class="BaseTypes"> + <stderr> + <line text="ColorT identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="ColorT identified on execution(void A.m())"/> + <line text="A.m() running"/> + <line text="ColorT identified on execution(void A.m())"/> + <line text="A.m() running"/> + </stderr> + </run> + </ajc-test--> + + <ajc-test dir="java5/annotations/declare" title="declare @type - annotations with different targets (using type patterns) - source weaving"> + <compile files="BaseTypes.java,DecaTypeBin6.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="error" line="15" text="The annotation @ColorM is disallowed for this location"/> + <message kind="error" line="16" text="The annotation @ColorC is disallowed for this location"/> + <message kind="error" line="17" text="The annotation @ColorL is disallowed for this location"/> + <message kind="error" line="18" text="The annotation @ColorF is disallowed for this location"/> + </compile> + </ajc-test> + + + <ajc-test dir="java5/annotations/declare" title="declare @type - complex decp decAtType interactions - binary weaving"> + <weave classesFiles="BaseTypes.java" aspectsFiles="DecaTypeBin7.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + </weave> + <run class="BaseTypes"> + <stderr> + <line text="Color identified on execution(void A.m())"/> + <line text="Fruit identified on execution(void A.m())"/> + <line text="Chocolate identified on execution(void A.m())"/> + <line text="M1 at execution(void A.m())"/> + <line text="M2 at execution(void A.m())"/> + <line text="M3 at execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Fruit identified on execution(void B.m())"/> + <line text="Chocolate identified on execution(void B.m())"/> + <line text="M1 at execution(void B.m())"/> + <line text="M2 at execution(void B.m())"/> + <line text="M3 at execution(void B.m())"/> + <line text="B.m() running"/> + <line text="Fruit identified on execution(void C.m())"/> + <line text="Chocolate identified on execution(void C.m())"/> + <line text="M1 at execution(void C.m())"/> + <line text="M2 at execution(void C.m())"/> + <line text="M3 at execution(void C.m())"/> + <line text="C.m() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - complex decp decAtType interactions - source weaving"> + <compile files="BaseTypes.java,DecaTypeBin7.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="BaseTypes"> + <stderr> + <line text="Color identified on execution(void A.m())"/> + <line text="Fruit identified on execution(void A.m())"/> + <line text="Chocolate identified on execution(void A.m())"/> + <line text="M1 at execution(void A.m())"/> + <line text="M2 at execution(void A.m())"/> + <line text="M3 at execution(void A.m())"/> + <line text="A.m() running"/> + <line text="Fruit identified on execution(void B.m())"/> + <line text="Chocolate identified on execution(void B.m())"/> + <line text="M1 at execution(void B.m())"/> + <line text="M2 at execution(void B.m())"/> + <line text="M3 at execution(void B.m())"/> + <line text="B.m() running"/> + <line text="Fruit identified on execution(void C.m())"/> + <line text="Chocolate identified on execution(void C.m())"/> + <line text="M1 at execution(void C.m())"/> + <line text="M2 at execution(void C.m())"/> + <line text="M3 at execution(void C.m())"/> + <line text="C.m() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - trying to put annotation targetting annos on normal types - source weaving"> + <compile files="BaseTypes.java,DecaTypeBin8.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="error" line="8" text="A is not a valid target for annotation ColorA"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - trying to put annotation targetting annos on normal types - binary weaving"> + <weave classesFiles="BaseTypes.java" aspectsFiles="DecaTypeBin8.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="error" line="8" text="A is not a valid target for annotation ColorA"/> + </weave> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - trying to put annotation targetting annos on normal types (uses pattern) - source weaving"> + <compile files="BaseTypes.java,DecaTypeBin9.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="warning" line="8" text="A is not a valid target for annotation ColorA"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - trying to put annotation targetting annos on normal types (uses pattern) - binary weaving"> + <weave classesFiles="BaseTypes.java" aspectsFiles="DecaTypeBin9.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="warning" line="8" text="A is not a valid target for annotation ColorA"/> + </weave> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - covering enum and class element values - source weaving"> + <compile files="EnumAndClassValues.aj,FunkyAnnotations.java" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="FunkyAnnotations"> + <stderr> + <line text="hello world"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare @type - covering enum and class element values - binary weaving"> + <weave aspectsFiles="EnumAndClassValues.aj" classesFiles="FunkyAnnotations.java" options="-1.9 -Xdev:Pinpoint" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="FunkyAnnotations"> + <stderr> + <line text="advice running: Red"/> + <line text="advice running: class java.lang.Integer"/> + <line text="method running"/> + </stderr> + </run> + </ajc-test> + + + <!-- ======================================================================================= --> + <!-- declare annotation (@field) --> + <!-- ======================================================================================= --> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - simple source weaving"> + <compile files="Base.java,Colored.java,AtField1.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Colored field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - simple binary weaving"> + <weave classesFiles="Base.java,Colored.java" aspectsFiles="AtField1.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Colored field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - two the same on one - source weaving"> + <compile files="Base.java,Colored.java,TwoOnOneField.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="warning" text="int Base.publicIntField - already has an annotation of type Colored"/> + </compile> + <run class="Base"> + <stderr> + <line text="Colored field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - two the same on one - binary weaving"> + <weave classesFiles="Base.java,Colored.java" aspectsFiles="TwoOnOneField.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="warning" text="int Base.publicIntField - already has an annotation of type Colored"/> + </weave> + <run class="Base"> + <stderr> + <line text="Colored field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - two different on one - source weaving"> + <compile files="Base.java,Colored.java,Fruit.java,TwoOnOneField2.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + </compile> + <run class="Base"> + <stderr> + <line text="Colored field access at set(int Base.publicIntField)"/> + <line text="Fruit field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - two different on one - binary weaving"> + <weave classesFiles="Base.java,Colored.java,Fruit.java" aspectsFiles="TwoOnOneField2.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + </weave> + <run class="Base"> + <stderr> + <line text="Colored field access at set(int Base.publicIntField)"/> + <line text="Fruit field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - wrong target - source weaving"> + <compile files="Base.java,Colored.java,WrongTarget.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="error" line="8" text="The annotation @MethodColoring is disallowed for this location"/> + <message kind="error" line="9" text="The annotation @TypeColoring is disallowed for this location"/> + <!-- xlint warnings that were put in as part of fix for pr115252 --> + <message kind="warning" line="13" text="does not match because annotation @MethodColoring has @Target{ElementType.METHOD} [Xlint:unmatchedTargetKind]"/> + <message kind="warning" line="16" text="does not match because annotation @TypeColoring has @Target{ElementType.TYPE} [Xlint:unmatchedTargetKind]"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - right target - source weaving"> + <compile files="Base.java,Colored.java,RightTarget.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Colored field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - right target - binary weaving"> + <weave classesFiles="Base.java,Colored.java" aspectsFiles="RightTarget.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Colored field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - recursive application - source weaving"> + <compile files="Base.java,Colored.java,Fruit.java,RecursiveFields.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Fruit field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - recursive application - binary weaving"> + <weave classesFiles="Base.java,Colored.java,Fruit.java" aspectsFiles="RecursiveFields.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Fruit field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - recursive application (other order) - source weaving"> + <compile files="Base.java,Colored.java,Fruit.java,RecursiveFields2.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Fruit field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atfield" title="declare @field - recursive application (other order) - binary weaving"> + <weave classesFiles="Base.java,Colored.java,Fruit.java" aspectsFiles="RecursiveFields2.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Fruit field access at set(int Base.publicIntField)"/> + </stderr> + </run> + </ajc-test> + <!-- incorrect target type for annotation on field --> + + <!-- incorrect target type for annotation on method --> + <!-- two annotations on one method --> + <!-- two of the same annotation on one method - error --> + <!-- two of the same on one using pattern spec - lint --> + +<!-- need some incorrect signatures in the declare @statements - e.g. declare @constructor: public Base(int): XXX; will blow things up as it uses Base rather than new --> + <!-- incorrect target type for annotation on ctor --> + <!-- two annotations on one ctor --> + <!-- two of the same annotation on one ctor - error --> + <!-- two of the same on one using pattern spec - lint --> + + <ajc-test dir="java5/annotations/declare/atmethodctor" title="declare @method - simple source weaving"> + <compile files="Base.java,Colored.java,AtMethod1.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Colored method invocation at call(void Base.m1())"/> + <line text="m1() running"/> + <line text="m2() running"/> + <line text="m3() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atmethodctor" title="declare @method - simple binary weaving"> + <weave classesFiles="Base.java,Colored.java" aspectsFiles="AtMethod1.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Colored method invocation at call(void Base.m1())"/> + <line text="m1() running"/> + <line text="m2() running"/> + <line text="m3() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atmethodctor" title="declare @constructor - simple source weaving"> + <compile files="Base.java,Colored.java,AtCtor1.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Colored constructor invocation at call(Base(int))"/> + <line text="m1() running"/> + <line text="m2() running"/> + <line text="m3() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atmethodctor" title="declare @constructor - simple binary weaving"> + <weave classesFiles="Base.java,Colored.java" aspectsFiles="AtCtor1.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Colored constructor invocation at call(Base(int))"/> + <line text="m1() running"/> + <line text="m2() running"/> + <line text="m3() running"/> + </stderr> + </run> + </ajc-test> + + + <!-- These tests verify both @method and @ctor behavior - they are so similar it is OK to have them together... --> + + <ajc-test dir="java5/annotations/declare/atmethodctor" title="declare @method @ctor - wrong target - source weaving"> + <compile files="Base.java,Colored.java,WrongTarget.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="error" line="8" text="The annotation @MethodColoring is disallowed for this location"/> + <message kind="error" line="9" text="The annotation @TypeColoring is disallowed for this location"/> + <message kind="error" line="10" text="The annotation @MethodColoring is disallowed for this location"/> + <message kind="error" line="11" text="The annotation @TypeColoring is disallowed for this location"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atmethodctor" title="declare @method @ctor - right target - source weaving"> + <compile files="Base.java,Colored.java,RightTarget.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Colored ctor call at call(Base(int))"/> + <line text="Colored method call at call(void Base.m1())"/> + <line text="m1() running"/> + <line text="m2() running"/> + <line text="m3() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atmethodctor" title="declare @method @ctor - right target - binary weaving"> + <weave classesFiles="Base.java,Colored.java" aspectsFiles="RightTarget.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="Base"> + <stderr> + <line text="Colored ctor call at call(Base(int))"/> + <line text="Colored method call at call(void Base.m1())"/> + <line text="m1() running"/> + <line text="m2() running"/> + <line text="m3() running"/> + </stderr> + </run> + </ajc-test> + +<!-- check @method/@ctor/@field recursively applying, can only happen if a pattern for one of them includes an annotation --> + + + <ajc-test dir="java5/annotations/declare/atmethodctor" title="declare @method @ctor - two the same on one - source weaving"> + <compile files="Base.java,Colored.java,TwoOnOneMember.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="warning" text="void Base.m1() - already has an annotation of type Colored"/> + <message kind="warning" text="void Base.<init>(int) - already has an annotation of type Colored"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atmethodctor" title="declare @method @ctor - two the same on one - binary weaving"> + <weave classesFiles="Base.java,Colored.java" aspectsFiles="TwoOnOneMember.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + <message kind="warning" text="void Base.m1() - already has an annotation of type Colored"/> + <message kind="warning" text="void Base.<init>(int) - already has an annotation of type Colored"/> + </weave> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atmethodctor" title="declare @method @ctor - two different on one - source weaving"> + <compile files="Base.java,Colored.java,Fruit.java,TwoOnOneMember2.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + </compile> + <run class="Base"> + <stderr> + <line text="Colored ctor call at Base.java:11"/> + <line text="Fruit ctor call at Base.java:11"/> + <line text="Colored method call at Base.java:15"/> + <line text="Fruit method call at Base.java:15"/> + <line text="m1() running"/> + <line text="m2() running"/> + <line text="m3() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare/atmethodctor" title="declare @method @ctor - two different on one - binary weaving"> + <weave classesFiles="Base.java,Colored.java,Fruit.java" aspectsFiles="TwoOnOneMember2.aj" options="-1.9" xlintfile="ignoreTypeNotExposed.properties"> + </weave> + <run class="Base"> + <stderr> + <line text="Colored ctor call at Base.java:11"/> + <line text="Fruit ctor call at Base.java:11"/> + <line text="Colored method call at Base.java:15"/> + <line text="Fruit method call at Base.java:15"/> + <line text="m1() running"/> + <line text="m2() running"/> + <line text="m3() running"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/declare" title="declare all annotations on one class - source weaving"> + <compile files="DeathByAnnotations.aj" options="-1.9,-emacssym" xlintfile="ignoreTypeNotExposed.properties"/> + <run class="p.q.DeathByAnnotations"/> + </ajc-test> + + <!-- ======================================================================================= --> + <!-- annotation binding with ITDs --> + <!-- ======================================================================================= --> + + <ajc-test dir="java5/annotations/binding" title="simple binding annotation values where itd method is annotated"> + <compile files="BindingWithAnnotatedItds1.aj" options="-1.9"/> + <run class="BindingWithAnnotatedItds1"> + <stderr> + <line text="Found apple at jp execution(int A.m()) (BindingWithAnnotatedItds1.aj:8)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" title="simple binding annotation values where itd field is annotated"> + <compile files="BindingWithAnnotatedItds2.aj" options="-1.9"/> + <run class="BindingWithAnnotatedItds2"> + <stderr> + <line text="Found banana at jp set(int A.i) (BindingWithAnnotatedItds2.aj:16)"/> + <line text="Found apple at jp set(String A.j) (BindingWithAnnotatedItds2.aj:17)"/> + <line text="Found orange at jp set(int[] A.k) (BindingWithAnnotatedItds2.aj:18)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" title="simple binding annotation values where itd ctor is annotated"> + <compile files="BindingWithAnnotatedItds3.aj" options="-1.9"/> + <run class="BindingWithAnnotatedItds3"> + <stderr> + <line text="Found pear at jp execution(A(String)) (BindingWithAnnotatedItds3.aj:8)"/> + <line text="Found orange at jp execution(A(int)) (BindingWithAnnotatedItds3.aj:10)"/> + <line text="Found tomato at jp execution(A(boolean)) (BindingWithAnnotatedItds3.aj:12)"/> + </stderr> + </run> + </ajc-test> + + <!-- ======================================================================================= --> + <!-- declare annotation targetting ITDs --> + <!-- ======================================================================================= --> + + + <ajc-test dir="java5/annotations/binding" title="simple binding annotation values where itd method is annotated via declare"> + <compile files="BindingWithDeclaredAnnotationItds1.aj" options="-1.9,-emacssym"/> + <run class="BindingWithDeclaredAnnotationItds1"> + <stderr> + <line text="Found orange at jp call(int A.m()) (BindingWithDeclaredAnnotationItds1.aj:16)"/> + <line text="Found orange at jp execution(int A.m()) (BindingWithDeclaredAnnotationItds1.aj:8)"/> + <line text="Found banana at jp call(int A.n()) (BindingWithDeclaredAnnotationItds1.aj:17)"/> + <line text="Found banana at jp execution(int A.n()) (BindingWithDeclaredAnnotationItds1.aj:10)"/> + <line text="Found tomato at jp call(int A.o()) (BindingWithDeclaredAnnotationItds1.aj:18)"/> + <line text="Found tomato at jp execution(int A.o()) (BindingWithDeclaredAnnotationItds1.aj:12)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" title="simple binding annotation values where itd field is annotated via declare"> + <compile files="BindingWithDeclaredAnnotationItds2.aj" options="-1.9,-emacssym"/> + <run class="BindingWithDeclaredAnnotationItds2"> + <stderr> + <line text="Found orange at jp set(int A.i) (BindingWithDeclaredAnnotationItds2.aj:16)"/> + <line text="Found banana at jp set(String A.j) (BindingWithDeclaredAnnotationItds2.aj:17)"/> + <line text="Found apple at jp set(boolean[] A.k) (BindingWithDeclaredAnnotationItds2.aj:18)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" title="simple binding annotation values where itd field is annotated multiple times via declare"> + <compile files="BindingWithDeclaredAnnotationItds3.aj" options="-1.9,-emacssym"/> + <run class="BindingWithDeclaredAnnotationItds3"> + <stderr> + <line text="Found fruit orange at jp set(int A.i) (BindingWithDeclaredAnnotationItds3.aj:13)"/> + <line text="Found drink margarita at jp set(int A.i) (BindingWithDeclaredAnnotationItds3.aj:13)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/annotations/binding" title="simple binding annotation values where itd ctor is annotated via declare"> + <compile files="BindingWithDeclaredAnnotationItds4.aj" options="-1.9,-emacssym"/> + <run class="BindingWithDeclaredAnnotationItds4"> + <stderr> + <line text="Found pear at jp execution(A(String)) (BindingWithDeclaredAnnotationItds4.aj:8)"/> + <line text="Found orange at jp execution(A(int)) (BindingWithDeclaredAnnotationItds4.aj:10)"/> + <line text="Found tomato at jp execution(A(boolean)) (BindingWithDeclaredAnnotationItds4.aj:12)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/suppressedWarnings" title="SuppressAjWarnings raised during matching"> + <compile files="SuppressionDuringMatching.aj" options="-1.9"> + </compile> + </ajc-test> + + <!-- ============================================================== --> + + <ajc-test dir="options/aspectpath" title="dirs on aspectpath"> + <compile files="MyAspect.aj" options="-d out"/> + <compile files="MyClass.java" options="-aspectpath out"> + <message kind="warning" line="3" text="a method"/> + </compile> + </ajc-test> + + <!-- ============================================================== --> + <!-- Start of generics tests --> + <!-- ============================================================== --> + + <ajc-test dir="java5/generics" title="ITD with parameterized type" vm="1.5"> + <compile files="ITDReturningParameterizedType.aj" options="-1.9"/> + <run class="ITDReturningParameterizedType"/> + </ajc-test> + + <ajc-test dir="java5/annotations/binding/bugs" title="AtArgs causes a VerifyError: Unable to pop operand off an empty stack" vm="1.5"> + <compile files="Test3.java" options="-1.9"/> + <run class="Test3"/> + </ajc-test> + + <ajc-test dir="java5/generics/bugs/pr91267" title="NPE using generic methods in aspects 1" vm="1.5"> + <compile files="TestBug1.aj" options="-1.9"/> + <run class="TestBug1"/> + </ajc-test> + + <ajc-test dir="java5/generics/bugs/pr91267" title="NPE using generic methods in aspects 2" vm="1.5"> + <compile files="TestBug2.aj" options="-1.9"/> + <run class="TestBug2"/> + </ajc-test> + + <ajc-test dir="java5/generics/bugs" title="Generics problem with Set" vm="1.5"> + <compile files="PR91053.aj" options="-1.9"/> + <run class="PR91053"/> + </ajc-test> + + <ajc-test dir="java5/generics/bugs" title="Compilation error on generic member introduction" vm="1.5"> + <compile files="PR87282.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/bugs" title="Parameterized types on introduced fields not correctly recognized" vm="1.5"> + <compile files="PR88606.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" title="enum called Enum, annotation called Annotation, etc"> + <compile files="PR90827.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" title="Internal compiler error"> + <compile files="PR86832.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" title="Exploding compile time with if() statements in pointcut"> + <compile files="PR94086.aj" options="-1.9"/> + </ajc-test> + + <!-- generic abstract aspects... --> + + <ajc-test dir="java5/generics/genericaspects" title="static pointcut parameterization suite"> + <compile files="GenericAspectPointcuts.aj" options="-1.9"> + <message kind="warning" line="62" text="kinded-returning-ok"/> + <message kind="warning" line="52" text="kinded-declaring-ok"/> + <message kind="warning" line="67" text="kinded-declaring-ok"/> + <message kind="warning" line="50" text="kinded-params-ok"/> + <message kind="warning" line="56" text="kinded-throws-ok"/> + <message kind="warning" line="64" text="and-ok"/> + <message kind="warning" line="60" text="or-ok"/> + <message kind="warning" line="64" text="or-ok"/> + <message kind="warning" line="67" text="or-ok"/> + <message kind="warning" line="1" text="not-ok"/> + <message kind="warning" line="42" text="not-ok"/> + <message kind="warning" line="72" text="not-ok"/> + <message kind="warning" line="59" text="within-ok"/> + <message kind="warning" line="64" text="withincode-ok"/> + <message kind="warning" line="53" text="handler-ok"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="dynamic pointcut parameterization suite"> + <compile files="GenericAspectRuntimePointcuts.aj" options="-1.9"> + </compile> + <run class="GenericAspectRuntimePointcuts"> + <stdout> + <line text="target-ok an X execution(void X.foo())"/> + <line text="@this-ok @MyAnnotation(value=my-value) execution(void X.foo())"/> + <line text="@target-ok @MyAnnotation(value=my-value) execution(void X.foo())"/> + <line text="@within-ok @MyAnnotation(value=my-value) execution(void X.foo())"/> + <line text="cflow-ok an X a Y set(Y X.y)"/> + <line text="@annotation-ok-sub @MyAnnotation(value=bar) execution(void X.bar())"/> + <line text="@annotation-ok @MyAnnotation(value=bar) execution(void X.bar())"/> + <line text="target-ok an X execution(void X.bar())"/> + <line text="@this-ok @MyAnnotation(value=my-value) execution(void X.bar())"/> + <line text="@target-ok @MyAnnotation(value=my-value) execution(void X.bar())"/> + <line text="@within-ok @MyAnnotation(value=my-value) execution(void X.bar())"/> + <line text="@args-ok @MyAnnotation(value=my-value) execution(void Y.foo(X))"/> + <line text="args-ok an X execution(void Y.foo(X))"/> + <line text="this-ok a Y execution(void Y.foo(X))"/> + <line text="@this-ok @MyAnnotation(value=on Y) execution(void Y.foo(X))"/> + <line text="@target-ok @MyAnnotation(value=on Y) execution(void Y.foo(X))"/> + <line text="@within-ok @MyAnnotation(value=on Y) execution(void Y.foo(X))"/> + <line text="@annotation-ok-sub @MyAnnotation(value=my-value) execution(X Y.bar())"/> + <line text="@annotation-ok @MyAnnotation(value=my-value) execution(X Y.bar())"/> + <line text="this-ok a Y execution(X Y.bar())"/> + <line text="@this-ok @MyAnnotation(value=on Y) execution(X Y.bar())"/> + <line text="@target-ok @MyAnnotation(value=on Y) execution(X Y.bar())"/> + <line text="@within-ok @MyAnnotation(value=on Y) execution(X Y.bar())"/> + <line text="@withincode-ok @MyAnnotation(value=my-value) get(X Y.x)"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="reference to pointcut in generic class"> + <compile files="PointcutsInGenericClasses.aj" options="-1.9"> + <message kind="warning" line="16" text="a match"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="reference to non-parameterized pointcut in generic class"> + <compile files="PointcutsInGenericClasses2.aj" options="-1.9"> + <message kind="error" line="10" text="cannot use a raw type reference to refer to a pointcut in a generic type (use a parameterized reference instead)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="declare parents parameterized"> + <compile files="DecPGenericTest.aj" options="-1.9"> + <message kind="warning" line="16" text="success"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="declare precedence parameterized"> + <compile files="DecPrecedenceGenericTest.aj" options="-1.9 -Xdev:Pinpoint"> + </compile> + <run class="DecPrecedenceGenericTest"> + <stdout> + <line text="A1"/> + <line text="A2"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="declare annotation parameterized"> + <compile files="DecAnnGenericTest.aj" options="-1.9"> + <message kind="warning" line="18" text="@type ok"/> + <message kind="warning" line="20" text="@field ok"/> + <message kind="warning" line="22" text="@constructor ok"/> + <message kind="warning" line="24" text="@method ok"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="multi-level generic abstract aspects"> + <compile files="MultiLevelGenericTest.aj" options="-1.9"> + <message kind="warning" line="23" text="base match"/> + <message kind="warning" line="23" text="middle match"/> + <message kind="warning" line="23" text="top match"/> + </compile> + </ajc-test> + <!-- generic bugs --> + + <ajc-test dir="java5/generics/bugs" title="ITD method with generic arg"> + <compile files="PR97763.aj" options="-1.9"/> + <run class="PR97763"> + <stderr> + <line text="Number of entries=2"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="bugs150" title="NPE at ClassScope.java:660 when compiling generic class"> + <compile files="PR95993.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/bugs" title="Problems resolving type name inside generic class"> + <compile files="PR95992.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150" pr="100227" title="inner class with generic enclosing class"> + <compile files="pr100227.aj" options="-1.9"/> + <run class="pr100227"> + <stderr> + <line text="Outer.Inner.inner=2"/> + <line text="Outer.Inner.p() executing"/> + <line text="Generic_Outer.Inner.inner=4"/> + <line text="Generic_Outer.Inner.p() executing"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="bugs150" pr="100260" title="methods inherited from a generic parent"> + <compile files="pr100260.aj" options="-1.9"/> + <run class="pr100260"/> + </ajc-test> + + <!-- end of generic bugs --> + + <!-- generic aspects --> + + <ajc-test dir="java5/generics/genericaspects" title="generic aspects - 1"> + <compile files="GenericAspect1.aj" options="-1.9"> + <message kind="error" line="2" text="only abstract aspects can have type parameters"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="generic aspects - 2"> + <compile files="GenericAspect2.aj" options="-1.9"> + <message kind="error" line="9" text="a generic super-aspect must be fully parameterized in an extends clause"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="generic aspects - 3"> + <compile files="GenericAspect3.aj" options="-1.9"/> + <run class="GenericAspect3"> + <stderr> + <line text="A"/> + <line text="B"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="generic aspects - 4"> + <compile files="ParentChildRelationship.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="generic aspect with declare warning using type vars"> + <compile files="DeclareWarningInGenericAspect.aj" options="-1.9"> + <message kind="warning" line="16" text="this method takes a T!"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="generic aspect with execution advice using type vars"> + <compile files="ExecutionAdviceInGenericAspect.aj" options="-1.9"> + </compile> + <run class="ExecutionAdviceInGenericAspect"> + <stdout> + <line text="I matched at execution(void C.foo(String))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="generic aspect with anonymous pointcut"> + <compile files="AnonymousPointcutInGenericAspect.aj" options="-1.9"> + </compile> + <run class="AnonymousPointcutInGenericAspect"> + <stdout> + <line text="I matched at execution(void C.foo(String))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="generic aspect declare parents"> + <compile files="DeclareParentsWithTypeVars.aj" options="-1.9"> + </compile> + <run class="DeclareParentsWithTypeVars"> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/genericaspects" title="generic aspect declare soft"> + <compile files="DeclareSoftWithTypeVars.aj" options="-1.9"> + </compile> + <run class="DeclareSoftWithTypeVars"> + <stderr> + <line text="handled exception: io, io, it's off to work we go..."/> + <line text="Successfully converted to domain exception"/> + </stderr> + </run> + </ajc-test> + + <!-- ajdk example --> + <ajc-test dir="java5/generics/genericaspects" title="generic aspects - 5 (ajdk)"> + <compile files="Blob.java,BlobContainment.aj,ParentChildRelationship.aj" options="-1.9"/> + <run class="BlobContainment"/> + </ajc-test> + + <!-- same as above but all types in one file --> + <ajc-test dir="java5/generics/genericaspects" title="generic aspects - 6 (ajdk)"> + <compile files="TheBigOne.java" options="-1.9"/> + <run class="TheBigOne"/> + </ajc-test> + + <!-- end of generic aspects --> + + <!-- generic ITDs --> + + <ajc-test dir="java5/generics/itds" title="ITDs on generic type"> + <compile files="Parse5.java" options="-1.9"> + <message kind="error" line="9"/> + <message kind="error" line="11"/> + <message kind="error" line="13"/> + <message kind="error" line="15"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="itd of non static member"> + <compile files="A.java" options="-1.9"/> + <run class="A"> + <stderr> + <line text="min(2,4)=>2"/> + <line text="max(2,4)=>4"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="itd of static member"> + <compile files="B.java" options="-1.9"/> + <run class="B"> + <stderr> + <line text="min(2,4)=>2"/> + <line text="max(2,4)=>4"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="itd using type parameter"> + <compile files="C.java" options="-1.9"/> + <run class="C"> + <stderr> + <line text="fillthisin..."/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="itd incorrectly using type parameter"> + <compile files="D.java" options="-1.9"/> + <run class="D"> + <stderr> + <line text="fillthisin..."/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="static generic method itd"> + <compile files="StaticGenericMethodITD.aj" options="-1.9"/> + <run class="StaticGenericMethodITD"> + <stderr> + <line text="First=10"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic ctor itd - 1"> + <compile files="GenericCtorITD1.aj" options="-1.9"/> + <run class="GenericCtorITD1"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic ctor itd - 2"> + <compile files="GenericCtorITD2.aj" options="-1.9"/> + <run class="GenericCtorITD2"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic ctor itd - 3"> + <compile files="GenericCtorITD3.aj" options="-1.9"/> + <run class="GenericCtorITD3"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="parameterized method itd - 1"> + <compile files="ParameterizedMethodITD1.aj" options="-1.9"/> + <run class="ParameterizedMethodITD1"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="parameterized method itd - 2"> + <compile files="ParameterizedMethodITD2.aj" options="-1.9"> + <message kind="error" line="9" text="The method simple(List<? extends Number>) in the type Base is not applicable for the arguments (List<A>)"/> + </compile> + </ajc-test> + + + <ajc-test dir="java5/generics/itds" title="parameterized method itd - 3"> + <compile files="ParameterizedMethodITD3.aj" options="-1.9"> + <message kind="error" line="9" text="The method simple(List<? super A>) in the type Base is not applicable for the arguments (List<B>)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="parameterized method itd - 4"> + <compile files="ParameterizedMethodITD4.aj" options="-1.9"/> + <run class="ParameterizedMethodITD4"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 1"> + <compile files="GenericMethodITD1.aj" options="-1.9"/> + <run class="GenericMethodITD1"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 2"> + <compile files="GenericMethodITD2.aj" options="-1.9"> + <message kind="error" line="9" text="Bound mismatch: The generic method simple(List<? extends E>) of type Base is not applicable for the arguments (List<A>). The inferred type A is not a valid substitute for the bounded parameter <E extends Number>"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 3"> + <compile files="GenericMethodITD3.aj" options="-1.9"/> + <run class="GenericMethodITD3"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 4"> + <compile files="GenericMethodITD4.aj" options="-1.9"/> + <run class="GenericMethodITD4"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 5"> + <compile files="GenericMethodITD5.aj" options="-1.9"> + <message kind="error" line="10" text="The method simple(List<E>, List<E>) in the type Base is not applicable for the arguments (List<A>, List<B>)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 6"> + <compile files="GenericMethodITD6.aj" options="-1.9"/> + <run class="GenericMethodITD6"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 7"> + <compile files="GenericMethodITD7.aj" options="-1.9"/> + <run class="GenericMethodITD7"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 8"> + <compile files="GenericMethodITD8.aj" options="-1.9"> + <message kind="error" line="10" text="The method simple(List<E>, List<? extends E>) in the type Base is not applicable for the arguments (List<Number>, List<String>)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 9"> + <compile files="GenericMethodITD9.aj" options="-1.9"/> + <run class="GenericMethodITD9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 10"> + <compile files="GenericMethodITD10.aj" options="-1.9"> + <message kind="error" line="10" text="Bound mismatch: The generic method crazy(List<R>) of type Base is not applicable for the arguments (List<A>). The inferred type A is not a valid substitute for the bounded parameter <R extends Comparable<? super R>>"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 11"> + <compile files="GenericMethodITD11.aj" options="-1.9"/> + <run class="GenericMethodITD11"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 12"> + <compile files="GenericMethodITD12.aj" options="-1.9"> + <message kind="error" line="10" text="Bound mismatch: The generic method crazy(List<R>) of type Base is not applicable for the arguments (List<A>). The inferred type A is not a valid substitute for the bounded parameter <R extends Foo<? extends R>>"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 13"> + <compile files="GenericMethodITD13.aj" options="-1.9"/> + <run class="GenericMethodITD13"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 14"> + <compile files="GenericMethodITD14.aj" options="-1.9"> + <message kind="error" line="10" text="Bound mismatch: The generic method crazy(List<R>) of type Base is not applicable for the arguments (List<A>). The inferred type A is not a valid substitute for the bounded parameter <R extends Foo<? super R>>"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 15"> + <compile files="GenericMethodITD15.aj" options="-1.9"/> + <run class="GenericMethodITD15"/> + </ajc-test> + + <!-- visibility --> + + <ajc-test dir="java5/generics/itds/visibility" title="public itds"> + <compile files="PublicITDs.aj" options="-1.9"/> + <run class="PublicITDs"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/visibility" title="private itds"> + <compile files="PrivateITDs.aj" options="-1.9"/> + <run class="PrivateITDs"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/visibility" title="package itds"> + <compile files="PackageITDs.aj" options="-1.9"/> + <run class="PackageITDs"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/visibility" title="public itds with errors"> + <compile files="PublicITDsErrors.aj" options="-1.9"> + <message kind="error" line="13" text="The method publicMethod2(List<R>, List<R>) in the type Base is not applicable for the arguments (List<Double>, List<Float>)"/> + <message kind="error" line="15" text="The constructor Base(List<Double>, Map<Integer,String>) is undefined"/> + </compile> + </ajc-test> + + <!-- targetting different types --> + + <ajc-test dir="java5/generics/itds/differingTargets" title="targetting interface"> + <compile files="TargettingInterface.aj" options="-1.9"/> + <run class="TargettingInterface"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/differingTargets" title="targetting aspect"> + <compile files="TargettingAspect.aj" options="-1.9"/> + <run class="TargettingAspect"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/differingTargets" title="targetting class"> + <compile files="TargettingClass.aj" options="-1.9"/> + <run class="TargettingClass"/> + </ajc-test> + + <!-- sharing type variables between the ITD and the generic type --> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type - 1"> + <compile files="FieldA.aj" options="-1.9"/> + <run class="FieldA"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type - 2"> + <compile files="FieldB.aj" options="-1.9"> + <message kind="error" line="16" text="Incorrect number of type parameters supplied. The generic type Base<N,M> has 2 type parameters, not 1."/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type - 3"> + <compile files="FieldC.aj" options="-1.9"/> + <run class="FieldC"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type - 4"> + <compile files="FieldD.aj" options="-1.9"/> + <run class="FieldD"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type - 5"> + <compile files="FieldE.aj" options="-1.9"/> + <run class="FieldE"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type - 6"> + <compile files="FieldF.aj" options="-1.9"/> + <run class="FieldF"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type - 7"> + <compile files="FieldG.aj" options="-1.9"/> + <run class="FieldG"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type - 8"> + <compile files="FieldH.aj" options="-1.9"/> + <run class="FieldH"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type - 9"> + <compile files="FieldI.aj" options="-1.9"> + <message kind="error" line="7" text="Type mismatch: cannot convert from List<String> to List<Integer>"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type -10"> + <compile files="FieldJ.aj" options="-1.9"/> + <run class="FieldJ"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type -11"> + <compile files="FieldK.aj" options="-1.9"/> + <run class="FieldK"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type -12"> + <compile files="FieldL.aj" options="-1.9"/> + <run class="FieldL"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type -13"> + <compile files="FieldM.aj" options="-1.9"/> + <run class="FieldM"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type -14"> + <compile files="FieldN.aj" options="-1.9"> + <message kind="error" line="11" text="Type parameters can not be specified in the ITD target type - the target type I is not generic."/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type -15"> + <compile files="FieldO.aj" options="-1.9"> + <message kind="error" line="11" text="Intertype declarations can only be made on the generic type, not on a parameterized type. The name 'String' cannot be used as a type parameter, since it refers to a real type."/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type -16"> + <compile files="FieldP.aj" options="-1.9"> + <message kind="error" line="10" text="static intertype field declarations cannot refer to type variables from the target generic type"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd using type variable from target type -17"> + <compile files="FieldQ.aj" options="-1.9"/> + <run class="FieldQ"/> + </ajc-test> + + <!-- Now intertype declared methods on generic types that use the target types type vars --> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - A1"> + <compile files="MethodA.aj" options="-1.9"/> + <run class="MethodA"/> + </ajc-test> + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - A2"> + <compile files="MethodA2.aj" options="-1.9"/> + <run class="MethodA2"/> + </ajc-test> + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - A3"> + <compile files="MethodA3.aj" options="-1.9"/> + <run class="MethodA3"/> + </ajc-test> + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - A4"> + <compile files="MethodA4.aj" options="-1.9"/> + <run class="MethodA4"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - B1"> + <compile files="MethodB.aj" options="-1.9"> + <message kind="error" line="16" text="Incorrect number of type parameters supplied. The generic type Base<N,M> has 2 type parameters, not 1."/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - C1"> + <compile files="MethodC.aj" options="-1.9"/> + <run class="MethodC"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - D1"> + <compile files="MethodD.aj" options="-1.9"/> + <run class="MethodD"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - E1"> + <compile files="MethodE.aj" options="-1.9"/> + <run class="MethodE"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - F1"> + <compile files="MethodF.aj" options="-1.9"/> + <run class="MethodF"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - G1"> + <compile files="MethodG.aj" options="-1.9"/> + <run class="MethodG"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - H1"> + <compile files="MethodH.aj" options="-1.9"/> + <run class="MethodH"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - I1"> + <compile files="MethodI.aj" options="-1.9"> + <message kind="error" line="6" text="Type mismatch: cannot convert from List<Integer> to List<String>"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - I2"> + <compile files="MethodI2.aj" options="-1.9"> + <message kind="error" line="7" text="The method m(List<Integer>) in the type Base<Integer> is not applicable for the arguments (List<String>)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - J1"> + <compile files="MethodJ.aj" options="-1.9"/> + <run class="MethodJ"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - K1"> + <compile files="MethodK.aj" options="-1.9"/> + <run class="MethodK"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - L1"> + <compile files="MethodL.aj" options="-1.9"/> + <run class="MethodL"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - M1"> + <compile files="MethodM.aj" options="-1.9"/> + <run class="MethodM"/> + </ajc-test> + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - M2"> + <compile files="MethodM2.aj" options="-1.9"/> + <run class="MethodM2"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - N1"> + <compile files="MethodN.aj" options="-1.9"> + <message kind="error" line="11" text="Type parameters can not be specified in the ITD target type - the target type I is not generic."/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - O1"> + <compile files="MethodO.aj" options="-1.9"> + <message kind="error" line="11" text="Intertype declarations can only be made on the generic type, not on a parameterized type. The name 'String' cannot be used as a type parameter, since it refers to a real type."/> + </compile> + </ajc-test> + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - O2"> + <compile files="MethodO2.aj" options="-1.9"> + <message kind="error" line="11" text="Intertype declarations can only be made on the generic type, not on a parameterized type. The name 'String' cannot be used as a type parameter, since it refers to a real type."/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - P1"> + <compile files="MethodP.aj" options="-1.9"/> + <run class="MethodP"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd using type variable from target type - Q1"> + <compile files="MethodQ.aj" options="-1.9"/> + <run class="MethodQ"/> + </ajc-test> + + <!-- Now intertype declared constructors on generic types that use the target types type vars --> + + <ajc-test dir="java5/generics/itds/sharing" title="ctor itd using type variable from target type - A1"> + <compile files="CtorA.aj" options="-1.9"/> + <run class="CtorA"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="ctor itd using type variable from target type - B1"> + <compile files="CtorB.aj" options="-1.9"> + <message kind="error" line="15" text="Incorrect number of type parameters supplied. The generic type Base<N,M> has 2 type parameters, not 1."/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="ctor itd using type variable from target type - C1"> + <compile files="CtorC.aj" options="-1.9"/> + <run class="CtorC"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="ctor itd using type variable from target type - D1"> + <compile files="CtorD.aj" options="-1.9"/> + <run class="CtorD"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="ctor itd using type variable from target type - E1"> + <compile files="CtorE.aj" options="-1.9"/> + <run class="CtorE"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="ctor itd using type variable from target type - F1"> + <compile files="CtorF.aj" options="-1.9"/> + <run class="CtorF"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="ctor itd using type variable from target type - G1"> + <compile files="CtorG.aj" options="-1.9"/> + <run class="CtorG"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="ctor itd using type variable from target type - H1"> + <compile files="CtorH.aj" options="-1.9"/> + <run class="CtorH"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="ctor itd using type variable from target type - I1"> + <compile files="CtorI.aj" options="-1.9"/> + <run class="CtorI"/> + </ajc-test> + + <!-- putting it all together, fields/methods/ctors and decps --> + + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - A"> + <compile files="GenericAspectA.aj" options="-1.9"/> + <run class="GenericAspectA"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - B"> + <compile files="GenericAspectB.aj" options="-1.9"/> + <run class="GenericAspectB"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - C"> + <compile files="GenericAspectC.aj" options="-1.9"/> + <run class="GenericAspectC"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - D"> + <compile files="GenericAspectD.aj" options="-1.9"/> + <run class="GenericAspectD"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - E"> + <compile files="GenericAspectE.aj" options="-1.9"/> + <run class="GenericAspectE"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - F"> + <compile files="GenericAspectF.aj" options="-1.9"/> + <run class="GenericAspectF"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - G"> + <compile files="GenericAspectG.aj" options="-1.9"/> + <run class="GenericAspectG"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - H"> + <compile files="GenericAspectH.aj" options="-1.9"> + <message kind="error" line="7" text="Type java.lang.String does not meet the specification for type parameter 1 (N extends java.lang.Number) in generic type GenericAspect$SimpleI"/> + <!-- see pr133307, shame about this --> + <!--message kind="error" line="16" text="The method m4(String) is undefined for the type Base"/--> + </compile> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - I"> + <compile files="GenericAspectI.aj" options="-1.9"/> + <run class="GenericAspectI"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - J"> + <compile files="GenericAspectJ.aj" options="-1.9"/> + <run class="GenericAspectJ"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - K"> + <compile files="GenericAspectK.aj" options="-1.9"> + <message kind="error" line="7" text="B does not meet the specification for type parameter 1 (L extends java.lang.Number) in generic type GenericAspect$SimpleI"/> + <message kind="error" line="16" text="The method m4(String) is undefined for the type Base"/> + </compile> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - K2"> + <compile files="GenericAspectK2.aj" options="-1.9"> + <message kind="error" line="13" text="The type String is not a valid substitute"/> + </compile> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - L"> + <compile files="GenericAspectL.aj" options="-1.9"/> + <run class="GenericAspectL"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - M"> + <compile files="GenericAspectM.aj" options="-1.9"> + <message kind="error" line="23" text="The method m0(Integer) in the type GenericAspect.SimpleI<Integer> is not applicable for the arguments (String)"/> + <message kind="error" line="24" text="The method m1(List<Integer>) in the type GenericAspect.SimpleI<Integer> is not applicable for the arguments (List<String>)"/> + <message kind="error" line="25" text="Type mismatch: cannot convert from String to Integer"/> + <message kind="error" line="26" text="Type mismatch: cannot convert from List<String> to List<Integer>"/> + </compile> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - N"> + <compile files="GenericAspectN.aj" options="-1.9"/> + <run class="GenericAspectN"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - O"> + <compile files="GenericAspectO.aj" options="-1.9"> + <message kind="error" line="24" text="Cannot make a static reference to the non-static field Bottom.parent"/> + <message kind="error" line="26" text="The method add(Bottom) in the type List<Bottom> is not applicable for the arguments (Top)"/> + <message kind="error" line="27" text="Cannot make a static reference to the non-static field Top.children"/> + </compile> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - P"> + <compile files="GenericAspectP.aj" options="-1.9"/> + <run class="GenericAspectP"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - Q"> + <compile files="GenericAspectQ.aj" options="-1.9"/> + <run class="GenericAspectQ"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - R"> + <compile files="GenericAspectR.aj" options="-1.9"/> + <run class="GenericAspectR"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - S"> + <compile files="GenericAspectS.aj" options="-1.9"/> + <run class="GenericAspectS"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - T"> + <compile files="GenericAspectT.aj" options="-1.9"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - U"> + <compile files="GenericAspectU.aj" options="-1.9"/> + <run class="GenericAspectU"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - V"> + <compile files="GenericAspectV.aj" options="-1.9"/> + <run class="GenericAspectV"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - W"> + <compile files="GenericAspectW.aj" options="-1.9"/> + <run class="GenericAspectW"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - X"> + <compile files="GenericAspectX.aj" options="-1.9"/> + <run class="GenericAspectX"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - Y"> + <compile files="GenericAspectY.aj" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Join point 'method-execution(void ParentChildRelationship$ParentHasChildren.addChild(C))' in Type 'ParentChildRelationship' (GenericAspectY.aj:53) advised by before advice from 'GenericAspectY' (GenericAspectY.aj:101) [with runtime test]"/> + <message kind="weave" text="Extending interface set for type 'Top' (GenericAspectY.aj) to include 'ParentChildRelationship$ParentHasChildren<Bottom>' (GenericAspectY.aj)"/> + <message kind="weave" text="Type 'Top' (GenericAspectY.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectY.aj:'java.util.List<Bottom> ParentChildRelationship$ParentHasChildren.children')"/> + <message kind="weave" text="Type 'Top' (GenericAspectY.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectY.aj:'java.util.List<Bottom> ParentChildRelationship$ParentHasChildren.getChildren()')"/> + <message kind="weave" text="Type 'Top' (GenericAspectY.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectY.aj:'void ParentChildRelationship$ParentHasChildren.addChild(Bottom)')"/> + <message kind="weave" text="Type 'Top' (GenericAspectY.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectY.aj:'void ParentChildRelationship$ParentHasChildren.removeChild(Bottom)')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectY.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectY.aj:'java.util.List<C> ParentChildRelationship$ParentHasChildren.children')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectY.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectY.aj:'java.util.List<C> ParentChildRelationship$ParentHasChildren.getChildren()')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectY.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectY.aj:'void ParentChildRelationship$ParentHasChildren.addChild(C)')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectY.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectY.aj:'void ParentChildRelationship$ParentHasChildren.removeChild(C)')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ChildHasParent' (GenericAspectY.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectY.aj:'P ParentChildRelationship$ChildHasParent.parent')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ChildHasParent' (GenericAspectY.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectY.aj:'P ParentChildRelationship$ChildHasParent.getParent()')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ChildHasParent' (GenericAspectY.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectY.aj:'void ParentChildRelationship$ChildHasParent.setParent(P)')"/> + <message kind="weave" text="Extending interface set for type 'Bottom' (GenericAspectY.aj) to include 'ParentChildRelationship$ChildHasParent<Top>' (GenericAspectY.aj)"/> + <message kind="weave" text="Type 'Bottom' (GenericAspectY.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectY.aj:'Top ParentChildRelationship$ChildHasParent.parent')"/> + <message kind="weave" text="Type 'Bottom' (GenericAspectY.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectY.aj:'Top ParentChildRelationship$ChildHasParent.getParent()')"/> + <message kind="weave" text="Type 'Bottom' (GenericAspectY.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectY.aj:'void ParentChildRelationship$ChildHasParent.setParent(Top)')"/> + </compile> + <run class="GenericAspectY"/> + </ajc-test> + <ajc-test dir="java5/generics/genericaspects/" title="uberaspects - Z"> + <compile files="GenericAspectZ.aj" options="-1.9 -showWeaveInfo"> + <message kind="weave" text="Join point 'method-execution(void ParentChildRelationship$ParentHasChildren.addChild(C))' in Type 'ParentChildRelationship' (GenericAspectZ.aj:53) advised by before advice from 'GenericAspectZ' (GenericAspectZ.aj:95) [with runtime test]"/> + <message kind="weave" text="Join point 'method-execution(void ParentChildRelationship$ParentHasChildren.removeChild(C))' in Type 'ParentChildRelationship' (GenericAspectZ.aj:65) advised by before advice from 'GenericAspectZ' (GenericAspectZ.aj:96) [with runtime test]"/> + + <message kind="weave" text="Extending interface set for type 'Top' (GenericAspectZ.aj) to include 'ParentChildRelationship$ParentHasChildren<Bottom>' (GenericAspectZ.aj)"/> + <message kind="weave" text="Type 'Top' (GenericAspectZ.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectZ.aj:'java.util.List<Bottom> ParentChildRelationship$ParentHasChildren.children')"/> + <message kind="weave" text="Type 'Top' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'java.util.List<Bottom> ParentChildRelationship$ParentHasChildren.getChildren()')"/> + <message kind="weave" text="Type 'Top' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ParentHasChildren.addChild(Bottom)')"/> + <message kind="weave" text="Type 'Top' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ParentHasChildren.removeChild(Bottom)')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectZ.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectZ.aj:'java.util.List<C> ParentChildRelationship$ParentHasChildren.children')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'java.util.List<C> ParentChildRelationship$ParentHasChildren.getChildren()')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ParentHasChildren.addChild(C)')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ParentHasChildren.removeChild(C)')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ChildHasParent' (GenericAspectZ.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectZ.aj:'P ParentChildRelationship$ChildHasParent.parent')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ChildHasParent' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'P ParentChildRelationship$ChildHasParent.getParent()')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ChildHasParent' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ChildHasParent.setParent(P)')"/> + <message kind="weave" text="Extending interface set for type 'Bottom' (GenericAspectZ.aj) to include 'ParentChildRelationship$ChildHasParent<Top>' (GenericAspectZ.aj)"/> + <message kind="weave" text="Type 'Bottom' (GenericAspectZ.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectZ.aj:'Top ParentChildRelationship$ChildHasParent.parent')"/> + <message kind="weave" text="Type 'Bottom' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'Top ParentChildRelationship$ChildHasParent.getParent()')"/> + <message kind="weave" text="Type 'Bottom' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ChildHasParent.setParent(Top)')"/> + + <!--message kind="weave" text="Extending interface set for type 'Top' (GenericAspectZ.aj) to include 'ParentChildRelationship$ParentHasChildren<Bottom>' (GenericAspectZ.aj)"/> + <message kind="weave" text="Type 'Top' (GenericAspectZ.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectZ.aj:'java.util.List<C> ParentChildRelationship$ParentHasChildren.children')"/> + <message kind="weave" text="Type 'Top' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'java.util.List<C> ParentChildRelationship$ParentHasChildren.getChildren()')"/> + <message kind="weave" text="Type 'Top' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ParentHasChildren.addChild(C)')"/> + <message kind="weave" text="Type 'Top' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ParentHasChildren.removeChild(C)')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectZ.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectZ.aj:'java.util.List<C> ParentChildRelationship$ParentHasChildren.children')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'java.util.List<C> ParentChildRelationship$ParentHasChildren.getChildren()')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ParentHasChildren.addChild(C)')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ParentHasChildren' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ParentHasChildren.removeChild(C)')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ChildHasParent' (GenericAspectZ.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectZ.aj:'ParentChildRelationship$ParentHasChildren ParentChildRelationship$ChildHasParent.parent')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ChildHasParent' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'ParentChildRelationship$ParentHasChildren ParentChildRelationship$ChildHasParent.getParent()')"/> + <message kind="weave" text="Type 'ParentChildRelationship$ChildHasParent' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ChildHasParent.setParent(P)')"/> + <message kind="weave" text="Extending interface set for type 'Bottom' (GenericAspectZ.aj) to include 'ParentChildRelationship$ChildHasParent<Top>' (GenericAspectZ.aj)"/> + <message kind="weave" text="Type 'Bottom' (GenericAspectZ.aj) has intertyped field from 'ParentChildRelationship' (GenericAspectZ.aj:'ParentChildRelationship$ParentHasChildren ParentChildRelationship$ChildHasParent.parent')"/> + <message kind="weave" text="Type 'Bottom' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'ParentChildRelationship$ParentHasChildren ParentChildRelationship$ChildHasParent.getParent()')"/> + <message kind="weave" text="Type 'Bottom' (GenericAspectZ.aj) has intertyped method from 'ParentChildRelationship' (GenericAspectZ.aj:'void ParentChildRelationship$ChildHasParent.setParent(P)')"/--> + </compile> + <run class="GenericAspectZ"/> + </ajc-test> + + <ajc-test dir="java5/generics/binaryBridging" title="binary bridge methods - two"> + <compile files="TwoA.java" outjar="twoa.jar" options="-1.9"/> + <compile files="TwoB.java" outjar="twob.jar" options="-1.9"/> + <compile files="TwoX.java" inpath="twoa.jar;twob.jar" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="method itd sharing type variable with generic type"> + <compile files="Simple.aj" options="-1.9"/> + <run class="Simple"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/sharing" title="field itd sharing type variable with generic type"> + <compile files="Simple2.aj" options="-1.9"/> + <run class="Simple2"/> + </ajc-test> + + + <ajc-test dir="java5/generics/itds" title="non static generic method itd - 2"> + <compile files="NonstaticGenericCtorITD2.aj" options="-1.9"/> + <run class="NonstaticGenericCtorITD2"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="reusing type variable letters"> + <compile files="ReusingLetters.aj" options="-1.9"/> + <run class="ReusingLetters"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="multiple generic itds in one file"> + <compile files="BizarroSignatures.aj" options="-1.9"/> + <run class="BizarroSignatures"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic intertype field declaration, sharing type variable"> + <compile files="FieldITDOnGenericType.aj" options="-1.9"/> + <run class="FieldITDOnGenericType"> + <stderr> + <line text=">42"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="Parsing generic ITDs - 1"> + <compile files="Parse1.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="Parsing generic ITDs - 2"> + <compile files="Parse2.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="Parsing generic ITDs - 3"> + <compile files="Parse3.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="Parsing generic ITDs - 4"> + <compile files="Parse4.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="Parsing generic ITDs - 5"> + <compile files="Parse5.java" options="-1.9"> + <message kind="error" line="11" text="Incorrect number of type parameters supplied. The generic type Parse5<T,S> has 2 type parameters, not 3."/> + <message kind="error" line="13" text="Incorrect number of type parameters supplied. The generic type Parse5<T,S> has 2 type parameters, not 1."/> + <message kind="error" line="15" text="Intertype declarations can only be made on the generic type, not on a parameterized type. The name 'String' cannot be used as a type parameter, since it refers to a real type."/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="Parsing generic ITDs - 6"> + <compile files="Parse6.java" options="-1.9"/> + </ajc-test> + + <!-- end of generic ITDs --> + + <!-- generic decps --> + + <ajc-test dir="java5/generics/decp" title="generic decp - simple"> + <compile files="Basic.aj" options="-1.9"/> + <run class="Basic"/> + </ajc-test> + + <ajc-test dir="java5/generics/decp" title="generic decp - implementing two variants #1"> + <compile files="Basic2.aj" options="-1.9"> + <message kind="error" line="11" text="Cannot declare parent I<java.lang.Integer> onto type Basic2 since it already has I<java.lang.String> in its hierarchy"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/decp" title="generic decp - implementing two variants #2"> + <compile files="Basic2b.aj" options="-1.9"> + <message kind="error" line="10" text="Cannot declare parent I<java.lang.Integer> onto type Basic2b since it already has I in its hierarchy"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/decp" title="generic decp - implementing two variants #3"> + <compile files="Basic2c.aj" options="-1.9"> + <message kind="error" line="10" text="Cannot declare parent I onto type Basic2c since it already has I<java.lang.Double> in its hierarchy"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/decp" title="generic decp - implementing two variants #4"> + <compile files="Basic2d.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/decp/binary" title="generic decp binary - implementing two variants #1"> + <weave classesFiles="Base1.java" aspectsFiles="Asp1.aj" options="-1.9,-showWeaveInfo"> + <message kind="error" line="2" text="Cannot declare parent I<java.lang.Integer> onto type Base1 since it already has I<java.lang.String> in its hierarchy"/> + </weave> + </ajc-test> + + <ajc-test dir="java5/generics/decp/binary" title="generic decp binary - implementing two variants #2"> + <weave classesFiles="Base2.java" aspectsFiles="Asp2.aj" options="-1.9,-showWeaveInfo"> + <message kind="error" line="2" text="Cannot declare parent I<java.lang.Integer> onto type Base2 since it already has I in its hierarchy"/> + </weave> + </ajc-test> + + <ajc-test dir="java5/generics/decp/binary" title="generic decp binary - implementing two variants #3"> + <weave classesFiles="Base3.java" aspectsFiles="Asp3.aj" options="-1.9,-showWeaveInfo"> + <message kind="error" line="2" text="Cannot declare parent I onto type Base3 since it already has I<java.lang.Double> in its hierarchy"/> + </weave> + </ajc-test> + + <ajc-test dir="java5/generics/decp/binary" title="generic decp binary - implementing two variants #4"> + <weave classesFiles="Base4.java" aspectsFiles="Asp4.aj" options="-1.9,-showWeaveInfo"/> + </ajc-test> + + <ajc-test dir="java5/generics/decp" title="generic decp - incorrect number of type parameters"> + <compile files="Basic3.aj" options="-1.9"> + <message kind="error" line="10" text="Type pattern does not match because the wrong number of type parameters are specified: Type I requires 1 parameter(s)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/decp" title="generic decp - specifying bounds"> + <compile files="Basic4.aj" options="-1.9"/> + <run class="Basic4"/> + </ajc-test> + + <ajc-test dir="java5/generics/decp" title="generic decp - specifying bounds but breaking them"> + <compile files="Basic5.aj" options="-1.9"> + <message kind="error" line="7" text="Type java.lang.String does not meet the specification for type parameter 1 (T extends java.lang.Number) in generic type I"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/decp" title="generic decp - with parameterized on the target"> + <compile files="Basic6.aj" options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Extending interface set for type 'Basic6' (Basic6.aj) to include 'K<java.lang.Integer>' (Basic6.aj)"/> + </compile> + <run class="Basic6"/> + </ajc-test> + + <!-- end of generic decps --> + + <!-- generics/itds and binary weaving --> + + <ajc-test dir="java5/generics/itds/binaryweaving" vm="1.5" title="binary weaving ITDs - A"> + <compile files="TestA_generictype.java" outjar="code.jar" options="-1.9"/> + <compile files="TestA_aspect.aj,TestA_class.java" inpath="code.jar" options="-1.9"/> + <run class="TestA_class"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/binaryweaving" vm="1.5" title="binary weaving ITDs - B"> + <compile files="TestB_generictype.java" outjar="code.jar" options="-1.9"/> + <compile files="TestB_aspect1.aj,TestB_aspect2.aj,TestB_class.java" inpath="code.jar" options="-1.9"/> + <run class="TestB_class"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/binaryweaving" vm="1.5" title="binary weaving ITDs - 1"> + <compile files="BaseClass.java" outjar="code.jar" options="-1.9"/> + <compile files="A1.aj" inpath="code.jar" options="-1.9"/> + <run class="BaseClass"> + <stderr> + <line text="Advice count=1"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds/binaryweaving" vm="1.5" title="binary weaving ITDs - 2"> + <compile files="BaseClass.java,A1.aj" outjar="code.jar" options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'BaseClass' (BaseClass.java) has intertyped field from 'A1' (A1.aj:'java.util.List<java.lang.String> BaseClass.list1')"/> + <message kind="weave" text="Type 'BaseClass' (BaseClass.java:12) advised by after advice from 'A1' (A1.aj:7)"/> + </compile> + <compile files="A2.aj" inpath="code.jar" options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'BaseClass' (BaseClass.java) has intertyped field from 'A1' (A1.aj:'java.util.List<java.lang.String> BaseClass.list1')"/> + <message kind="weave" text="Type 'BaseClass' (BaseClass.java:12) advised by after advice from 'A1' (code.jar!A1.class:7(from A1.aj))"/> + <message kind="weave" text="Type 'BaseClass' (BaseClass.java) has intertyped field from 'A2' (A2.aj:'java.util.List<N> BaseClass.list2')"/> + <message kind="weave" text="Type 'BaseClass' (BaseClass.java:13) advised by after advice from 'A2' (A2.aj:8)"/> + </compile> + <run class="BaseClass"> + <stderr> + <line text="Advice count=2"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds/binaryweaving" vm="1.5" title="binary weaving ITDs - 3"> + <compile files="BaseClass.java,A1.aj,A2.aj" outjar="code.jar" options="-1.9"/> + <compile files="A3.aj" inpath="code.jar" options="-1.9"/> + <run class="BaseClass"> + <stderr> + <line text="Advice count=3"/> + </stderr> + </run> + </ajc-test> + + <!-- end of generics/itds and binary weaving --> + + <!-- generics/itds and bridge methods --> + + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 1"> + <compile files="Sub1.java,Super1.java,X1.aj" options="-1.9"/> + <run class="X1"/> + </ajc-test> + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 1 - binary"> + <compile files="Sub1.java,Super1.java" outjar="code.jar" options="-1.9"/> + <compile files="X1.aj" inpath="code.jar" options ="-1.9"/> + <run class="X1"/> + </ajc-test> + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 2"> + <compile files="Sub2.java,Super2.java,X2.aj" options="-1.9"/> + <run class="X2"/> + </ajc-test> + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 2 - binary"> + <compile files="Sub2.java,Super2.java" outjar="code.jar" options="-1.9"/> + <compile files="X2.aj,Util.java" inpath="code.jar" options ="-1.9"/> + <run class="X2"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 3"> + <compile files="Sub3.java,Super3.java,X3.aj" options="-1.9"/> + <run class="X3"/> + </ajc-test> + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 3 - binary"> + <compile files="Sub3.java,Super3.java" outjar="code.jar" options="-1.9"/> + <compile files="X3.aj" inpath="code.jar" options ="-1.9"/> + <run class="X3"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 4"> + <compile files="Sub4.java,Super4.java,X4.aj" options="-1.9"/> + <run class="X4"/> + </ajc-test> + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridge methods - 4 - binary"> + <compile files="Sub4.java,Super4.java" outjar="code.jar" options="-1.9"/> + <compile files="X4.aj" inpath="code.jar" options ="-1.9"/> + <run class="X4"/> + </ajc-test> + + <ajc-test dir="java5/generics/binaryBridging" title="binary bridge methods - one"> + <compile files="OneA.java" outjar="onea.jar" options="-1.9"/> + <compile files="OneB.java" outjar="oneb.jar" options="-1.9"/> + <compile files="OneX.java" inpath="onea.jar;oneb.jar" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/binaryBridging" title="binary bridge methods - two"> + <compile files="TwoA.java" outjar="twoa.jar" options="-1.9"/> + <compile files="TwoB.java" outjar="twob.jar" options="-1.9"/> + <compile files="TwoX.java" inpath="twoa.jar;twob.jar" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/binaryBridging" title="binary bridge methods - three"> + <compile files="ThreeA.java" outjar="threea.jar" options="-1.9"/> + <compile files="ThreeB.java" outjar="threeb.jar" options="-1.9"/> + <compile files="ThreeX.java" inpath="threea.jar;threeb.jar" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="abstract intertype methods and covariant returns"> + <compile files="pr91381.aj" options="-1.9"/> + <run class="pr91381"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/bridgeMethods" title="abstract intertype methods and covariant returns - error"> + <compile files="pr91381_2.aj"> + <message kind="error" line="15" text="The return type is incompatible with A.foo()"/> + </compile> + </ajc-test> + + + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridging with covariance 1 - normal"> + <compile files="Bridging1.aj,Util.java" options="-1.9"/> + <run class="Bridging1"> + <stderr> + <line text="Number of methods defined for D is 2"/> + <line text="C D.method1() [BridgeMethod]"/> + <line text="D D.method1()"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="bridging with covariance 1 - itd"> + <compile files="BridgingITD1.aj,Util.java" options="-1.9"/> + <run class="BridgingITD1"> + <stderr> + <line text="Number of methods defined for D is 2"/> + <line text="C D.method1() [BridgeMethod]"/> + <line text="D D.method1()"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="basic bridging with type vars - 1 - normal"> + <compile files="Bridging2.aj,Util.java" options="-1.9"/> + <run class="Bridging2"> + <stderr> + <line text="Number of methods defined for D is 2"/> + <line text="java.lang.Object D.next() [BridgeMethod]"/> + <line text="java.lang.String D.next()"/> + </stderr> + </run> + </ajc-test> + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="basic bridging with type vars - 1 - itd"> + <compile files="BridgingITD2.aj,Util.java" options="-1.9"/> + <run class="BridgingITD2"> + <stderr> + <line text="Number of methods defined for D is 2"/> + <line text="java.lang.Object D.next() [BridgeMethod]"/> + <line text="java.lang.String D.next()"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="basic bridging with type vars - 2 - normal"> + <compile files="Bridging3.aj,Util.java" options="-1.9"/> + <run class="Bridging3"> + <stderr> + <line text="Number of methods defined for D is 2"/> + <line text="java.lang.Object D.id(java.lang.Object) [BridgeMethod]"/> + <line text="java.lang.String D.id(java.lang.String)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="basic bridging with type vars - 2 - itd"> + <compile files="BridgingITD3.aj,Util.java" options="-1.9"/> + <run class="BridgingITD3"> + <stderr> + <line text="Number of methods defined for D is 2"/> + <line text="java.lang.Object D.id(java.lang.Object) [BridgeMethod]"/> + <line text="java.lang.String D.id(java.lang.String)"/> + </stderr> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/itds/bridgeMethods" vm="1.5" title="Abstract intertype method and covariant returns" pr="91381"> + <compile files="pr91381.aj" options="-1.9,-showWeaveInfo"> + <message kind="weave" text="Type 'A' (pr91381.aj) has intertyped method from 'pr91381' (pr91381.aj:'java.lang.Object A.foo()')"/> + </compile> + <run class="pr91381"/> + </ajc-test> + <!-- end of generics/itds and bridge methods --> + + + <!-- generics and pointcuts --> + + <ajc-test dir="java5/generics/pointcuts" title="handler pcd and generics / type vars"> + <compile files="GenericInterface.java,HandlerPointcutTests.aj" options="-1.9"> + <message kind="error" line="4" text="Syntax error on token"/> + <message kind="error" line="8" text="a parameterized type pattern may not be used in a handler pointcut expression"/> + <message kind="warning" line="8" text="no match for this type name: T"/> + <message kind="error" line="11" text="a parameterized type pattern may not be used in a handler pointcut expression"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="pointcuts that dont allow type vars"> + <compile files="PointcutsThatDontAllowTypeVars.aj" options="-1.9"> + <message kind="error" line="3" text="Syntax error on token"/> + <message kind="error" line="5" text="Syntax error on token"/> + <message kind="error" line="7" text="Syntax error on token"/> + <message kind="error" line="9" text="Syntax error on token"/> + <message kind="error" line="11" text="Syntax error on token"/> + <message kind="error" line="13" text="Syntax error on token"/> + <message kind="error" line="15" text="Syntax error on token"/> + <message kind="error" line="17" text="Syntax error on token"/> + <message kind="error" line="19" text="Syntax error on token"/> + <message kind="error" line="21" text="Syntax error on token"/> + <message kind="error" line="23" text="Syntax error on token"/> + <message kind="error" line="25" text="Syntax error on token"/> + <message kind="error" line="27" text="Syntax error on token"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="annotation pcds with parameterized types"> + <compile files="ParameterizedTypesInAtPCDs.aj" options="-1.9"> + <message kind="error" line="3" text="Syntax error on token"/> + <message kind="error" line="5" text="Syntax error on token"/> + <message kind="error" line="7" text="Syntax error on token"/> + <message kind="error" line="9" text="Syntax error on token"/> + <message kind="error" line="11" text="Syntax error on token"/> + <message kind="error" line="13" text="Syntax error on token"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="annotation patterns with parameterized types"> + <compile files="ParameterizedTypesInAnnotationPatterns.aj" options="-1.9"> + <message kind="error" line="5" text="is not an annotation type"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="staticinitialization and parameterized types"> + <compile files="GenericInterface.java,GenericImplementingClass.java,StaticInitializationWithParameterizedTypes.aj" options="-1.9"> + <message kind="error" line="4" text="no static initialization join points for parameterized types, use raw type instead"/> + <message kind="error" line="6" text="no static initialization join points for parameterized types, use raw type instead"/> + <message kind="error" line="9" text="no static initialization join points for parameterized types, use raw type instead"/> + <message kind="error" line="11" text="no static initialization join points for parameterized types, use raw type instead"/> + <message kind="error" line="14" text="no static initialization join points for parameterized types, use raw type instead"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="staticinitialization and parameterized type matching"> + <compile files="GenericInterface.java,GenericImplementingClass.java,ConcreteImplementingClass.java,ConcreteExtendingClass.java,StaticInitializationWithParameterizedTypesMatching.aj" options="-1.9"> + <message kind="warning" line="1" text="clinit(GenericInterface<Double>+)"/> + <message kind="warning" line="3" text="clinit(GenericInterface<Double>+)"/> + <message kind="warning" line="3" text="clinit(GenericImplementingClass<Double>+)"/> + <message kind="warning" line="15" text="Type java.lang.String does not meet the specification for type parameter 1 (N extends java.lang.Number) in generic type GenericInterface"/> + <message kind="warning" line="19" text="Type pattern does not match because the wrong number of type parameters are specified: Type GenericInterface requires 1 parameter(s)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="staticinitialization with generic types"> + <compile files="GenericInterface.java,GenericImplementingClass.java,StaticInitializationWithGenericTypes.aj" options="-1.9"> + <message kind="warning" line="1" text="one generic param, correct bounds"/> + <message kind="warning" line="1" text="doesn't matter what type variable name you use"/> + <message kind="warning" line="1" text="works with classes too"/> + <message kind="warning" line="4" text="Type T does not meet the specification for type parameter 1 (N extends java.lang.Number) in generic type GenericInterface"/> + <message kind="warning" line="20" text="Type pattern does not match because the wrong number of type parameters are specified: Type GenericImplementingClass requires 1 parameter(s)"/> + <message kind="warning" line="24" text="Type N extends java.lang.Number & java.lang.Comparable does not meet the specification for type parameter 1 (N extends java.lang.Number) in generic type GenericImplementingClass"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="staticinitialization with generic types - advanced"> + <compile files="StaticInitializationWithGenericTypesAdvanced.aj" options="-1.9"> + <message kind="warning" line="76" text="simple match"/> + <message kind="warning" line="76" text="matches since R and R extends Object are equivalent"/> + <message kind="warning" line="63" text="raw type should match"/> + <message kind="warning" line="63" text="matches all bounds"/> + <message kind="warning" line="63" text="still matches with interfaces specified in a different order"/> + <message kind="warning" line="69" text="matches with type variable inter-dependencies"/> + <message kind="warning" line="76" text="matches any generic type with one unbound type var"/> + <message kind="warning" line="82" text="any generic type with one type var bound to Number or subtype"/> + <message kind="warning" line="63" text="matches a generic type with any upper bound and i/f bounds"/> + <message kind="warning" line="76" text="matches a generic type with any upper bound and i/f bounds"/> + <message kind="warning" line="82" text="matches a generic type with any upper bound and i/f bounds"/> + <message kind="warning" line="19" text="Type X does not meet the specification for type parameter 1 (T extends java.lang.Number & java.lang.Comparable & java.io.Serializable) in generic type ClassWithInterfaceBounds"/> + <message kind="warning" line="23" text="Type Y extends java.lang.Number does not meet the specification for type parameter 1 (T extends java.lang.Number & java.lang.Comparable & java.io.Serializable) in generic type ClassWithInterfaceBounds"/> + <message kind="warning" line="27" text="Type Z extends java.lang.Number & java.lang.Comparable does not meet the specification for type parameter 1 (T extends java.lang.Number & java.lang.Comparable & java.io.Serializable) in generic type ClassWithInterfaceBounds"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="within pcd with various parameterizations and generic types - errors"> + <compile files="WithinPointcutMatching.aj" options="-1.9"> + <message kind="warning" line="4" text="no match for this type name: T"/> + <message kind="error" line="4" text="parameterized type pattern not supported by 'within', use a raw type pattern instead"/> + <message kind="error" line="5" text="parameterized type pattern not supported by 'within', use a raw type pattern instead"/> + <message kind="error" line="6" text="parameterized type pattern not supported by 'within', use a raw type pattern instead"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="within pcd with various parameterizations and generic types - warnings"> + <compile files="WithinPointcutMatchingWarnings.aj" options="-1.9"> + <message kind="warning" line="16" text="matched set correctly"/> + <message kind="warning" line="18" text="matched execution correctly"/> + <message kind="warning" line="24" text="init matched correctly"/> + <message kind="warning" line="32" text="matched parameterization ok"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="this and target with various parameterizations and generic types - errors"> + <compile files="ThisAndTargetPointcutMatching.aj" options="-1.9"> + <message kind="warning" line="4" text="no match for this type name: T"/> + <message kind="warning" line="5" text="no match for this type name: T"/> + <message kind="error" line="4" text="parameterized types not supported for this and target pointcuts (erasure limitation)"/> + <message kind="error" line="5" text="parameterized types not supported for this and target pointcuts (erasure limitation)"/> + <message kind="error" line="6" text="parameterized types not supported for this and target pointcuts (erasure limitation)"/> + <message kind="error" line="7" text="parameterized types not supported for this and target pointcuts (erasure limitation)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="this and target with various parameterizations and generic types - runtime"> + <compile files="ThisAndTargetPointcutMatchingRuntime.aj" options="-1.9"> + </compile> + <run class="ThisAndTargetPointcutMatchingRuntime"> + <stdout> + <line text="set and this matched ok"/> + <line text="set and target matched ok"/> + <line text="call and target matched ok"/> + <line text="execution and this matched ok"/> + <line text="execution and target matched ok"/> + <line text="parameterized call and target matched ok"/> + <line text="parameterized call and this matched ok"/> + <line text="parameterized call and target matched ok"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="get and set with various parameterizations and generic types - errors"> + <compile files="GetAndSetPointcutMatching.aj" options="-1.9"> + <message kind="warning" line="4" text="no match for this type name: T"/> + <message kind="warning" line="5" text="no match for this type name: T"/> + <message kind="error" line="4" text="can't use parameterized type patterns for the declaring type of a get or set pointcut expression (use the raw type instead)"/> + <message kind="error" line="5" text="can't use parameterized type patterns for the declaring type of a get or set pointcut expression (use the raw type instead)"/> + <message kind="error" line="6" text="can't use parameterized type patterns for the declaring type of a get or set pointcut expression (use the raw type instead)"/> + <message kind="error" line="7" text="can't use parameterized type patterns for the declaring type of a get or set pointcut expression (use the raw type instead)"/> + <message kind="error" line="8" text="can't use parameterized type patterns for the declaring type of a get or set pointcut expression (use the raw type instead)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="get and set with various parameterizations and generic declaring types"> + <compile files="GetAndSetPointcutMatchingDeclaringType.aj" options="-1.9"> + <message kind="warning" line="15" text="generic/param get matching ok"/> + <message kind="warning" line="33" text="generic/param get matching ok"/> + <message kind="warning" line="12" text="generic/param set matching ok"/> + <message kind="warning" line="32" text="generic/param set matching ok"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="get and set with various parameterizations and generic field types"> + <compile files="GetAndSetPointcutMatchingFieldType.aj" options="-1.9"> + <message kind="warning" line="13" text="raw field type matching in get ok"/> + <message kind="warning" line="14" text="raw field type matching in set ok"/> + <message kind="warning" line="49" text="erasure matching in get ok"/> + <message kind="warning" line="45" text="erasure matching in set ok"/> + <message kind="warning" line="53" text="erasure matching in get with params ok"/> + <message kind="warning" line="46" text="erasure matching in set with params ok"/> + <message kind="warning" line="72" text="parameterized type matching in set ok"/> + <message kind="warning" line="73" text="parameterized type matching in get ok"/> + <message kind="warning" line="74" text="parameterized type matching in set ok x2"/> + <message kind="warning" line="75" text="parameterized type matching in get ok x2"/> + <message kind="warning" line="83" text="wildcard set matching ok"/> + <message kind="warning" line="84" text="wildcard get matching ok"/> + <message kind="warning" line="85" text="wildcard extends set matching ok"/> + <message kind="warning" line="86" text="wildcard extends get matching ok"/> + <message kind="warning" line="87" text="wildcard super set matching ok"/> + <message kind="warning" line="88" text="wildcard super get matching ok"/> + <message kind="warning" line="73" text="the really wild show"/> + <message kind="warning" line="84" text="the really wild show"/> + <message kind="warning" line="86" text="the really wild show"/> + <message kind="warning" line="88" text="the really wild show"/> + <message kind="warning" line="53" text="the really wild show"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="init and preinit with parameterized declaring types"> + <compile files="InitializationPointcutMatching.aj" options="-1.9"> + <message kind="warning" line="4" text="no match for this type name: T"/> + <message kind="warning" line="5" text="no match for this type name: T"/> + <message kind="error" line="4" text="no [pre]initialization join points for parameterized types, use raw type instead"/> + <message kind="error" line="5" text="no [pre]initialization join points for parameterized types, use raw type instead"/> + <message kind="error" line="6" text="no [pre]initialization join points for parameterized types, use raw type instead"/> + <message kind="error" line="7" text="no [pre]initialization join points for parameterized types, use raw type instead"/> + <message kind="error" line="8" text="no [pre]initialization join points for parameterized types, use raw type instead"/> + <message kind="error" line="9" text="invalid throws pattern: a generic class may not be a direct or indirect subclass of Throwable"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="init and preinit with raw declaring type pattern"> + <compile files="InitializationPointcutMatchingDeclaringType.aj" options="-1.9"> + <message kind="warning" line="10" text="generic/param init matching ok"/> + <message kind="warning" line="10" text="generic/param preinit matching ok"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="init and preinit with parameterized parameter types"> + <compile files="InitializationPointcutMatchingParamTypes.aj" options="-1.9"> + <message kind="warning" line="36" text="raw param type matching in init ok"/> + <message kind="warning" line="36" text="raw param type matching in preinit ok"/> + <message kind="warning" line="37" text="erasure matching in init ok"/> + <message kind="warning" line="37" text="erasure matching in preinit ok"/> + <message kind="warning" line="38" text="erasure matching in init with params ok"/> + <message kind="warning" line="38" text="erasure matching in preinit with params ok"/> + <message kind="warning" line="48" text="parameterized type matching in init ok"/> + <message kind="warning" line="48" text="parameterized type matching in preinit ok"/> + <message kind="warning" line="49" text="parameterized type matching in init ok x2"/> + <message kind="warning" line="49" text="parameterized type matching in preinit ok x2"/> + <message kind="warning" line="50" text="wildcard init matching ok"/> + <message kind="warning" line="50" text="wildcard preinit matching ok"/> + <message kind="warning" line="51" text="wildcard extends init matching ok"/> + <message kind="warning" line="51" text="wildcard extends preinit matching ok"/> + <message kind="warning" line="52" text="wildcard super init matching ok"/> + <message kind="warning" line="52" text="wildcard super preinit matching ok"/> + <message kind="warning" line="48" text="the really wild show"/> + <message kind="warning" line="50" text="the really wild show"/> + <message kind="warning" line="51" text="the really wild show"/> + <message kind="warning" line="52" text="the really wild show"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="withincode with various parameterizations and generic types - errors"> + <compile files="WithincodePointcutMatching.aj" options="-1.9"> + <message kind="warning" line="4" text="no match for this type name: T"/> + <message kind="error" line="4" text="can't use parameterized type patterns for the declaring type of a withincode pointcut expression (use the raw type instead)"/> + <message kind="error" line="5" text="can't use parameterized type patterns for the declaring type of a withincode pointcut expression (use the raw type instead)"/> + <message kind="error" line="6" text="invalid throws pattern: a generic class may not be a direct or indirect subclass of Throwable"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="withincode with various parameterizations and generic types - matching"> + <compile files="WithinCodePointcutMatchingParamAndReturnTypes.aj" options="-1.9"> + <message kind="warning" line="35" text="raw param type matching in withincode ok"/> + <message kind="warning" line="36" text="raw param type matching in withincode ok"/> + <message kind="warning" line="67" text="raw return type matching in withincode ok"/> + <message kind="warning" line="38" text="erasure type matching in withincode ok"/> + <message kind="warning" line="39" text="erasure type matching in withincode ok"/> + <message kind="warning" line="42" text="erasure type matching in withincode ok"/> + <message kind="warning" line="62" text="withincode and parameterized method ok"/> + <message kind="warning" line="62" text="withincode and generic interface ok"/> + <message kind="warning" line="65" text="withincode and interface control test"/> + <message kind="warning" line="35" text="match on parameterized args"/> + <message kind="warning" line="36" text="match on parameterized args"/> + <message kind="warning" line="67" text="match on parameterized return type"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="withincode with overriding of inherited generic members"> + <compile files="WithinCodeOverriding.aj" options="-1.9"> + <message kind="warning" line="37" text="wildcard declaring type match on erasure"/> + <message kind="warning" line="50" text="wildcard declaring type match on erasure"/> + <message kind="warning" line="63" text="wildcard declaring type match on erasure"/> + <message kind="warning" line="37" text="base declaring type match on erasure"/> + <message kind="warning" line="50" text="base declaring type match on erasure"/> + <message kind="warning" line="63" text="base declaring type match on erasure"/> + <message kind="warning" line="50" text="sub type match on erasure"/> + <message kind="warning" line="63" text="parameterized match on erasure"/> + <message kind="warning" line="80" text="erasure match on base interface"/> + <message kind="warning" line="80" text="wildcard match on erasure"/> + <message kind="warning" line="80" text="parameterized match"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="execution pcd with raw type matching"> + <compile files="GenericInterface.java,ConcreteImplementingClass.java,GenericImplementingClass.java,RawTypeMatching.aj" options="-1.9"> + <message kind="warning" line="4" text="execution(* GenericInterface.*(..))"/> + <message kind="warning" line="5" text="execution(* GenericInterface.*(..))"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="execution pcd with raw signature matching"> + <compile files="GenericInterface.java,ConcreteImplementingClass.java,GenericImplementingClass.java,RawSignatureMatching.aj" options="-1.9"> + <message kind="warning" line="4" text="execution(* GenericInterface.asInt(Number))"/> + <message kind="warning" line="5" text="execution(* GenericInterface.asInt(Number))"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="execution with various parameterizations and generic types - errors"> + <compile files="ExecutionPointcutMatchingErrorCases.aj" options="-1.9"> + <message kind="warning" line="4" text="no match for this type name: T"/> + <message kind="error" line="4" text="can't use parameterized type patterns for the declaring type of an execution pointcut expression (use the raw type instead)"/> + <message kind="error" line="5" text="can't use parameterized type patterns for the declaring type of an execution pointcut expression (use the raw type instead)"/> + <message kind="error" line="6" text="invalid throws pattern: a generic class may not be a direct or indirect subclass of Throwable"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="execution with various parameterizations and generic types - matching"> + <compile files="ExecutionPointcutMatchingParamAndReturnTypes.aj" options="-1.9"> + <message kind="warning" line="35" text="raw param type matching in execution ok"/> + <message kind="warning" line="67" text="raw return type matching in execution ok"/> + <message kind="warning" line="38" text="erasure type matching in execution ok"/> + <message kind="warning" line="42" text="erasure type matching in execution ok"/> + <message kind="warning" line="61" text="execution and parameterized method ok"/> + <message kind="warning" line="61" text="execution and generic interface ok"/> + <message kind="warning" line="65" text="execution and interface control test"/> + <message kind="warning" line="35" text="match on parameterized args"/> + <message kind="warning" line="67" text="match on parameterized return type"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="execution with overriding of inherited generic members"> + <compile files="ExecutionOverriding.aj" options="-1.9"> + <message kind="warning" line="36" text="wildcard declaring type match on erasure"/> + <message kind="warning" line="49" text="wildcard declaring type match on erasure"/> + <message kind="warning" line="62" text="wildcard declaring type match on erasure"/> + <message kind="warning" line="36" text="base declaring type match on erasure"/> + <message kind="warning" line="49" text="base declaring type match on erasure"/> + <message kind="warning" line="62" text="base declaring type match on erasure"/> + <message kind="warning" line="49" text="sub type match on erasure"/> + <message kind="warning" line="62" text="parameterized match on erasure"/> + <message kind="warning" line="79" text="erasure match on base interface"/> + <message kind="warning" line="79" text="wildcard match on erasure"/> + <message kind="warning" line="79" text="parameterized match"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="execution pcd with generic declaring type and erased parameter types"> + <compile files="GenericInterface.java,ConcreteImplementingClass.java,GenericImplementingClass.java,GenericDeclaringTypeWithParameterErasure.aj" options="-1.9"> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="execution pcd with generic signature matching"> + <compile files="GenericInterface.java,ConcreteImplementingClass.java,GenericImplementingClass.java,GenericSignatureMatching.aj" options="-1.9"> + <message kind="warning" line="4" text="execution<T>(* GenericInterface<T extends Number>.asInt(T))"/> + <message kind="warning" line="5" text="execution<T>(* GenericInterface<T extends Number>.asInt(T))"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="call with various parameterizations and generic types - errors"> + <compile files="CallPointcutMatchingErrorCases.aj" options="-1.9"> + <message kind="warning" line="4" text="no match for this type name: T"/> + <message kind="error" line="4" text="can't use parameterized type patterns for the declaring type of a call pointcut expression (use the raw type instead)"/> + <message kind="error" line="5" text="can't use parameterized type patterns for the declaring type of a call pointcut expression (use the raw type instead)"/> + <message kind="error" line="6" text="invalid throws pattern: a generic class may not be a direct or indirect subclass of Throwable"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="call with various parameterizations and generic types - matching"> + <compile files="CallPointcutMatchingParamAndReturnTypes.aj" options="-1.9"> + <message kind="warning" line="7" text="raw param type matching in call ok"/> + <message kind="warning" line="8" text="raw return type matching in call ok"/> + <message kind="warning" line="9" text="erasure type matching in call ok"/> + <message kind="warning" line="10" text="erasure type matching in call ok"/> + <message kind="warning" line="11" text="call and parameterized method ok"/> + <message kind="warning" line="11" text="call and generic interface ok"/> + <message kind="warning" line="12" text="call and interface control test"/> + <message kind="warning" line="7" text="match on parameterized args"/> + <message kind="warning" line="8" text="match on parameterized return type"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="call with overriding of inherited generic members"> + <compile files="CallOverriding.aj" options="-1.9"> + <message kind="warning" line="8" text="wildcard declaring type match on erasure"/> + <message kind="warning" line="9" text="wildcard declaring type match on erasure"/> + <message kind="warning" line="10" text="wildcard declaring type match on erasure"/> + <message kind="warning" line="8" text="base declaring type match on erasure"/> + <message kind="warning" line="9" text="base declaring type match on erasure"/> + <message kind="warning" line="10" text="base declaring type match on erasure"/> + <message kind="warning" line="9" text="sub type match on erasure"/> + <message kind="warning" line="10" text="parameterized match on erasure"/> + <message kind="warning" line="87" text="erasure match on base interface"/> + <message kind="warning" line="87" text="wildcard match on erasure"/> + <message kind="warning" line="87" text="parameterized match"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="call with bridge methods"> + <compile files="CallWithBridgeMethods.aj" options="-1.9"> + <!-- see testcode + <message kind="warning" line="23" text="should match call to bridge method on L23, this is a real call!"/> + --> + </compile> + </ajc-test> + + + <ajc-test dir="java5/generics/pointcuts" title="args with raw type and generic / parameterized sigs"> + <compile files="RawArgs.aj" options="-1.9"> + </compile> + <run class="RawArgs"> + <stdout> + <line text="args(List) match at call(void Generic.foo(List))"/> + <line text="args(List) match at call(void Generic.bar(List))"/> + <line text="args(List) match at call(void Generic.tada(List))"/> + <line text="args(List) match at call(void Generic.tada(List))"/> + <line text="args(List) match at call(void Generic.tada(List))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="args with parameterized type and generic / parameterized sigs"> + <compile files="ArgsParameterized.aj" options="-1.9"> + <message kind="warning" line="28" text="unchecked match of List<String> with List"/> + </compile> + <run class="ArgsParameterized"> + <stdout> + <line text="args(List<String> matched at call(void Generic.foo(List))"/> + <line text="args(List<String> matched at call(void Generic.bar(List))"/> + <line text="args(List<String> matched at call(void Generic.tada(List))"/> + <line text="args(List<String> matched at call(void Generic.something(List))"/> + <line text="args(List<String> matched at call(void MustBeString.listit(List))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="args with parameterized type and wildcards"> + <compile files="ArgsParameterizedWithWildcards.aj" options="-1.9"> + <message kind="warning" line="10" text="unchecked match of List<Double> with List when argument is an instance of List"/> + <message kind="warning" line="10" text="unchecked match of List<Double> with List<? extends Double> when argument is an instance of List"/> + <message kind="warning" line="10" text="unchecked match of List<Double> with List<? extends Number> when argument is an instance of List"/> + <message kind="warning" line="10" text="unchecked match of List<Double> with List<?> when argument is an instance of List"/> + </compile> + <run class="ArgsParameterizedWithWildcards"> + <stdout> + <line text="List<Double> matched at execution(void C.rawList(List))"/> + <line text="List<Double> matched at execution(void C.listOfSomething(List))"/> + <line text="List<Double> matched at execution(void C.listOfSomeNumber(List))"/> + <line text="List<Double> matched at execution(void C.listOfDouble(List))"/> + <line text="List<Double> matched at execution(void C.listOfSomeDouble(List))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="args with generic wildcard"> + <compile files="ArgsListOfSomething.aj" options="-1.9 -Xlint:ignore"> + </compile> + <run class="ArgsListOfSomething"> + <stdout> + <line text="List<?> matches execution(void ArgsListOfSomething.rawList(List))"/> + <line text="List<?> matches execution(void ArgsListOfSomething.listOfString(List))"/> + <line text="List<?> matches execution(void ArgsListOfSomething.listOfSomething(List))"/> + <line text="List<?> matches execution(void ArgsListOfSomething.listOfSomethingExtends(List))"/> + <line text="List<?> matches execution(void ArgsListOfSomething.listOfSomethingSuper(List))"/> + <line text="wild map matches execution(void ArgsListOfSomething.mapit(Map))"/> + <line text="exact wild map matches execution(void ArgsListOfSomething.mapit(Map))"/> + <line text="super type exact matches execution(void ArgsListOfSomething.setOf(HashSet))"/> + <line text="super wild type matches execution(void ArgsListOfSomething.setOf(HashSet))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="args with generic wildcard extends"> + <compile files="ArgsListOfSomethingExtends.aj" options="-1.9"> + <message kind="warning" line="27" text="unchecked match of List<? extends Number> with List"/> + <message kind="warning" line="27" text="unchecked match of List<? extends Number> with List<?>"/> + </compile> + <run class="ArgsListOfSomethingExtends"> + <stdout> + <line text="List<? extends Number> matches execution(void ArgsListOfSomethingExtends.rawList(List))"/> + <line text="List<? extends Number> matches execution(void ArgsListOfSomethingExtends.listOfNumber(List))"/> + <line text="List<? extends Number> matches execution(void ArgsListOfSomethingExtends.listOfDouble(List))"/> + <line text="List<? extends Number> matches execution(void ArgsListOfSomethingExtends.listOfSomething(List))"/> + <line text="List<? extends Number> matches execution(void ArgsListOfSomethingExtends.listOfSomethingExtends(List))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="args with generic wildcard super"> + <compile files="ArgsListOfSomethingSuper.aj" options="-1.9"> + <message kind="warning" line="32" text="unchecked match of List<? super Number> with List"/> + <message kind="warning" line="32" text="unchecked match of List<? super Number> with List<?>"/> + <message kind="warning" line="32" text="unchecked match of List<? super Number> with List<? extends Number>"/> + </compile> + <run class="ArgsListOfSomethingSuper"> + <stdout> + <line text="List<? super Number> matches execution(void ArgsListOfSomethingSuper.rawList(List))"/> + <line text="List<? super Number> matches execution(void ArgsListOfSomethingSuper.listOfObject(List))"/> + <line text="List<? super Number> matches execution(void ArgsListOfSomethingSuper.listOfNumber(List))"/> + <line text="List<? super Number> matches execution(void ArgsListOfSomethingSuper.listOfSomething(List))"/> + <line text="List<? super Number> matches execution(void ArgsListOfSomethingSuper.listOfSomethingSuper(List))"/> + <line text="List<? super Number> matches execution(void ArgsListOfSomethingSuper.listOfSomethingExtendsNumber(List))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="generic method matching"> + <compile files="GenericMethods.aj" options="-1.9"> + <message kind="warning" line="19" text="static generic method match"/> + <message kind="warning" line="34" text="static generic method match"/> + <message kind="warning" line="24" text="instance generic method match"/> + <message kind="warning" line="39" text="instance generic method match"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/pointcuts" title="generic wildcards in signature matching"> + <compile files="GenericWildcardsInSignatureMatching.aj" options="-1.9"> + <message kind="warning" line="5" text="set of a list"/> + <message kind="warning" line="7" text="exact nested wildcard match"/> + <message kind="warning" line="7" text="wildcard nested wildcard match"/> + <message kind="warning" line="11" text="super"/> + <message kind="warning" line="15" text="super wild match"/> + </compile> + </ajc-test> + + <!-- end of generics and pointcuts tests --> + + <ajc-test dir="java5/generics/afterAdvice" title="after throwing with parameterized throw type"> + <compile files="AfterThrowing.aj" options="-1.9"> + <message kind="error" line="6" text="cannot convert from List<String> to Throwable"/> + </compile> + </ajc-test> + + + <ajc-test dir="java5/generics/afterAdvice" title="after returning with raw type and generic / parameterized sigs"> + <compile files="AfterReturningRawType.aj" options="-1.9"> + </compile> + <run class="AfterReturningRawType"> + <stdout> + <line text="returning(List) match at call(List Generic.foo(List))"/> + <line text="returning(List) match at call(List Generic.bar(List))"/> + <line text="returning(List) match at call(List Generic.tada(List))"/> + <line text="returning(List) match at call(List Generic.tada(List))"/> + <line text="returning(List) match at call(List Generic.tada(List))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/afterAdvice" title="after returning with parameterized type and generic / parameterized sigs"> + <compile files="AfterReturningParameterized.aj" options="-1.9"> + <message kind="warning" line="28" text="unchecked match of List<String> with List"/> + </compile> + <run class="AfterReturningParameterized"> + <stdout> + <line text="returning(List<String> matched at call(List Generic.foo(List))"/> + <line text="returning(List<String> matched at call(List Generic.bar(List))"/> + <line text="returning(List<String> matched at call(List Generic.tada(List))"/> + <line text="returning(List<String> matched at call(List Generic.something(List))"/> + <line text="returning(List<String> matched at call(List MustBeString.listit(List))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/afterAdvice" title="after returning with parameterized type and wildcards"> + <compile files="AfterReturningParameterizedWithWildcards.aj" options="-1.9"> + <message kind="warning" line="10" text="unchecked match of List<Double> with List when argument is an instance of List"/> + <message kind="warning" line="10" text="unchecked match of List<Double> with List<? extends Double> when argument is an instance of List"/> + <message kind="warning" line="10" text="unchecked match of List<Double> with List<? extends Number> when argument is an instance of List"/> + <message kind="warning" line="10" text="unchecked match of List<Double> with List<?> when argument is an instance of List"/> + </compile> + <run class="AfterReturningParameterizedWithWildcards"> + <stdout> + <line text="List<Double> matched at call(List C.rawList(List))"/> + <line text="List<Double> matched at call(List C.listOfSomething(List))"/> + <line text="List<Double> matched at call(List C.listOfSomeNumber(List))"/> + <line text="List<Double> matched at call(List C.listOfDouble(List))"/> + <line text="List<Double> matched at call(List C.listOfSomeDouble(List))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/afterAdvice" title="after returning with generic wildcard"> + <compile files="AfterReturningListOfSomething.aj" options="-1.9"> + <!-- warning is unchecked match of List<?> from line 28 onto line 15. --> + <!-- some sets may be lists unless the set is final, so as a cast is allowed, the match is allowed --> + <message kind="warning" line="28"/> + <message kind="warning" line="44"/> + <message kind="warning" line="48"/> + </compile> + <run class="AfterReturningListOfSomething"> + <stdout> + <line text="List<?> matches execution(List AfterReturningListOfSomething.rawList(List))"/> + <line text="List<?> matches execution(List AfterReturningListOfSomething.listOfString(List))"/> + <line text="List<?> matches execution(List AfterReturningListOfSomething.listOfSomething(List))"/> + <line text="List<?> matches execution(List AfterReturningListOfSomething.listOfSomethingExtends(List))"/> + <line text="List<?> matches execution(List AfterReturningListOfSomething.listOfSomethingSuper(List))"/> + <line text="wild map matches execution(Map AfterReturningListOfSomething.mapit(Map))"/> + <line text="exact wild map matches execution(Map AfterReturningListOfSomething.mapit(Map))"/> + <line text="super type exact matches execution(HashSet AfterReturningListOfSomething.setOf(HashSet))"/> + <line text="super wild type matches execution(HashSet AfterReturningListOfSomething.setOf(HashSet))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/afterAdvice" title="after returning with generic wildcard extends"> + <compile files="AfterReturningListOfSomethingExtends.aj" options="-1.9"> + <message kind="warning" line="27" text="unchecked match of List<? extends Number> with List"/> + <message kind="warning" line="27" text="unchecked match of List<? extends Number> with List<?>"/> + </compile> + <run class="AfterReturningListOfSomethingExtends"> + <stdout> + <line text="List<? extends Number> matches execution(List AfterReturningListOfSomethingExtends.rawList(List))"/> + <line text="List<? extends Number> matches execution(List AfterReturningListOfSomethingExtends.listOfNumber(List))"/> + <line text="List<? extends Number> matches execution(List AfterReturningListOfSomethingExtends.listOfDouble(List))"/> + <line text="List<? extends Number> matches execution(List AfterReturningListOfSomethingExtends.listOfSomething(List))"/> + <line text="List<? extends Number> matches execution(List AfterReturningListOfSomethingExtends.listOfSomethingExtends(List))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="java5/generics/afterAdvice" title="after returning with generic wildcard super"> + <compile files="AfterReturningListOfSomethingSuper.aj" options="-1.9"> + <message kind="warning" line="32" text="unchecked match of List<? super Number> with List"/> + <message kind="warning" line="32" text="unchecked match of List<? super Number> with List<?>"/> + <message kind="warning" line="32" text="unchecked match of List<? super Number> with List<? extends Number>"/> + </compile> + <run class="AfterReturningListOfSomethingSuper"> + <stdout> + <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.rawList(List))"/> + <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.listOfObject(List))"/> + <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.listOfNumber(List))"/> + <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.listOfSomething(List))"/> + <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.listOfSomethingSuper(List))"/> + <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.listOfSomethingExtendsNumber(List))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test title="ajdk notebook: erasure matching examples" dir="java5/generics/ajdk"> + <compile files="ErasureMatching.aj" options="-1.9"> + <message kind="warning" line="18" text="static generic method match"/> + <message kind="warning" line="21" text="instance generic method match"/> + <message kind="warning" line="31" text="method in generic type match"/> + <message kind="warning" line="28" text="field in generic type match"/> + </compile> + </ajc-test> + + <ajc-test title="ajdk notebook: simple parameterized type matching examples" dir="java5/generics/ajdk"> + <compile files="SimpleParameterizedTypeExamples.aj" options="-1.9"> + <message kind="warning" line="34" text="get myStrings 1"/> + <message kind="warning" line="34" text="get myStrings 2"/> + <message kind="warning" line="38" text="get myStrings 1"/> + <message kind="warning" line="38" text="get myStrings 2"/> + <message kind="warning" line="35" text="get myFloats 1"/> + <message kind="warning" line="35" text="get myFloats 2"/> + <message kind="warning" line="35" text="get myFloats 3"/> + <message kind="warning" line="34" text="getter 1"/> + <message kind="warning" line="35" text="getter 1"/> + <message kind="warning" line="34" text="getter 2"/> + <message kind="warning" line="35" text="getter 2"/> + <message kind="warning" line="34" text="getter 3"/> + <message kind="warning" line="35" text="getter 4"/> + <message kind="warning" line="25" text="call 1"/> + <message kind="warning" line="25" text="call 2"/> + </compile> + </ajc-test> + + <ajc-test title="ajdk notebook: mixed parameterized types and generic methods" dir="java5/generics/ajdk"> + <compile files="MixedParameterizedAndTypeVariables.aj" options="-1.9"> + <message kind="warning" line="13" text="erasure match"/> + <message kind="warning" line="13" text="mixed match"/> + <message kind="warning" line="13" text="params only match"/> + </compile> + </ajc-test> + + <ajc-test title="ajdk notebook: signature matching with generic wildcards" dir="java5/generics/ajdk"> + <compile files="SignatureWildcards.aj" options="-1.9"> + <message kind="warning" line="13" text="any list"/> + <message kind="warning" line="15" text="any list"/> + <message kind="warning" line="17" text="any list"/> + <message kind="warning" line="13" text="only foo"/> + <message kind="warning" line="15" text="some list"/> + <message kind="warning" line="13" text="any list with upper bound"/> + <message kind="warning" line="15" text="any list with upper bound"/> + </compile> + </ajc-test> + + <ajc-test title="ajdk notebook: bridge method examples" dir="java5/generics/ajdk"> + <compile files="BridgeMethodExamples.aj" options="-1.9"> + <message kind="warning" line="17" text="double match"/> + <message kind="warning" line="25" text="double match"/> + <message kind="warning" line="9" text="match"/> + <message kind="warning" line="11" text="match"/> + </compile> + </ajc-test> + + <ajc-test title="ajdk notebook: args examples" dir="java5/generics/ajdk"> + <compile files="ArgsExamples.aj" options="-1.9"> + <message kind="warning" line="15" text="unchecked match of List<Double> with List<? extends Number> when argument is an instance of List at join point method-execution(void C.goo(List<? extends Number>)) [Xlint:uncheckedArgument]"/> + <message kind="warning" line="53" text="unchecked match"/> + </compile> + <run class="ArgsExamples"> + <stdout> + <line text="args(List)"/> + <line text="args List of String"/> + <line text="args(List)"/> + <line text="args List of Double"/> + <line text="args(List)"/> + <line text="args List of Double"/> + </stdout> + </run> + </ajc-test> + + <ajc-test title="ajdk notebook: after returning examples" dir="java5/generics/ajdk"> + <compile files="AfterReturningExamples.aj" options="-1.9"> + <message kind="warning" line="20" text="unchecked match of List<Double> with List<? extends Number>"/> + </compile> + <run class="AfterReturningExamples"> + <stdout> + <line text="execution(List C.foo(List))"/> + <line text="raw s1"/> + <line text="raw s2"/> + <line text="execution(List C.bar(List))"/> + <line text="raw 5.0"/> + <line text="raw 10.0"/> + <line text="a1 5.0"/> + <line text="a1 10.0"/> + <line text="a2 5.0"/> + <line text="a2 10.0"/> + <line text="a3 5.0"/> + <line text="a3 10.0"/> + <line text="execution(List C.goo(List))"/> + <line text="raw 5.0"/> + <line text="raw 10.0"/> + <line text="a1 5.0"/> + <line text="a1 10.0"/> + <line text="a3 5.0"/> + <line text="a3 10.0"/> + </stdout> + </run> + </ajc-test> + + <ajc-test title="ajdk notebook: args and wildcards examples" dir="java5/generics/ajdk"> + <compile files="WildcardArgsExamples.aj" options="-1.9"> + <message kind="warning" line="6" text="unchecked match of List<? extends Number> with List"/> + </compile> + <run class="WildcardArgsExamples"> + <stdout> + <line text="advice match at call(void C.foo(Object))"/> + <line text="advice match at call(void C.foo(Object))"/> + <line text="advice match 2 at call(void C.goo1(List))"/> + <line text="advice match 2 at call(void C.goo2(List))"/> + <line text="advice match 2 at call(void C.goo4(List))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test title="ajdk notebook: pointcut in generic class example" dir="java5/generics/ajdk"> + <compile files="PointcutInGenericClassExample.aj" options="-1.9"> + <message kind="warning" line="23" text="parameterized with C"/> + <message kind="warning" line="29" text="parameterized with D"/> + </compile> + </ajc-test> + + <!-- ============================================================== --> + <!-- End of generics tests --> + <!-- ============================================================== --> + + <ajc-test dir="bugs150/pr98901" title="public method with declare @method"> + <compile files="Case01.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B01"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" title="Compiler error due to a wrong exception check in try blocks"> + <compile files="pr82989.aj" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr98901" title="public method on the aspect that declares @method on it"> + <compile files="Case02.aj" options="-1.9 -Xlint:error"/> + <run class="B02"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr98901" title="public annotated method"> + <compile files="Case03.aj" options="-1.9 -Xlint:error"/> + <run class="B03"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public ITD method with declare @method"> + <compile files="Case04.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B04"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public annotated ITD method"> + <compile files="Case05.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B05"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public ITD-on-itself method with declare @method"> + <compile files="Case06.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B06"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public annotated ITD-on-itself method"> + <compile files="Case07.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B07"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public method on an Interface with declare @method"> + <compile files="Case08.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B08"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public annotated method on an Interface"> + <compile files="Case09.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B09"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public ITD method onto an Interface with declare @method"> + <compile files="Case10.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B10"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public annotated ITD method onto an Interface"> + <compile files="Case11.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B11"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public abstract method with declare @method"> + <compile files="Case12.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B12"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public abstract method on the aspect that declares @method on it"> + <compile files="Case13.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B13"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public abstract annotated method"> + <compile files="Case14.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B14"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public abstract ITD method with declare @method"> + <compile files="Case15.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B15"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public abstract annotated ITD method"> + <compile files="Case16.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B16"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public abstract ITD-on-itself method with declare @method"> + <compile files="Case17.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B17"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public abstract annotated ITD-on-itself method"> + <compile files="Case18.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B18"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public abstract method on an Interface with declare @method"> + <compile files="Case19.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B19"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public abstract annotated method on an Interface"> + <compile files="Case20.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B20"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public abstract ITD method onto an Interface with declare @method"> + <compile files="Case21.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B21"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public abstract annotated ITD method onto an Interface"> + <compile files="Case22.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B22"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public field with declare @field"> + <compile files="Case23.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B23"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + + +<ajc-test dir="bugs150/pr98901" title="public field on the aspect that declares @field on it"> + <compile files="Case24.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B24"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + +<ajc-test dir="bugs150/pr98901" title="public annotated field"> + <compile files="Case25.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B25"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr98901" title="public ITD field with declare @field"> + <compile files="Case26.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B26"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr98901" title="public annotated ITD field"> + <compile files="Case27.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B27"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr98901" title="public ITD-on-itself field with declare @field"> + <compile files="Case28.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B28"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr98901" title="public annotated ITD-on-itself field"> + <compile files="Case29.aj" options="-1.9 -Xlint:error -Xdev:NoAtAspectJProcessing"/> + <run class="B29"> + <stdout> + <line text="@anInterface()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" title="Unable to build shadows"> + <compile files="pr109728.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr110788" title="bad generic decp - 1"> + <compile files="Case1.java" options="-1.9"> + <message kind="error" line="10" text="Cannot declare parent B<java.lang.Number> onto type C since it already has A<java.lang.String> in its hierarchy"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr110788" title="bad generic decp - 2"> + <compile files="Case2.java" options="-1.9"> + <message kind="error" line="8" text="Cannot declare parent A<java.lang.Number> onto type C since it already has A<java.lang.String> in its hierarchy"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr110788" title="bad generic decp - 3"> + <compile files="Case3.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr110788" title="bad generic decp - 4"> + <compile files="Case4.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr110927" title="cant create signature attribute"> + <compile files="Case1.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr72834" title="broken dispatch"> + <compile files="Trouble.java"> + <message kind="error" line="7" text="package visible abstract inter-type declarations are not allowed"/> + <message kind="error" line="9" text="The method getName() is undefined for the type A"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr73856" title="missing accessor"> + <compile files="MissingAccessor.java"/> + <run class="MissingAccessor"/> + </ajc-test> + + <ajc-test dir="bugs150/pr90143" title="cant call super methods"> + <compile files="A.aj"/> + </ajc-test> + + <ajc-test dir="bugs150" title="cunning declare parents"> + <compile files="pr92311.aj"/> + </ajc-test> + + <ajc-test dir="bugs150" title="ITD varargs problem"> + <compile files="pr110906.aj" options="-1.9"/> + <run class="pr110906"> + <stdout> + <line text="a"/> + <line text="a"/> + <line text="a"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150" title="generic itds and abstract method error"> + <compile files="pr102357.aj"/> + <run class="pr102357"/> + </ajc-test> + + <ajc-test dir="bugs150" title="unexpected error unboundFormalInPC"> + <compile files="pr112027.aj"/> + </ajc-test> + + <ajc-test dir="bugs150" title="ITD varargs in constructor"> + <compile files="pr111481.aj" options="-1.9"/> + <run class="pr111481"> + <stdout> + <line text="a"/> + <line text="a"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr112602" title="ClassCastException with generic wildcard"> + <compile files="GenericInterface.java,Implementation.java" options="-1.9,-emacssym"/> + </ajc-test> + + <ajc-test dir="bugs150/pr110307" title="Cant provide default implementation via ITD - 1"> + <compile files="Case1.java" options="-1.9"> + <message kind="warning" line="27" text="no match for this type name: Branch [Xlint:invalidAbsoluteTypeName]"/> + <message kind="error" line="26" text="can't bind type name 'Branch'"/> + <message kind="error" line="27" text="can't bind type name 'Revision'"/> + <message kind="error" line="33" text="List cannot be resolved to a type"/> + <message kind="error" line="38" text="List cannot be resolved to a type"/> + <message kind="error" line="39" text="List cannot be resolved to a type"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr110307" title="Cant provide default implementation via ITD - 2"> + <compile files="Case2.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr110307" title="Cant provide default implementation via ITD - 3"> + <compile files="Case3.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr110307" title="Cant provide default implementation via ITD - 4"> + <compile files="Case4.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr110307" title="Cant provide default implementation via ITD - 5"> + <compile files="Case5.java" options="-1.9"> + <!-- might possibly need more diagnostics in this case to explain what has happened --> + <message kind="error" line="10" text="can't override java.util.List<java.lang.String> I.foo() with java.util.List<java.lang.Integer> A.foo() return types don't match"/> + <message kind="error" line="15" text="can't override java.util.List<java.lang.String> I.foo() with java.util.List<java.lang.Integer> A.foo() return types don't match"/> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr110307" title="Cant provide default implementation via ITD - 6"> + <compile files="Case6.java" options="-1.9"> + <message kind="error" line="8" text="N cannot be resolved to a type"/> + <!--message kind="error" line="7" text="T cannot be resolved to a type"/--> + </compile> + </ajc-test> + + <ajc-test dir="bugs150/pr110307" title="Cant provide default implementation via ITD - 7"> + <compile files="Case7.java" options="-1.9"/> + <run class="Case7"> + <stderr> + <line text="in=hello out=hello"/> + <line text="in=35 out=35"/> + <line text="in=[] out=[]"/> + </stderr> + </run> + </ajc-test> + + <!-- generic ITDs --> + + <ajc-test dir="java5/generics/itds/design" title="generic itds - design A"> + <compile files="DesignA.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/design" title="generic itds - design B"> + <compile files="DesignB.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/design" title="generic itds - design C"> + <compile files="DesignC.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/design" title="generic itds - design D"> + <compile files="DesignD.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/design" title="generic itds - design E"> + <compile files="DesignE.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/design" title="generic itds - design F"> + <compile files="DesignF.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds/design" title="generic itds - design G"> + <compile files="DesignG.java" options="-1.9"/> + </ajc-test> + + <ajc-test dir="bugs150/pr116626" title="NPE in WeavingAdaptor"> + <compile files="com/foo/bar/Test.java, TestAspect.aj" options="-1.9"/> + <run class="com.foo.bar.Test" ltw="aop.xml" + > + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr119657" title="IllegalAccessError with around advice on interface method call"> + <compile files="services/account/StockQuoteServiceTest.java, services/accountdata/StockAccount.java, services/stockquote/StockQuoteService.java, services/stockquote/StockQuoteServiceImpl.java, services/account/AccountReport.java, accounts/recovery/Recovery.aj"/> + <run class="services.account.StockQuoteServiceTest"> + <stdout> + <line text="Recovery.around() call(float services.stockquote.StockQuoteService.getQuote(String))"/> + </stdout> + </run> + <run class="services.account.StockQuoteServiceTest" ltw="aop.xml"> + <stdout> + <line text="Recovery.around() call(float services.stockquote.StockQuoteService.getQuote(String))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr119657" title="IllegalAccessError with around advice on interface method call not self"> + <compile files="services/account/StockQuoteServiceTest.java, services/accountdata/StockAccount.java, services/stockquote/StockQuoteService.java, services/stockquote/StockQuoteServiceImpl.java, services/account/AccountReport.java, accounts/recovery/RecoveryNotSelf.aj"/> + <run class="services.account.StockQuoteServiceTest"> + <stdout> + <line text="RecoveryNotSelf.around() call(float services.stockquote.StockQuoteService.getQuote(String))"/> + </stdout> + </run> + <run class="services.account.StockQuoteServiceTest" ltw="aop-notself.xml"> + <stdout> + <line text="RecoveryNotSelf.around() call(float services.stockquote.StockQuoteService.getQuote(String))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr119657" title="IllegalAccessError with around advice on interface method call using -XterminateAfterCompilation and LTW"> + <compile files="services/account/StockQuoteServiceTest.java, services/accountdata/StockAccount.java, services/stockquote/StockQuoteService.java, services/stockquote/StockQuoteServiceImpl.java, services/account/AccountReport.java"/> + <compile files="accounts/recovery/Recovery.aj" options="-XterminateAfterCompilation"/> + <run class="services.account.StockQuoteServiceTest" ltw="aop.xml"> + <stdout> + <line text="Recovery.around() call(float services.stockquote.StockQuoteService.getQuote(String))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr119657" title="IllegalAccessError with around advice on interface method call using LTW"> + <compile files="services/account/StockQuoteServiceTest.java, services/accountdata/StockAccount.java, services/stockquote/StockQuoteService.java, services/stockquote/StockQuoteServiceImpl.java, services/account/AccountReport.java"/> + <compile files="accounts/recovery/Recovery.aj"/> + <run class="services.account.StockQuoteServiceTest" ltw="aop.xml"> + <stdout> + <line text="Recovery.around() call(float services.stockquote.StockQuoteService.getQuote(String))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr119657" title="IllegalAccessError with around advice on interface method call not self using LTW"> + <compile files="services/account/StockQuoteServiceTest.java, services/accountdata/StockAccount.java, services/stockquote/StockQuoteService.java, services/stockquote/StockQuoteServiceImpl.java, services/account/AccountReport.java"/> + <compile files="accounts/recovery/RecoveryNotSelf.aj"/> + <run class="services.account.StockQuoteServiceTest" ltw="aop-notself.xml"> + <stdout> + <line text="RecoveryNotSelf.around() call(float services.stockquote.StockQuoteService.getQuote(String))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr119657" title="IllegalAccessError with around advice on interface method call self and not self using LTW"> + <compile files="services/account/StockQuoteServiceTest.java, services/accountdata/StockAccount.java, services/stockquote/StockQuoteService.java, services/stockquote/StockQuoteServiceImpl.java, services/account/AccountReport.java"/> + <compile files="accounts/recovery/Recovery.aj, accounts/recovery/RecoveryNotSelf.aj"/> + <run class="services.account.StockQuoteServiceTest" ltw="aop-selfandnotself.xml"> + <stdout> + <line text="Recovery.around() call(float services.stockquote.StockQuoteService.getQuote(String))"/> + <line text="RecoveryNotSelf.around() call(float services.stockquote.StockQuoteService.getQuote(String))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr119657" title="IllegalAccessError with around advice on interface method call using LTW and -XnoInline"> + <compile files="services/account/StockQuoteServiceTest.java, services/accountdata/StockAccount.java, services/stockquote/StockQuoteService.java, services/stockquote/StockQuoteServiceImpl.java, services/account/AccountReport.java"/> + <compile files="accounts/recovery/Recovery.aj"/> + <run class="services.account.StockQuoteServiceTest" ltw="aop-noinline.xml"> + <stdout> + <line text="Recovery.around() call(float services.stockquote.StockQuoteService.getQuote(String))"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="bugs150/pr121385" title="override protected pointcut in aop.xml concrete aspect"> + <compile files="Hello.java"/> + <compile files="World.aj, ConcreteWorld.aj"/> + <run class="Hello" ltw="aop.xml"> + <stdout> + <line text="around start!"/> + <line text="Hello"/> + <line text="around start!"/> + <line text="World"/> + <line text="around end!"/> + <line text="around end!"/> + </stdout> + </run> + </ajc-test> + +</suite>
\ No newline at end of file diff --git a/tests/src/org/aspectj/systemtest/ajc190/sanity-tests-19.xml b/tests/src/org/aspectj/systemtest/ajc190/sanity-tests-19.xml new file mode 100644 index 000000000..4965b448a --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc190/sanity-tests-19.xml @@ -0,0 +1,70 @@ +<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]> + +<!-- AspectJ v1.6.0 Tests --> +<suite> + + <!-- empty class --> + <ajc-test dir="bugs160/simplejava" title="simple - a"> + <compile files="SimpleA.java" options="-1.9"/> + </ajc-test> + + <!-- class with one method --> + <ajc-test dir="bugs160/simplejava" title="simple - b"> + <compile files="SimpleB.java" options="-1.9"/> + <run class="SimpleB"/> + </ajc-test> + + <!-- empty aspect --> + <ajc-test dir="bugs160/simplejava" title="simple - c"> + <compile files="SimpleC.java" options="-1.9"/> + </ajc-test> + + <!-- simple before --> + <ajc-test dir="bugs160/simplejava" title="simple - d"> + <compile files="SimpleD.java" options="-1.9"/> + </ajc-test> + + <!-- simple itd field --> + <ajc-test dir="bugs160/simplejava" title="simple - e"> + <compile files="SimpleE.java" options="-1.9"/> + </ajc-test> + + <!-- aspect with main calling a static method --> + <ajc-test dir="bugs160/simplejava" title="simple - f"> + <compile files="SimpleF.java" options="-1.9"/> + </ajc-test> + + <!-- pertarget --> + <ajc-test dir="bugs160/simplejava" title="simple - g"> + <compile files="SimpleG.java" options="-1.9"/> + </ajc-test> + + <!-- generic ctor itds --> + <ajc-test dir="bugs160/simplejava" title="simple - h"> + <compile files="SimpleH.java" options="-1.9"/> + </ajc-test> + + <!-- overriding generic itd methods --> + <ajc-test dir="bugs160/simplejava" title="simple - i"> + <compile files="SimpleI.java" options="-1.9"/> + </ajc-test> + + <!-- check class file version is 53.0 --> + <ajc-test dir="bugs160/simplejava" title="simple - j"> + <compile files="SimpleJ.java" options="-1.9"/> + </ajc-test> + + <!-- check class file version is 53.0 --> + <ajc-test dir="bugs160/simplejava" title="simple - k"> + <compile files="SimpleJ.java" options="-source 1.9"/> + </ajc-test> + + <!-- check class file version is 49.0 --> + <ajc-test dir="bugs160/simplejava" title="simple - m"> + <compile files="SimpleJ.java" options="-1.5"/> + </ajc-test> + + <ajc-test dir="bugs160/simplejava" title="simple - n"> + <compile files="SimpleN.java" options="-1.9"/> + </ajc-test> +</suite> diff --git a/tests/src/org/aspectj/systemtest/apt/AptTests.java b/tests/src/org/aspectj/systemtest/apt/AptTests.java index af8df5e8c..bf9c53916 100644 --- a/tests/src/org/aspectj/systemtest/apt/AptTests.java +++ b/tests/src/org/aspectj/systemtest/apt/AptTests.java @@ -13,6 +13,7 @@ package org.aspectj.systemtest.apt; import junit.framework.Test; import org.aspectj.apache.bcel.classfile.Method; import org.aspectj.testing.XMLBasedAjcTestCase; +import org.aspectj.util.LangUtil; import java.io.File; @@ -24,6 +25,9 @@ import java.io.File; public class AptTests extends XMLBasedAjcTestCase { public void testAptWithSpecifiedProcessor() { + if (LangUtil.is19VMOrGreater()) { + return; + } runTest("annotation processing with specified processor"); } @@ -31,6 +35,9 @@ public class AptTests extends XMLBasedAjcTestCase { * SPI - http://docs.oracle.com/javase/tutorial/sound/SPI-intro.html */ public void testAptUsingSPI() { + if (LangUtil.is19VMOrGreater()) { + return; + } runTest("annotation processing in action using SPI"); } diff --git a/tests/src/org/aspectj/systemtest/apt/apt-spec.xml b/tests/src/org/aspectj/systemtest/apt/apt-spec.xml index 703e24fc5..0ce327c49 100644 --- a/tests/src/org/aspectj/systemtest/apt/apt-spec.xml +++ b/tests/src/org/aspectj/systemtest/apt/apt-spec.xml @@ -15,6 +15,7 @@ } } --> + <!-- believe fails on JDK9 because of split packages and unable to find @Generated --> <compile options="-1.8 -processor test.SimpleProcessor -s generated -showWeaveInfo" files="Some.java" classpath="annotation_processor.jar" outjar="code.jar"> <message kind="weave" @@ -42,12 +43,12 @@ - {className}Callbacks.java - this file contains callback interfaces for methods annotated with @Event. Example: public final class SomeCallbacks { public interface OnMethod1 { - void changed(Some emmiter); + void changed(Some emitter); } } --> - <!--apt_service_description.jar contains only SPI descrition file - META-INF/services/javax.annotation.processing.Processor--> + <!--apt_service_description.jar contains only SPI description file - META-INF/services/javax.annotation.processing.Processor--> <compile options="-1.8 -s generated -showWeaveInfo" files="Some.java" classpath="annotation_processor.jar;apt_service_description.jar" outjar="code.jar"> <message kind="weave" diff --git a/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjTestCompilerConfiguration.java b/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjTestCompilerConfiguration.java index 86302bfba..cd80218b2 100644 --- a/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjTestCompilerConfiguration.java +++ b/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjTestCompilerConfiguration.java @@ -19,6 +19,7 @@ import java.util.Set; import org.aspectj.ajde.core.ICompilerConfiguration; import org.aspectj.ajde.core.IOutputLocationManager; +import org.aspectj.util.LangUtil; /** * ICompilerConfiguration which mirrors the way AJDT behaves. Always returns that its 1.5 compliant and enables the setting of all @@ -72,6 +73,9 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio + "c:/batik/batik-1.6/lib/batik-awt-util.jar;" + "c:/batik/batik-1.6/lib/batik-dom.jar;" + "c:/batik/batik-1.6/lib/batik-svggen.jar;" + File.pathSeparator + ".." + File.separator + "lib" + File.separator + "test" + File.separator + "aspectjrt.jar"; + if (LangUtil.is19VMOrGreater()) { + cp = LangUtil.getJrtFsFilePath() + File.pathSeparator + cp; + } // look at dependant projects if (dependants != null) { @@ -258,4 +262,14 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio return this.processorPath; } + @Override + public String getModulepath() { + return null; + } + + @Override + public String getModuleSourcepath() { + return null; + } + } diff --git a/tests/testsrc/org/aspectj/tests/TestsModuleTests.java b/tests/testsrc/org/aspectj/tests/TestsModuleTests.java index 35d88df72..672a95299 100644 --- a/tests/testsrc/org/aspectj/tests/TestsModuleTests.java +++ b/tests/testsrc/org/aspectj/tests/TestsModuleTests.java @@ -20,6 +20,7 @@ import org.aspectj.systemtest.AllTests; import org.aspectj.systemtest.AllTests14; import org.aspectj.systemtest.AllTests17; import org.aspectj.systemtest.AllTests18; +import org.aspectj.systemtest.AllTests19; import org.aspectj.util.LangUtil; public class TestsModuleTests extends TestCase { @@ -28,7 +29,9 @@ public class TestsModuleTests extends TestCase { String name = TestsModuleTests.class.getName(); TestSuite suite = new TestSuite(name); // compiler tests, wrapped for JUnit - if (LangUtil.is18VMOrGreater()) { + if (LangUtil.is19VMOrGreater()) { + suite.addTest(AllTests19.suite()); + } else if (LangUtil.is18VMOrGreater()) { suite.addTest(AllTests18.suite()); } else if (LangUtil.is15VMOrGreater()) { // suite.addTest(AllTests15.suite()); diff --git a/util/src/org/aspectj/util/LangUtil.java b/util/src/org/aspectj/util/LangUtil.java index 0f19124a9..ff6c7246c 100644 --- a/util/src/org/aspectj/util/LangUtil.java +++ b/util/src/org/aspectj/util/LangUtil.java @@ -42,6 +42,17 @@ public class LangUtil { private static double vmVersion; + /** + * @return the vm version (1.1, 1.2, 1.3, 1.4, etc) + */ + public static String getVmVersionString() { + return Double.toString(vmVersion); + } + + public static double getVmVersion() { + return vmVersion; + } + static { StringWriter buf = new StringWriter(); PrintWriter writer = new PrintWriter(buf); @@ -59,6 +70,8 @@ public class LangUtil { } static { + // http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html + // http://openjdk.java.net/jeps/223 "New Version-String Scheme" try { String vm = System.getProperty("java.version"); // JLS 20.18.7 if (vm == null) { @@ -73,17 +86,21 @@ public class LangUtil { .printStackTrace(System.err); vmVersion = 1.5; } else { - if (vm.startsWith("9")) { - // JDK 9 beta 99 starts using 9-ea as the version string. - vmVersion = 1.9; - } else { - try { - String versionString = vm.substring(0, 3); - Double temp = new Double(Double.parseDouble(versionString)); - vmVersion = temp.doubleValue(); - } catch (Exception e) { - vmVersion = 1.4; + // Version: [1-9][0-9]*((\.0)*\.[1-9][0-9]*)* + // Care about the first set of digits and second set if first digit is 1 + try { + List<Integer> numbers = getFirstNumbers(vm); + if (numbers.get(0) == 1) { + // Old school for 1.0 > 1.8 + vmVersion = numbers.get(0)+(numbers.get(1)/10d); + } else { + // numbers.get(0) is the major version (9 and above) + // Note here the number will be 9 (or 10), *not* 1.9 or 1.10 + vmVersion = numbers.get(0); } + } catch (Throwable t) { + // Give up + vmVersion = 1.5; } } } catch (Throwable t) { @@ -93,6 +110,19 @@ public class LangUtil { vmVersion = 1.5; } } + + private static List<Integer> getFirstNumbers(String vm) { + List<Integer> result = new ArrayList<Integer>(); + StringTokenizer st = new StringTokenizer(vm,".-_"); + try { + result.add(Integer.parseInt(st.nextToken())); + result.add(Integer.parseInt(st.nextToken())); + } catch (Exception e) { + // NoSuchElementException if no more tokens + // NumberFormatException if not a number + } + return result; + } public static boolean is13VMOrGreater() { return 1.3 <= vmVersion; @@ -119,7 +149,7 @@ public class LangUtil { } public static boolean is19VMOrGreater() { - return 1.9 <= vmVersion; + return 9 <= vmVersion; } /** diff --git a/util/src/org/aspectj/util/SoftHashMap.java b/util/src/org/aspectj/util/SoftHashMap.java new file mode 100644 index 000000000..94ae83441 --- /dev/null +++ b/util/src/org/aspectj/util/SoftHashMap.java @@ -0,0 +1,95 @@ +/* ******************************************************************* + * Copyright (c) 2017 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * ******************************************************************/package org.aspectj.util; + +import java.lang.ref.*; +import java.util.*; + +public class SoftHashMap<K,V> extends AbstractMap<K,V> { + private Map<K, SpecialValue> map; + private ReferenceQueue<? super V> rq = new ReferenceQueue(); + + public SoftHashMap() { + this.map = new HashMap<K,SpecialValue>(); + } + + class SpecialValue extends SoftReference<V> { + private final K key; + + SpecialValue(K k, V v) { + super(v, rq); + this.key = k; + } + } + + @SuppressWarnings("unchecked") + private void processQueue() { + SpecialValue sv = null; + while ((sv = (SpecialValue)rq.poll()) != null) { + map.remove(sv.key); + } + } + + @Override + public V get(Object key) { + SpecialValue ref = map.get(key); + if (ref == null) { + map.remove(key); + return null; + } + V value = ref.get(); + if (value == null) { + map.remove(ref.key); + return null; + } + return value; + } + + @Override + public V put(K k, V v) { + processQueue(); + SpecialValue sv = new SpecialValue(k, v); + SpecialValue result = map.put(k, sv); + return (result == null ? null : result.get()); + } + + @Override + public java.util.Set<Map.Entry<K,V>> entrySet() { + if (map.isEmpty()) { return Collections.<K,V>emptyMap().entrySet(); } + Map<K,V> currentContents = new HashMap<K,V>(); + for (Map.Entry<K,SpecialValue> entry: map.entrySet()) { + V currentValueForEntry = entry.getValue().get(); + if (currentValueForEntry != null) { + currentContents.put(entry.getKey(), currentValueForEntry); + } + } + return currentContents.entrySet(); + } + + @Override + public void clear() { + processQueue(); + map.clear(); + } + + @Override + public int size() { + processQueue(); + return map.size(); + } + + @Override + public V remove(Object k) { + processQueue(); + SpecialValue ref = map.remove(k); + if (ref == null) { + return null; + } + return ref.get(); + } +} diff --git a/weaver/.classpath b/weaver/.classpath index 7792b8d4a..78357b253 100644 --- a/weaver/.classpath +++ b/weaver/.classpath @@ -11,8 +11,8 @@ <classpathentry combineaccessrules="false" kind="src" path="/aspectj5rt"/> <classpathentry kind="lib" path="/lib/commons/commons.jar" sourcepath="/lib/commons/commons-src.zip"/> <classpathentry kind="lib" path="/lib/bcel/bcel.jar" sourcepath="/lib/bcel/bcel-src.zip"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> <classpathentry combineaccessrules="false" kind="src" path="/org.aspectj.matcher"/> - <classpathentry kind="lib" path="/lib/asm/asm-5.0.4.renamed.jar"/> + <classpathentry kind="lib" path="/lib/asm/asm-6.0_BETA.renamed.jar"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/weaver/.settings/org.eclipse.jdt.core.prefs b/weaver/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..7341ab168 --- /dev/null +++ b/weaver/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +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=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java index 10fdbd05c..6ba22ed97 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java @@ -3059,6 +3059,7 @@ public class BcelShadow extends Shadow { LazyClassGen closureClass = new LazyClassGen(closureClassName, superClassName, getEnclosingClass().getFileName(), Modifier.PUBLIC, new String[] {}, getWorld()); + closureClass.setMajorMinor(getEnclosingClass().getMajor(), getEnclosingClass().getMinor()); InstructionFactory fact = new InstructionFactory(closureClass.getConstantPool()); // constructor diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index 9768cb9e4..c82c352ae 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -352,8 +352,21 @@ public class BcelTypeMunger extends ConcreteTypeMunger { && targetMethod.getBackingGenericMember().getParameterSignature().equals(newParentMethodSig)) { discoveredImpl = targetMethod; } else if (newParentMethod.hasBackingGenericMember()) { - if (newParentMethod.getBackingGenericMember().getParameterSignature().equals(targetMethodSignature)) { + if (newParentMethod.getBackingGenericMember().getParameterSignature().equals(targetMethodSignature)) { // newParentMethod.getBackingGenericMember().getParameterSignature gives: (Pjava/util/List<TI;>;) targetMethodSignature= (Ljava/util/List;) discoveredImpl = targetMethod; + } else if (targetMethod instanceof BcelMethod) { + // BcelMethod does not have backing generic member set (need to investigate why). For now, special case here: + UnresolvedType[] targetMethodGenericParameterTypes = targetMethod.getGenericParameterTypes(); + if (targetMethodGenericParameterTypes !=null) { + StringBuilder b = new StringBuilder("("); + for (UnresolvedType p: targetMethodGenericParameterTypes) { + b.append(p.getSignature()); + } + b.append(')'); + if (b.toString().equals(newParentMethodSig)) { + discoveredImpl = targetMethod; + } + } } } } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index 1a66c72b3..4306602e7 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -1035,10 +1035,12 @@ public class BcelWeaver { // repaired prior to weaving for (Iterator<UnwovenClassFile> i = input.getClassFileIterator(); i.hasNext();) { UnwovenClassFile classFile = i.next(); - String className = classFile.getClassName(); - ResolvedType theType = world.resolve(className); - if (theType != null) { - theType.ensureConsistent(); + if (classFile.shouldBeWoven()) { + String className = classFile.getClassName(); + ResolvedType theType = world.resolve(className); + if (theType != null) { + theType.ensureConsistent(); + } } } @@ -1051,22 +1053,24 @@ public class BcelWeaver { CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_ASPECTS, ""); for (Iterator<UnwovenClassFile> i = input.getClassFileIterator(); i.hasNext();) { UnwovenClassFile classFile = i.next(); - String className = classFile.getClassName(); - ResolvedType theType = world.resolve(className); - if (theType.isAnnotationStyleAspect()) { - BcelObjectType classType = BcelWorld.getBcelObjectType(theType); - if (classType == null) { - throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass()); - } - LazyClassGen clazz = classType.getLazyClassGen(); - BcelPerClauseAspectAdder selfMunger = new BcelPerClauseAspectAdder(theType, theType.getPerClause().getKind()); - selfMunger.forceMunge(clazz, true); - classType.finishedWith(); - UnwovenClassFile[] newClasses = getClassFilesFor(clazz); - for (int news = 0; news < newClasses.length; news++) { - requestor.acceptResult(newClasses[news]); + if (classFile.shouldBeWoven()) { + String className = classFile.getClassName(); + ResolvedType theType = world.resolve(className); + if (theType.isAnnotationStyleAspect()) { + BcelObjectType classType = BcelWorld.getBcelObjectType(theType); + if (classType == null) { + throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass()); + } + LazyClassGen clazz = classType.getLazyClassGen(); + BcelPerClauseAspectAdder selfMunger = new BcelPerClauseAspectAdder(theType, theType.getPerClause().getKind()); + selfMunger.forceMunge(clazz, true); + classType.finishedWith(); + UnwovenClassFile[] newClasses = getClassFilesFor(clazz); + for (int news = 0; news < newClasses.length; news++) { + requestor.acceptResult(newClasses[news]); + } + wovenClassNames.add(classFile.getClassName()); } - wovenClassNames.add(classFile.getClassName()); } } requestor.weaveCompleted(); @@ -1081,17 +1085,19 @@ public class BcelWeaver { // clear all state from files we'll be reweaving for (Iterator<UnwovenClassFile> i = input.getClassFileIterator(); i.hasNext();) { UnwovenClassFile classFile = i.next(); - String className = classFile.getClassName(); - BcelObjectType classType = getClassType(className); - - // null return from getClassType() means the delegate is an eclipse - // source type - so - // there *cant* be any reweavable state... (he bravely claimed...) - if (classType != null) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase( - CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE, className); - processReweavableStateIfPresent(className, classType); - CompilationAndWeavingContext.leavingPhase(tok); + if (classFile.shouldBeWoven()) { + String className = classFile.getClassName(); + BcelObjectType classType = getClassType(className); + + // null return from getClassType() means the delegate is an eclipse + // source type - so + // there *cant* be any reweavable state... (he bravely claimed...) + if (classType != null) { + ContextToken tok = CompilationAndWeavingContext.enteringPhase( + CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE, className); + processReweavableStateIfPresent(className, classType); + CompilationAndWeavingContext.leavingPhase(tok); + } } } @@ -1112,7 +1118,9 @@ public class BcelWeaver { List<String> typesToProcess = new ArrayList<String>(); for (Iterator<UnwovenClassFile> iter = input.getClassFileIterator(); iter.hasNext();) { UnwovenClassFile clf = iter.next(); - typesToProcess.add(clf.getClassName()); + if (clf.shouldBeWoven()) { + typesToProcess.add(clf.getClassName()); + } } while (typesToProcess.size() > 0) { weaveParentsFor(typesToProcess, typesToProcess.get(0), null); @@ -1120,8 +1128,10 @@ public class BcelWeaver { for (Iterator<UnwovenClassFile> i = input.getClassFileIterator(); i.hasNext();) { UnwovenClassFile classFile = i.next(); - String className = classFile.getClassName(); - addNormalTypeMungers(className); + if (classFile.shouldBeWoven()) { + String className = classFile.getClassName(); + addNormalTypeMungers(className); + } } CompilationAndWeavingContext.leavingPhase(typeMungingToken); @@ -1131,28 +1141,30 @@ public class BcelWeaver { // first weave into aspects for (Iterator<UnwovenClassFile> i = input.getClassFileIterator(); i.hasNext();) { UnwovenClassFile classFile = i.next(); - String className = classFile.getClassName(); - ResolvedType theType = world.resolve(className); - if (theType.isAspect()) { - BcelObjectType classType = BcelWorld.getBcelObjectType(theType); - if (classType == null) { - - // Sometimes.. if the Bcel Delegate couldn't be found then a - // problem occurred at compile time - on - // a previous compiler run. In this case I assert the - // delegate will still be an EclipseSourceType - // and we can ignore the problem here (the original compile - // error will be reported again from - // the eclipse source type) - pr113531 - ReferenceTypeDelegate theDelegate = ((ReferenceType) theType).getDelegate(); - if (theDelegate.getClass().getName().endsWith("EclipseSourceType")) { - continue; + if (classFile.shouldBeWoven()) { + String className = classFile.getClassName(); + ResolvedType theType = world.resolve(className); + if (theType.isAspect()) { + BcelObjectType classType = BcelWorld.getBcelObjectType(theType); + if (classType == null) { + + // Sometimes.. if the Bcel Delegate couldn't be found then a + // problem occurred at compile time - on + // a previous compiler run. In this case I assert the + // delegate will still be an EclipseSourceType + // and we can ignore the problem here (the original compile + // error will be reported again from + // the eclipse source type) - pr113531 + ReferenceTypeDelegate theDelegate = ((ReferenceType) theType).getDelegate(); + if (theDelegate.getClass().getName().endsWith("EclipseSourceType")) { + continue; + } + + throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass()); } - - throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass()); + weaveAndNotify(classFile, classType, requestor); + wovenClassNames.add(className); } - weaveAndNotify(classFile, classType, requestor); - wovenClassNames.add(className); } } @@ -1163,25 +1175,27 @@ public class BcelWeaver { // then weave into non-aspects for (Iterator<UnwovenClassFile> i = input.getClassFileIterator(); i.hasNext();) { UnwovenClassFile classFile = i.next(); - String className = classFile.getClassName(); - ResolvedType theType = world.resolve(className); - if (!theType.isAspect()) { - BcelObjectType classType = BcelWorld.getBcelObjectType(theType); - if (classType == null) { - - // bug 119882 - see above comment for bug 113531 - ReferenceTypeDelegate theDelegate = ((ReferenceType) theType).getDelegate(); - - // TODO urgh - put a method on the interface to check this, - // string compare is hideous - if (theDelegate.getClass().getName().endsWith("EclipseSourceType")) { - continue; + if (classFile.shouldBeWoven()) { + String className = classFile.getClassName(); + ResolvedType theType = world.resolve(className); + if (!theType.isAspect()) { + BcelObjectType classType = BcelWorld.getBcelObjectType(theType); + if (classType == null) { + + // bug 119882 - see above comment for bug 113531 + ReferenceTypeDelegate theDelegate = ((ReferenceType) theType).getDelegate(); + + // TODO urgh - put a method on the interface to check this, + // string compare is hideous + if (theDelegate.getClass().getName().endsWith("EclipseSourceType")) { + continue; + } + + throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass()); } - - throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass()); + weaveAndNotify(classFile, classType, requestor); + wovenClassNames.add(className); } - weaveAndNotify(classFile, classType, requestor); - wovenClassNames.add(className); } } CompilationAndWeavingContext.leavingPhase(classToken); diff --git a/weaver/src/org/aspectj/weaver/bcel/ClassPathManager.java b/weaver/src/org/aspectj/weaver/bcel/ClassPathManager.java index f176f8880..14fb6e9ac 100644 --- a/weaver/src/org/aspectj/weaver/bcel/ClassPathManager.java +++ b/weaver/src/org/aspectj/weaver/bcel/ClassPathManager.java @@ -1,5 +1,5 @@ /* ******************************************************************* - * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * Copyright (c) 2002, 2017 Contributors * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 @@ -7,35 +7,57 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * PARC initial implementation + * Palo Alto Research Center, Incorporated (PARC). * ******************************************************************/ - package org.aspectj.weaver.bcel; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.aspectj.bridge.IMessageHandler; import org.aspectj.bridge.MessageUtil; +import org.aspectj.util.LangUtil; +import org.aspectj.util.SoftHashMap; import org.aspectj.weaver.BCException; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.tools.Trace; import org.aspectj.weaver.tools.TraceFactory; +/** + * @author Andy Clement + * @author Mario Ivankovits + */ public class ClassPathManager { private static Trace trace = TraceFactory.getTraceFactory().getTrace(ClassPathManager.class); + private static int maxOpenArchives = -1; + + private static URI JRT_URI = URI.create("jrt:/"); //$NON-NLS-1$ + + private static final int MAXOPEN_DEFAULT = 1000; + private List<Entry> entries; // In order to control how many open files we have, we maintain a list. @@ -44,10 +66,6 @@ public class ClassPathManager { // and it defaults to 1000 private List<ZipFile> openArchives = new ArrayList<ZipFile>(); - private static int maxOpenArchives = -1; - - private static final int MAXOPEN_DEFAULT = 1000; - static { String openzipsString = getSystemPropertyWithoutSecurityException("org.aspectj.weaver.openarchives", Integer.toString(MAXOPEN_DEFAULT)); @@ -88,7 +106,11 @@ public class ClassPathManager { return; } try { - entries.add(new ZipFileEntry(f)); + if (lc.endsWith(LangUtil.JRT_FS)) { // Java9 + entries.add(new JImageEntry()); + } else { + entries.add(new ZipFileEntry(f)); + } } catch (IOException ioe) { MessageUtil.warn(handler, WeaverMessages.format(WeaverMessages.ZIPFILE_ENTRY_INVALID, name, ioe.getMessage())); @@ -151,11 +173,46 @@ public class ClassPathManager { public abstract void close(); } - public abstract static class Entry { + abstract static class Entry { public abstract ClassFile find(String name) throws IOException; } + + static class ByteBasedClassFile extends ClassFile { + + private byte[] bytes; + private ByteArrayInputStream bais; + private String path; + + public ByteBasedClassFile(byte[] bytes, String path) { + this.bytes = bytes; + this.path = path; + } + + @Override + public InputStream getInputStream() throws IOException { + this.bais = new ByteArrayInputStream(bytes); + return this.bais; + } - private static class FileClassFile extends ClassFile { + @Override + public String getPath() { + return this.path; + } + + @Override + public void close() { + if (this.bais!=null) { + try { + this.bais.close(); + } catch (IOException e) { + } + this.bais = null; + } + } + + } + + static class FileClassFile extends ClassFile { private File file; private FileInputStream fis; @@ -184,7 +241,7 @@ public class ClassPathManager { } } - public class DirEntry extends Entry { + class DirEntry extends Entry { private String dirPath; public DirEntry(File dir) { @@ -208,7 +265,7 @@ public class ClassPathManager { } } - private static class ZipEntryClassFile extends ClassFile { + static class ZipEntryClassFile extends ClassFile { private ZipEntry entry; private ZipFileEntry zipFile; private InputStream is; @@ -239,8 +296,143 @@ public class ClassPathManager { } } + + /** + * Maintains a shared package cache for java runtime image. This maps packages (for example: + * java/lang) to a starting root position in the filesystem (for example: /modules/java.base/java/lang). + * When searching for a type we work out the package name, use it to find where in the filesystem + * to start looking then run from there. Once found we do cache what we learn to make subsequent + * lookups of that type even faster. Maintaining just a package cache rather than complete type cache + * helps reduce memory usage but still gives reasonably fast lookup performance. + */ + static class JImageEntry extends Entry { + + private final static FileSystem fs = FileSystems.getFileSystem(JRT_URI); + + private final static Map<String, Path> fileCache = new SoftHashMap<String, Path>(); + + private final static Map<String, Path> packageCache = new HashMap<String, Path>(); + + private static boolean packageCacheInitialized = false; + + public JImageEntry() { + buildPackageMap(); + } + + class PackageCacheBuilderVisitor extends SimpleFileVisitor<Path> { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (file.getNameCount() > 3 && file.toString().endsWith(".class")) { + int fnc = file.getNameCount(); + if (fnc > 3) { // There is a package name - e.g. /modules/java.base/java/lang/Object.class + Path packagePath = file.subpath(2, fnc-1); // e.g. java/lang + String packagePathString = packagePath.toString(); + packageCache.put(packagePathString, file.subpath(0, fnc-1)); // java/lang -> /modules/java.base/java/lang + } + } + return FileVisitResult.CONTINUE; + } + } + + /** + * Create a map from package names to the specific directory of the package members in the filesystem. + */ + private synchronized void buildPackageMap() { + if (!packageCacheInitialized) { + packageCacheInitialized = true; + Iterable<java.nio.file.Path> roots = fs.getRootDirectories(); + PackageCacheBuilderVisitor visitor = new PackageCacheBuilderVisitor(); + try { + for (java.nio.file.Path path : roots) { + Files.walkFileTree(path, visitor); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + class TypeIdentifier extends SimpleFileVisitor<Path> { + + // What are we looking for? + private String name; + + // If set, where did we find it? + public Path found; + + // Basic metric count of how many files we checked before finding it + public int filesSearchedCount; + + public TypeIdentifier(String name) { + this.name = name; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + filesSearchedCount++; + if (file.getNameCount() > 2 && file.toString().endsWith(".class")) { + int fnc = file.getNameCount(); + Path filePath = file.subpath(2, fnc); + String filePathString = filePath.toString(); + if (filePathString.equals(name)) { + fileCache.put(filePathString, file); + found = file; + return FileVisitResult.TERMINATE; + } + } + return FileVisitResult.CONTINUE; + } + } + + private Path searchForFileAndCache(final Path startPath, final String name) { + TypeIdentifier locator = new TypeIdentifier(name); + try { + Files.walkFileTree(startPath, locator); + } catch (IOException e) { + throw new RuntimeException(e); + } + return locator.found; + } + + public ClassFile find(String name) throws IOException { + String fileName = name.replace('.', '/') + ".class"; + Path file = fileCache.get(fileName); + if (file == null) { + // Check the packages map to see if we know about this package + int idx = fileName.lastIndexOf('/'); + if (idx == -1) { + // Package not here + return null; + } + Path packageStart = null; + String packageName = null; + if (idx !=-1 ) { + packageName = fileName.substring(0, idx); + packageStart = packageCache.get(packageName); + if (packageStart != null) { + file = searchForFileAndCache(packageStart, fileName); + } + } + } + if (file == null) { + return null; + } + byte[] bs = Files.readAllBytes(file); + ClassFile cf = new ByteBasedClassFile(bs, fileName); + return cf; + } - public class ZipFileEntry extends Entry { + static Map<String, Path> getPackageCache() { + return packageCache; + } + + static Map<String, Path> getFileCache() { + return fileCache; + } + + } + + class ZipFileEntry extends Entry { private File file; private ZipFile zipFile; @@ -359,4 +551,10 @@ public class ClassPathManager { return aDefaultValue; } } + + // Mainly exposed for testing + public List<Entry> getEntries() { + return entries; + } + } diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java index 933402248..24240d7ca 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java @@ -53,6 +53,7 @@ import org.aspectj.apache.bcel.generic.Type; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.SourceLocation; +import org.aspectj.util.LangUtil; import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AjAttribute.WeaverState; import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; @@ -252,6 +253,19 @@ public final class LazyClassGen { regenerateGenericSignatureAttribute = true; this.world = world; } + + public void setMajorMinor(int major, int minor) { + myGen.setMajor(major); + myGen.setMinor(minor); + } + + public int getMajor() { + return myGen.getMajor(); + } + + public int getMinor() { + return myGen.getMinor(); + } // Non child type, so it comes from a real type in the world. public LazyClassGen(BcelObjectType myType) { @@ -1003,7 +1017,13 @@ public final class LazyClassGen { return tjpField; } - int modifiers = Modifier.STATIC | Modifier.FINAL ; + int modifiers = Modifier.STATIC; + + // J9: Can't always be final on Java 9 because it is set outside of clinit + // But must be final in interface + if (shadow.getEnclosingClass().isInterface()) { + modifiers |= Modifier.FINAL; + } // XXX - Do we ever inline before or after advice? If we do, then we // better include them in the check below. (or just change it to diff --git a/weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java b/weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java index d02c90130..7076316f7 100644 --- a/weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java +++ b/weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java @@ -30,19 +30,27 @@ public class UnwovenClassFile implements IUnwovenClassFile { // protected byte[] writtenBytes = null; protected List<ChildClass> writtenChildClasses = Collections.emptyList(); protected String className = null; + protected boolean isModule = false; public UnwovenClassFile(String filename, byte[] bytes) { this.filename = filename; + this.isModule = filename.toLowerCase().endsWith("module-info.java"); this.bytes = bytes; } /** Use if the classname is known, saves a bytecode parse */ public UnwovenClassFile(String filename, String classname, byte[] bytes) { this.filename = filename; + this.isModule = filename.toLowerCase().endsWith("module-info.class"); this.className = classname; this.bytes = bytes; } + public boolean shouldBeWoven() { + // Skip module-info files for now, they aren't really types + return !isModule; + } + public String getFilename() { return filename; } diff --git a/weaver/src/org/aspectj/weaver/bcel/Utility.java b/weaver/src/org/aspectj/weaver/bcel/Utility.java index afbfbc7ef..cd1fd4ab8 100644 --- a/weaver/src/org/aspectj/weaver/bcel/Utility.java +++ b/weaver/src/org/aspectj/weaver/bcel/Utility.java @@ -212,7 +212,7 @@ public class Utility { kind = Constants.INVOKEVIRTUAL; } - return fact.createInvoke(m.getClassName(), m.getName(), m.getReturnType(), m.getArgumentTypes(), kind); + return fact.createInvoke(m.getClassName(), m.getName(), m.getReturnType(), m.getArgumentTypes(), kind, m.getEnclosingClass().isInterface()); } /** diff --git a/weaver/src/org/aspectj/weaver/loadtime/IWeavingContext.java b/weaver/src/org/aspectj/weaver/loadtime/IWeavingContext.java index 8f7f72c4c..51b781e86 100644 --- a/weaver/src/org/aspectj/weaver/loadtime/IWeavingContext.java +++ b/weaver/src/org/aspectj/weaver/loadtime/IWeavingContext.java @@ -16,6 +16,7 @@ import java.net.URL; import java.util.Enumeration; import java.util.List; +import org.aspectj.weaver.loadtime.definition.Definition; import org.aspectj.weaver.tools.WeavingAdaptor; /** @@ -35,7 +36,7 @@ public interface IWeavingContext { * @return an enumeration containing all of the matching resources found * @throws IOException */ - public Enumeration getResources(String name) throws IOException; + public Enumeration<URL> getResources(String name) throws IOException; /** * In an OSGi environment, determin which bundle a URL originated from. @@ -86,6 +87,6 @@ public interface IWeavingContext { * @param adaptor * @return List containing 0 or more Definition instances */ - public List getDefinitions(final ClassLoader loader, WeavingAdaptor adaptor); + public List<Definition> getDefinitions(final ClassLoader loader, WeavingAdaptor adaptor); } diff --git a/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java b/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java index 48ef6ae8a..c372afc83 100644 --- a/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java +++ b/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java @@ -20,7 +20,17 @@ import java.io.PrintWriter; import java.net.URL; import java.net.URLClassLoader; import java.security.ProtectionDomain; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.StringTokenizer; import org.aspectj.bridge.AbortException; import org.aspectj.bridge.IMessage; @@ -134,9 +144,20 @@ public class WeavingAdaptor implements IMessageContext { warn("cannot determine classpath"); } } - + // On Java9 it is possible to fail to find a URLClassLoader from which to derive a suitable classpath + // For now we can determine it from the java.class.path: + if (LangUtil.is19VMOrGreater()) { + list.add(0, LangUtil.getJrtFsFilePath()); + List<String> javaClassPathEntries = makeClasspath(System.getProperty("java.class.path")); + for (int i=javaClassPathEntries.size()-1;i>=0;i--) { + String javaClassPathEntry = javaClassPathEntries.get(i); + if (!list.contains(javaClassPathEntry)) { + list.add(0,javaClassPathEntry); + } + } + } + // On Java9 the sun.boot.class.path won't be set. System classes accessible through JRT filesystem list.addAll(0, makeClasspath(System.getProperty("sun.boot.class.path"))); - return list; } diff --git a/weaver/testdata/StaticEnclosingTjpBeforeHelloWorld.txt b/weaver/testdata/StaticEnclosingTjpBeforeHelloWorld.txt index 847ee5214..62425ac53 100644 --- a/weaver/testdata/StaticEnclosingTjpBeforeHelloWorld.txt +++ b/weaver/testdata/StaticEnclosingTjpBeforeHelloWorld.txt @@ -1,6 +1,6 @@ public class HelloWorld extends java.lang.Object: - private static final org.aspectj.lang.JoinPoint$EnclosingStaticPart ajc$tjp_0 [Synthetic] - private static final org.aspectj.lang.JoinPoint$EnclosingStaticPart ajc$tjp_1 [Synthetic] + private static org.aspectj.lang.JoinPoint$EnclosingStaticPart ajc$tjp_0 [Synthetic] + private static org.aspectj.lang.JoinPoint$EnclosingStaticPart ajc$tjp_1 [Synthetic] public void <init>(): ALOAD_0 // LHelloWorld; this (line 5) INVOKESPECIAL java.lang.Object.<init> ()V diff --git a/weaver/testdata/StaticTjpBeforeHelloWorld.9.0.txt b/weaver/testdata/StaticTjpBeforeHelloWorld.9.0.txt new file mode 100644 index 000000000..72ec8a056 --- /dev/null +++ b/weaver/testdata/StaticTjpBeforeHelloWorld.9.0.txt @@ -0,0 +1,103 @@ +public class HelloWorld extends java.lang.Object: + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] + public void <init>(): + ALOAD_0 // LHelloWorld; this (line 5) + INVOKESPECIAL java.lang.Object.<init> ()V + constructor-execution(void HelloWorld.<init>()) + | GETSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart; + | INVOKESTATIC Aspect.ajc_before (Lorg/aspectj/lang/JoinPoint$StaticPart;)V + | RETURN + constructor-execution(void HelloWorld.<init>()) + end public void <init>() + + public static void main(String[]): + method-execution(void HelloWorld.main(java.lang.String[])) + | GETSTATIC HelloWorld.ajc$tjp_3 Lorg/aspectj/lang/JoinPoint$StaticPart; (line 8) + | INVOKESTATIC Aspect.ajc_before (Lorg/aspectj/lang/JoinPoint$StaticPart;)V + | field-get(java.io.PrintStream java.lang.System.out) + | | GETSTATIC HelloWorld.ajc$tjp_1 Lorg/aspectj/lang/JoinPoint$StaticPart; + | | INVOKESTATIC Aspect.ajc_before (Lorg/aspectj/lang/JoinPoint$StaticPart;)V + | | GETSTATIC java.lang.System.out Ljava/io/PrintStream; + | field-get(java.io.PrintStream java.lang.System.out) + | LDC "hello world" (line 9) + | method-call(void java.io.PrintStream.println(java.lang.String)) + | | GETSTATIC HelloWorld.ajc$tjp_2 Lorg/aspectj/lang/JoinPoint$StaticPart; + | | INVOKESTATIC Aspect.ajc_before (Lorg/aspectj/lang/JoinPoint$StaticPart;)V + | | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V + | method-call(void java.io.PrintStream.println(java.lang.String)) + | RETURN (line 11) + method-execution(void HelloWorld.main(java.lang.String[])) + end public static void main(String[]) + + static void <clinit>(): + INVOKESTATIC HelloWorld.ajc$preClinit ()V + staticinitialization(void HelloWorld.<clinit>()) + | RETURN + staticinitialization(void HelloWorld.<clinit>()) + end static void <clinit>() + + private static void ajc$preClinit(): + NEW org.aspectj.runtime.reflect.Factory + DUP + LDC "HelloWorld.java" + LDC "HelloWorld" + INVOKESTATIC java.lang.Class.forName (Ljava/lang/String;)Ljava/lang/Class; + INVOKESPECIAL org.aspectj.runtime.reflect.Factory.<init> (Ljava/lang/String;Ljava/lang/Class;)V + ASTORE_0 + ALOAD_0 + LDC "constructor-execution" + ALOAD_0 + LDC "1" + LDC "HelloWorld" + LDC "" + LDC "" + LDC "" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeConstructorSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/ConstructorSignature; + ICONST_5 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "field-get" + ALOAD_0 + LDC "19" + LDC "out" + LDC "java.lang.System" + LDC "java.io.PrintStream" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeFieldSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/FieldSignature; + BIPUSH 8 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_1 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "method-call" + ALOAD_0 + LDC "1" + LDC "println" + LDC "java.io.PrintStream" + LDC "java.lang.String" + LDC "x" + LDC "" + LDC "void" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeMethodSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/MethodSignature; + BIPUSH 9 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_2 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "method-execution" + ALOAD_0 + LDC "9" + LDC "main" + LDC "HelloWorld" + LDC "[Ljava.lang.String;" + LDC "args" + LDC "" + LDC "void" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeMethodSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/MethodSignature; + BIPUSH 8 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_3 Lorg/aspectj/lang/JoinPoint$StaticPart; + RETURN + end private static void ajc$preClinit() +end public class HelloWorld diff --git a/weaver/testdata/StaticTjpBeforeHelloWorld.txt b/weaver/testdata/StaticTjpBeforeHelloWorld.txt index 587838f4f..ff631f57f 100644 --- a/weaver/testdata/StaticTjpBeforeHelloWorld.txt +++ b/weaver/testdata/StaticTjpBeforeHelloWorld.txt @@ -1,8 +1,8 @@ public class HelloWorld extends java.lang.Object: - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] public void <init>(): ALOAD_0 // LHelloWorld; this (line 5) INVOKESPECIAL java.lang.Object.<init> ()V diff --git a/weaver/testdata/TjpAround2HelloWorld.9.0.txt b/weaver/testdata/TjpAround2HelloWorld.9.0.txt new file mode 100644 index 000000000..242d2be48 --- /dev/null +++ b/weaver/testdata/TjpAround2HelloWorld.9.0.txt @@ -0,0 +1,505 @@ +public class HelloWorld extends java.lang.Object: + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] + public void <init>(): + ALOAD_0 // LHelloWorld; ajc$this (line 5) + INVOKESPECIAL java.lang.Object.<init> ()V + GETSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + ALOAD_0 + INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + ASTORE_1 + constructor-execution(void HelloWorld.<init>()) + | ICONST_2 + | ANEWARRAY java.lang.Object + | ASTORE_3 + | ALOAD_3 + | ICONST_0 + | ALOAD_0 + | AASTORE + | ALOAD_3 + | ICONST_1 + | ALOAD_1 + | AASTORE + | NEW HelloWorld$AjcClosure3 + | DUP + | ALOAD_3 + | INVOKESPECIAL HelloWorld$AjcClosure3.<init> ([Ljava/lang/Object;)V + | ALOAD_1 + | INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + | POP + | RETURN + constructor-execution(void HelloWorld.<init>()) + end public void <init>() + + public static void main(String[]): + ALOAD_0 + ASTORE 9 + GETSTATIC HelloWorld.ajc$tjp_3 Lorg/aspectj/lang/JoinPoint$StaticPart; + ACONST_NULL + ACONST_NULL + ALOAD 9 + INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + ASTORE 10 + method-execution(void HelloWorld.main(java.lang.String[])) + | ICONST_2 (line 8) + | ANEWARRAY java.lang.Object + | ASTORE 12 + | ALOAD 12 + | ICONST_0 + | ALOAD 9 + | AASTORE + | ALOAD 12 + | ICONST_1 + | ALOAD 10 + | AASTORE + | NEW HelloWorld$AjcClosure15 + | DUP + | ALOAD 12 + | INVOKESPECIAL HelloWorld$AjcClosure15.<init> ([Ljava/lang/Object;)V + | ALOAD 10 + | INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + | POP + | RETURN + method-execution(void HelloWorld.main(java.lang.String[])) + end public static void main(String[]) + + static void <clinit>(): + INVOKESTATIC HelloWorld.ajc$preClinit ()V + staticinitialization(void HelloWorld.<clinit>()) + | RETURN + staticinitialization(void HelloWorld.<clinit>()) + end static void <clinit>() + + static final void init$_aroundBody0(HelloWorld, org.aspectj.lang.JoinPoint): + RETURN (line 5) + end static final void init$_aroundBody0(HelloWorld, org.aspectj.lang.JoinPoint) + + static final void init$_aroundBody2(HelloWorld, org.aspectj.lang.JoinPoint): + ICONST_2 + ANEWARRAY java.lang.Object + ASTORE_2 + ALOAD_2 + ICONST_0 + ALOAD_0 + AASTORE + ALOAD_2 + ICONST_1 + ALOAD_1 + AASTORE + NEW HelloWorld$AjcClosure1 + DUP + ALOAD_2 + INVOKESPECIAL HelloWorld$AjcClosure1.<init> ([Ljava/lang/Object;)V + ALOAD_1 + INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + POP + RETURN + end static final void init$_aroundBody2(HelloWorld, org.aspectj.lang.JoinPoint) + + static final java.io.PrintStream out_aroundBody4(org.aspectj.lang.JoinPoint): + GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 8) + ARETURN + end static final java.io.PrintStream out_aroundBody4(org.aspectj.lang.JoinPoint) + + static final java.io.PrintStream out_aroundBody6(org.aspectj.lang.JoinPoint): + ICONST_1 + ANEWARRAY java.lang.Object + ASTORE_1 + ALOAD_1 + ICONST_0 + ALOAD_0 + AASTORE + NEW HelloWorld$AjcClosure5 + DUP + ALOAD_1 + INVOKESPECIAL HelloWorld$AjcClosure5.<init> ([Ljava/lang/Object;)V + ALOAD_0 + INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + CHECKCAST java.io.PrintStream + ARETURN + end static final java.io.PrintStream out_aroundBody6(org.aspectj.lang.JoinPoint) + + static final void println_aroundBody8(java.io.PrintStream, String, org.aspectj.lang.JoinPoint): + ALOAD_0 + ALOAD_1 + INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V (line 9) + RETURN + end static final void println_aroundBody8(java.io.PrintStream, String, org.aspectj.lang.JoinPoint) + + static final void println_aroundBody10(java.io.PrintStream, String, org.aspectj.lang.JoinPoint): + ICONST_3 + ANEWARRAY java.lang.Object + ASTORE_3 + ALOAD_3 + ICONST_0 + ALOAD_0 + AASTORE + ALOAD_3 + ICONST_1 + ALOAD_1 + AASTORE + ALOAD_3 + ICONST_2 + ALOAD_2 + AASTORE + NEW HelloWorld$AjcClosure9 + DUP + ALOAD_3 + INVOKESPECIAL HelloWorld$AjcClosure9.<init> ([Ljava/lang/Object;)V + ALOAD_2 + INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + POP + RETURN + end static final void println_aroundBody10(java.io.PrintStream, String, org.aspectj.lang.JoinPoint) + + static final void main_aroundBody12(String[], org.aspectj.lang.JoinPoint): + GETSTATIC HelloWorld.ajc$tjp_1 Lorg/aspectj/lang/JoinPoint$StaticPart; + ACONST_NULL + ACONST_NULL + INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + ASTORE_2 + field-get(java.io.PrintStream java.lang.System.out) + | ICONST_1 + | ANEWARRAY java.lang.Object + | ASTORE 4 + | ALOAD 4 + | ICONST_0 + | ALOAD_2 + | AASTORE + | NEW HelloWorld$AjcClosure7 + | DUP + | ALOAD 4 + | INVOKESPECIAL HelloWorld$AjcClosure7.<init> ([Ljava/lang/Object;)V + | ALOAD_2 + | INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + | CHECKCAST java.io.PrintStream + field-get(java.io.PrintStream java.lang.System.out) + LDC "hello world" (line 9) + ASTORE 6 + ASTORE 8 + GETSTATIC HelloWorld.ajc$tjp_2 Lorg/aspectj/lang/JoinPoint$StaticPart; + ACONST_NULL + ALOAD 8 + ALOAD 6 + INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + ASTORE 10 + method-call(void java.io.PrintStream.println(java.lang.String)) + | ICONST_3 + | ANEWARRAY java.lang.Object + | ASTORE 12 + | ALOAD 12 + | ICONST_0 + | ALOAD 8 + | AASTORE + | ALOAD 12 + | ICONST_1 + | ALOAD 6 + | AASTORE + | ALOAD 12 + | ICONST_2 + | ALOAD 10 + | AASTORE + | NEW HelloWorld$AjcClosure11 + | DUP + | ALOAD 12 + | INVOKESPECIAL HelloWorld$AjcClosure11.<init> ([Ljava/lang/Object;)V + | ALOAD 10 + | INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + | POP + method-call(void java.io.PrintStream.println(java.lang.String)) + RETURN (line 11) + end static final void main_aroundBody12(String[], org.aspectj.lang.JoinPoint) + + static final void main_aroundBody14(String[], org.aspectj.lang.JoinPoint): + ICONST_2 (line 8) + ANEWARRAY java.lang.Object + ASTORE_2 + ALOAD_2 + ICONST_0 + ALOAD_0 + AASTORE + ALOAD_2 + ICONST_1 + ALOAD_1 + AASTORE + NEW HelloWorld$AjcClosure13 + DUP + ALOAD_2 + INVOKESPECIAL HelloWorld$AjcClosure13.<init> ([Ljava/lang/Object;)V + ALOAD_1 + INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + POP + RETURN + end static final void main_aroundBody14(String[], org.aspectj.lang.JoinPoint) + + private static void ajc$preClinit(): + NEW org.aspectj.runtime.reflect.Factory + DUP + LDC "HelloWorld.java" + LDC "HelloWorld" + INVOKESTATIC java.lang.Class.forName (Ljava/lang/String;)Ljava/lang/Class; + INVOKESPECIAL org.aspectj.runtime.reflect.Factory.<init> (Ljava/lang/String;Ljava/lang/Class;)V + ASTORE_0 + ALOAD_0 + LDC "constructor-execution" + ALOAD_0 + LDC "1" + LDC "HelloWorld" + LDC "" + LDC "" + LDC "" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeConstructorSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/ConstructorSignature; + ICONST_5 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "field-get" + ALOAD_0 + LDC "19" + LDC "out" + LDC "java.lang.System" + LDC "java.io.PrintStream" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeFieldSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/FieldSignature; + BIPUSH 8 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_1 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "method-call" + ALOAD_0 + LDC "1" + LDC "println" + LDC "java.io.PrintStream" + LDC "java.lang.String" + LDC "x" + LDC "" + LDC "void" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeMethodSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/MethodSignature; + BIPUSH 9 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_2 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "method-execution" + ALOAD_0 + LDC "9" + LDC "main" + LDC "HelloWorld" + LDC "[Ljava.lang.String;" + LDC "args" + LDC "" + LDC "void" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeMethodSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/MethodSignature; + BIPUSH 8 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_3 Lorg/aspectj/lang/JoinPoint$StaticPart; + RETURN + end private static void ajc$preClinit() +end public class HelloWorld + +public class HelloWorld$AjcClosure1 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST HelloWorld + ALOAD_2 + ICONST_1 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.init$_aroundBody0 (LHelloWorld;Lorg/aspectj/lang/JoinPoint;)V + ACONST_NULL + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure1 + +public class HelloWorld$AjcClosure3 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST HelloWorld + ALOAD_2 + ICONST_1 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.init$_aroundBody2 (LHelloWorld;Lorg/aspectj/lang/JoinPoint;)V + ACONST_NULL + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure3 + +public class HelloWorld$AjcClosure5 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.out_aroundBody4 (Lorg/aspectj/lang/JoinPoint;)Ljava/io/PrintStream; + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure5 + +public class HelloWorld$AjcClosure7 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.out_aroundBody6 (Lorg/aspectj/lang/JoinPoint;)Ljava/io/PrintStream; + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure7 + +public class HelloWorld$AjcClosure9 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST java.io.PrintStream + ALOAD_2 + ICONST_1 + AALOAD + CHECKCAST java.lang.String + ALOAD_2 + ICONST_2 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.println_aroundBody8 (Ljava/io/PrintStream;Ljava/lang/String;Lorg/aspectj/lang/JoinPoint;)V + ACONST_NULL + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure9 + +public class HelloWorld$AjcClosure11 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST java.io.PrintStream + ALOAD_2 + ICONST_1 + AALOAD + CHECKCAST java.lang.String + ALOAD_2 + ICONST_2 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.println_aroundBody10 (Ljava/io/PrintStream;Ljava/lang/String;Lorg/aspectj/lang/JoinPoint;)V + ACONST_NULL + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure11 + +public class HelloWorld$AjcClosure13 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST [Ljava.lang.String; + ALOAD_2 + ICONST_1 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.main_aroundBody12 ([Ljava/lang/String;Lorg/aspectj/lang/JoinPoint;)V + ACONST_NULL + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure13 + +public class HelloWorld$AjcClosure15 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST [Ljava.lang.String; + ALOAD_2 + ICONST_1 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.main_aroundBody14 ([Ljava/lang/String;Lorg/aspectj/lang/JoinPoint;)V + ACONST_NULL + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure15 diff --git a/weaver/testdata/TjpAround2HelloWorld.txt b/weaver/testdata/TjpAround2HelloWorld.txt index 6a1affae8..76c19fca8 100644 --- a/weaver/testdata/TjpAround2HelloWorld.txt +++ b/weaver/testdata/TjpAround2HelloWorld.txt @@ -1,8 +1,8 @@ public class HelloWorld extends java.lang.Object: - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] public void <init>(): ALOAD_0 // LHelloWorld; ajc$this (line 5) INVOKESPECIAL java.lang.Object.<init> ()V diff --git a/weaver/testdata/TjpAroundHelloWorld.9.0.txt b/weaver/testdata/TjpAroundHelloWorld.9.0.txt new file mode 100644 index 000000000..65abd2ef6 --- /dev/null +++ b/weaver/testdata/TjpAroundHelloWorld.9.0.txt @@ -0,0 +1,314 @@ +public class HelloWorld extends java.lang.Object: + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] + public void <init>(): + ALOAD_0 // LHelloWorld; ajc$this (line 5) + INVOKESPECIAL java.lang.Object.<init> ()V + GETSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + ALOAD_0 + INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + ASTORE_1 + constructor-execution(void HelloWorld.<init>()) + | ICONST_2 + | ANEWARRAY java.lang.Object + | ASTORE_2 + | ALOAD_2 + | ICONST_0 + | ALOAD_0 + | AASTORE + | ALOAD_2 + | ICONST_1 + | ALOAD_1 + | AASTORE + | NEW HelloWorld$AjcClosure1 + | DUP + | ALOAD_2 + | INVOKESPECIAL HelloWorld$AjcClosure1.<init> ([Ljava/lang/Object;)V + | ALOAD_1 + | INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + | POP + | RETURN + constructor-execution(void HelloWorld.<init>()) + end public void <init>() + + public static void main(String[]): + ALOAD_0 + ASTORE 7 + GETSTATIC HelloWorld.ajc$tjp_3 Lorg/aspectj/lang/JoinPoint$StaticPart; + ACONST_NULL + ACONST_NULL + ALOAD 7 + INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + ASTORE 8 + method-execution(void HelloWorld.main(java.lang.String[])) + | ICONST_2 (line 8) + | ANEWARRAY java.lang.Object + | ASTORE 9 + | ALOAD 9 + | ICONST_0 + | ALOAD 7 + | AASTORE + | ALOAD 9 + | ICONST_1 + | ALOAD 8 + | AASTORE + | NEW HelloWorld$AjcClosure7 + | DUP + | ALOAD 9 + | INVOKESPECIAL HelloWorld$AjcClosure7.<init> ([Ljava/lang/Object;)V + | ALOAD 8 + | INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + | POP + | RETURN + method-execution(void HelloWorld.main(java.lang.String[])) + end public static void main(String[]) + + static void <clinit>(): + INVOKESTATIC HelloWorld.ajc$preClinit ()V + staticinitialization(void HelloWorld.<clinit>()) + | RETURN + staticinitialization(void HelloWorld.<clinit>()) + end static void <clinit>() + + static final void init$_aroundBody0(HelloWorld, org.aspectj.lang.JoinPoint): + RETURN (line 5) + end static final void init$_aroundBody0(HelloWorld, org.aspectj.lang.JoinPoint) + + static final java.io.PrintStream out_aroundBody2(org.aspectj.lang.JoinPoint): + GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 8) + ARETURN + end static final java.io.PrintStream out_aroundBody2(org.aspectj.lang.JoinPoint) + + static final void println_aroundBody4(java.io.PrintStream, String, org.aspectj.lang.JoinPoint): + ALOAD_0 + ALOAD_1 + INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V (line 9) + RETURN + end static final void println_aroundBody4(java.io.PrintStream, String, org.aspectj.lang.JoinPoint) + + static final void main_aroundBody6(String[], org.aspectj.lang.JoinPoint): + GETSTATIC HelloWorld.ajc$tjp_1 Lorg/aspectj/lang/JoinPoint$StaticPart; + ACONST_NULL + ACONST_NULL + INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + ASTORE_2 + field-get(java.io.PrintStream java.lang.System.out) + | ICONST_1 + | ANEWARRAY java.lang.Object + | ASTORE 4 + | ALOAD 4 + | ICONST_0 + | ALOAD_2 + | AASTORE + | NEW HelloWorld$AjcClosure3 + | DUP + | ALOAD 4 + | INVOKESPECIAL HelloWorld$AjcClosure3.<init> ([Ljava/lang/Object;)V + | ALOAD_2 + | INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + | CHECKCAST java.io.PrintStream + field-get(java.io.PrintStream java.lang.System.out) + LDC "hello world" (line 9) + ASTORE 6 + ASTORE 8 + GETSTATIC HelloWorld.ajc$tjp_2 Lorg/aspectj/lang/JoinPoint$StaticPart; + ACONST_NULL + ALOAD 8 + ALOAD 6 + INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + ASTORE 10 + method-call(void java.io.PrintStream.println(java.lang.String)) + | ICONST_3 + | ANEWARRAY java.lang.Object + | ASTORE 12 + | ALOAD 12 + | ICONST_0 + | ALOAD 8 + | AASTORE + | ALOAD 12 + | ICONST_1 + | ALOAD 6 + | AASTORE + | ALOAD 12 + | ICONST_2 + | ALOAD 10 + | AASTORE + | NEW HelloWorld$AjcClosure5 + | DUP + | ALOAD 12 + | INVOKESPECIAL HelloWorld$AjcClosure5.<init> ([Ljava/lang/Object;)V + | ALOAD 10 + | INVOKESTATIC Aspect.ajc_around (Lorg/aspectj/runtime/internal/AroundClosure;Lorg/aspectj/lang/JoinPoint;)Ljava/lang/Object; + | POP + method-call(void java.io.PrintStream.println(java.lang.String)) + RETURN (line 11) + end static final void main_aroundBody6(String[], org.aspectj.lang.JoinPoint) + + private static void ajc$preClinit(): + NEW org.aspectj.runtime.reflect.Factory + DUP + LDC "HelloWorld.java" + LDC "HelloWorld" + INVOKESTATIC java.lang.Class.forName (Ljava/lang/String;)Ljava/lang/Class; + INVOKESPECIAL org.aspectj.runtime.reflect.Factory.<init> (Ljava/lang/String;Ljava/lang/Class;)V + ASTORE_0 + ALOAD_0 + LDC "constructor-execution" + ALOAD_0 + LDC "1" + LDC "HelloWorld" + LDC "" + LDC "" + LDC "" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeConstructorSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/ConstructorSignature; + ICONST_5 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "field-get" + ALOAD_0 + LDC "19" + LDC "out" + LDC "java.lang.System" + LDC "java.io.PrintStream" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeFieldSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/FieldSignature; + BIPUSH 8 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_1 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "method-call" + ALOAD_0 + LDC "1" + LDC "println" + LDC "java.io.PrintStream" + LDC "java.lang.String" + LDC "x" + LDC "" + LDC "void" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeMethodSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/MethodSignature; + BIPUSH 9 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_2 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "method-execution" + ALOAD_0 + LDC "9" + LDC "main" + LDC "HelloWorld" + LDC "[Ljava.lang.String;" + LDC "args" + LDC "" + LDC "void" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeMethodSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/MethodSignature; + BIPUSH 8 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_3 Lorg/aspectj/lang/JoinPoint$StaticPart; + RETURN + end private static void ajc$preClinit() +end public class HelloWorld + +public class HelloWorld$AjcClosure1 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST HelloWorld + ALOAD_2 + ICONST_1 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.init$_aroundBody0 (LHelloWorld;Lorg/aspectj/lang/JoinPoint;)V + ACONST_NULL + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure1 + +public class HelloWorld$AjcClosure3 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.out_aroundBody2 (Lorg/aspectj/lang/JoinPoint;)Ljava/io/PrintStream; + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure3 + +public class HelloWorld$AjcClosure5 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST java.io.PrintStream + ALOAD_2 + ICONST_1 + AALOAD + CHECKCAST java.lang.String + ALOAD_2 + ICONST_2 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.println_aroundBody4 (Ljava/io/PrintStream;Ljava/lang/String;Lorg/aspectj/lang/JoinPoint;)V + ACONST_NULL + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure5 + +public class HelloWorld$AjcClosure7 extends org.aspectj.runtime.internal.AroundClosure: + public void <init>(Object[]): + ALOAD_0 + ALOAD_1 + INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V + RETURN + end public void <init>(Object[]) + + public Object run(Object[]): + ALOAD_0 + GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; + ASTORE_2 + ALOAD_2 + ICONST_0 + AALOAD + CHECKCAST [Ljava.lang.String; + ALOAD_2 + ICONST_1 + AALOAD + CHECKCAST org.aspectj.lang.JoinPoint + INVOKESTATIC HelloWorld.main_aroundBody6 ([Ljava/lang/String;Lorg/aspectj/lang/JoinPoint;)V + ACONST_NULL + ARETURN + end public Object run(Object[]) +end public class HelloWorld$AjcClosure7 diff --git a/weaver/testdata/TjpAroundHelloWorld.txt b/weaver/testdata/TjpAroundHelloWorld.txt index 3643d2c07..6b065bdc9 100644 --- a/weaver/testdata/TjpAroundHelloWorld.txt +++ b/weaver/testdata/TjpAroundHelloWorld.txt @@ -1,8 +1,8 @@ public class HelloWorld extends java.lang.Object: - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] public void <init>(): ALOAD_0 // LHelloWorld; ajc$this (line 5) INVOKESPECIAL java.lang.Object.<init> ()V diff --git a/weaver/testdata/TjpBeforeHelloWorld.9.0.txt b/weaver/testdata/TjpBeforeHelloWorld.9.0.txt new file mode 100644 index 000000000..0c34c3bf1 --- /dev/null +++ b/weaver/testdata/TjpBeforeHelloWorld.9.0.txt @@ -0,0 +1,131 @@ +public class HelloWorld extends java.lang.Object: + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] + public void <init>(): + ALOAD_0 // LHelloWorld; this (line 5) + INVOKESPECIAL java.lang.Object.<init> ()V + GETSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + ALOAD_0 + INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + ASTORE_1 + constructor-execution(void HelloWorld.<init>()) + | ALOAD_1 + | INVOKESTATIC Aspect.ajc_before (Lorg/aspectj/lang/JoinPoint;)V + | RETURN + constructor-execution(void HelloWorld.<init>()) + end public void <init>() + + public static void main(String[]): + ALOAD_0 + ASTORE 6 + GETSTATIC HelloWorld.ajc$tjp_3 Lorg/aspectj/lang/JoinPoint$StaticPart; + ACONST_NULL + ACONST_NULL + ALOAD 6 + INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + ASTORE 5 + method-execution(void HelloWorld.main(java.lang.String[])) + | ALOAD 5 (line 8) + | INVOKESTATIC Aspect.ajc_before (Lorg/aspectj/lang/JoinPoint;)V + | GETSTATIC HelloWorld.ajc$tjp_1 Lorg/aspectj/lang/JoinPoint$StaticPart; + | ACONST_NULL + | ACONST_NULL + | INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + | ASTORE_1 + | field-get(java.io.PrintStream java.lang.System.out) + | | ALOAD_1 + | | INVOKESTATIC Aspect.ajc_before (Lorg/aspectj/lang/JoinPoint;)V + | | GETSTATIC java.lang.System.out Ljava/io/PrintStream; + | field-get(java.io.PrintStream java.lang.System.out) + | LDC "hello world" (line 9) + | ASTORE_3 + | ASTORE 4 + | GETSTATIC HelloWorld.ajc$tjp_2 Lorg/aspectj/lang/JoinPoint$StaticPart; + | ACONST_NULL + | ALOAD 4 + | ALOAD_3 + | INVOKESTATIC org.aspectj.runtime.reflect.Factory.makeJP (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint; + | ASTORE_2 + | method-call(void java.io.PrintStream.println(java.lang.String)) + | | ALOAD_2 + | | INVOKESTATIC Aspect.ajc_before (Lorg/aspectj/lang/JoinPoint;)V + | | ALOAD 4 + | | ALOAD_3 + | | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V + | method-call(void java.io.PrintStream.println(java.lang.String)) + | RETURN (line 11) + method-execution(void HelloWorld.main(java.lang.String[])) + end public static void main(String[]) + + static void <clinit>(): + INVOKESTATIC HelloWorld.ajc$preClinit ()V + staticinitialization(void HelloWorld.<clinit>()) + | RETURN + staticinitialization(void HelloWorld.<clinit>()) + end static void <clinit>() + + private static void ajc$preClinit(): + NEW org.aspectj.runtime.reflect.Factory + DUP + LDC "HelloWorld.java" + LDC "HelloWorld" + INVOKESTATIC java.lang.Class.forName (Ljava/lang/String;)Ljava/lang/Class; + INVOKESPECIAL org.aspectj.runtime.reflect.Factory.<init> (Ljava/lang/String;Ljava/lang/Class;)V + ASTORE_0 + ALOAD_0 + LDC "constructor-execution" + ALOAD_0 + LDC "1" + LDC "HelloWorld" + LDC "" + LDC "" + LDC "" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeConstructorSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/ConstructorSignature; + ICONST_5 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "field-get" + ALOAD_0 + LDC "19" + LDC "out" + LDC "java.lang.System" + LDC "java.io.PrintStream" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeFieldSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/FieldSignature; + BIPUSH 8 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_1 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "method-call" + ALOAD_0 + LDC "1" + LDC "println" + LDC "java.io.PrintStream" + LDC "java.lang.String" + LDC "x" + LDC "" + LDC "void" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeMethodSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/MethodSignature; + BIPUSH 9 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_2 Lorg/aspectj/lang/JoinPoint$StaticPart; + ALOAD_0 + LDC "method-execution" + ALOAD_0 + LDC "9" + LDC "main" + LDC "HelloWorld" + LDC "[Ljava.lang.String;" + LDC "args" + LDC "" + LDC "void" + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeMethodSig (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/MethodSignature; + BIPUSH 8 + INVOKEVIRTUAL org.aspectj.runtime.reflect.Factory.makeSJP (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart; + PUTSTATIC HelloWorld.ajc$tjp_3 Lorg/aspectj/lang/JoinPoint$StaticPart; + RETURN + end private static void ajc$preClinit() +end public class HelloWorld diff --git a/weaver/testdata/TjpBeforeHelloWorld.txt b/weaver/testdata/TjpBeforeHelloWorld.txt index c8ed93a86..d169c765c 100644 --- a/weaver/testdata/TjpBeforeHelloWorld.txt +++ b/weaver/testdata/TjpBeforeHelloWorld.txt @@ -1,8 +1,8 @@ public class HelloWorld extends java.lang.Object: - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] - private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic] + private static org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic] public void <init>(): ALOAD_0 // LHelloWorld; this (line 5) INVOKESPECIAL java.lang.Object.<init> ()V diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/BcelTests.java b/weaver/testsrc/org/aspectj/weaver/bcel/BcelTests.java index ae7f15960..77f066083 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/BcelTests.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/BcelTests.java @@ -13,6 +13,8 @@ package org.aspectj.weaver.bcel; +import org.aspectj.util.LangUtil; + import junit.framework.*; public class BcelTests extends TestCase { @@ -43,6 +45,9 @@ public class BcelTests extends TestCase { suite.addTestSuite(WeaveOrderTestCase.class); suite.addTestSuite(WorldTestCase.class); suite.addTestSuite(ZipTestCase.class); + if (LangUtil.is19VMOrGreater()) { + suite.addTestSuite(JImageTestCase.class); + } //$JUnit-END$ return suite; } diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/JImageTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/JImageTestCase.java new file mode 100644 index 000000000..9b465ebe8 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/JImageTestCase.java @@ -0,0 +1,135 @@ +/* ******************************************************************* + * Copyright (c) 2017 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * ******************************************************************/ +package org.aspectj.weaver.bcel; + +import java.io.IOException; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessage.Kind; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.bcel.ClassPathManager.ClassFile; +import org.aspectj.weaver.bcel.ClassPathManager.Entry; +import org.aspectj.weaver.bcel.ClassPathManager.JImageEntry; + +import junit.framework.TestCase; + +/** + * Exercise the JImage handling in @link {@link org.aspectj.weaver.bcel.ClassPathManager}. + * + * @author Andy Clement + */ +public class JImageTestCase extends TestCase { + + ClassPathManager cpm; + + public void setUp() throws Exception { + List<String> paths = new ArrayList<>(); + paths.add(LangUtil.getJrtFsFilePath()); + cpm = new ClassPathManager(paths,new TestMessageHandler()); + } + + public void testOnJava9() { + assertTrue(LangUtil.is19VMOrGreater()); + } + + public void testBasicStructureAndCapabilities() { + // Should be one entry for finding JRT contents + List<Entry> entries = cpm.getEntries(); + assertEquals(1,entries.size()); + assertEquals(JImageEntry.class,entries.get(0).getClass()); + + ClassFile stringClassFile = cpm.find(UnresolvedType.JL_STRING); + assertNotNull(stringClassFile); + assertEquals("java/lang/String.class",stringClassFile.getPath()); + } + + public void testBehaviour() throws Exception { + JImageEntry jie = getJImageEntry(); + + Map<String, Path> packageCache = JImageEntry.getPackageCache(); + assertTrue(packageCache.size()>0); + // Note: seems to be about 1625 entries in it for Java9 + Path path = packageCache.get("java/lang"); + assertEquals("modules/java.base/java/lang", path.toString()); + path = packageCache.get("java/io"); + assertEquals("modules/java.base/java/io", path.toString()); + + assertNotNull(jie.find("java/lang/String")); + assertNotNull(jie.find("java/io/File")); + // TODO test the filecache, hard because difficult to simulate collection of SoftReferences + } + + + static class TestMessageHandler implements IMessageHandler { + + @Override + public boolean handleMessage(IMessage message) throws AbortException { + return false; + } + + @Override + public boolean isIgnoring(Kind kind) { + return false; + } + + @Override + public void dontIgnore(Kind kind) { + } + + @Override + public void ignore(Kind kind) { + } + + } + + // --- + + private JImageEntry getJImageEntry() { + return (JImageEntry) cpm.getEntries().get(0); + } + + public List<String> getAllTheClasses() { + final List<String> result = new ArrayList<>(); + URI JRT_URI = URI.create("jrt:/"); //$NON-NLS-1$ + FileSystem fs = FileSystems.getFileSystem(JRT_URI); + Iterable<java.nio.file.Path> roots = fs.getRootDirectories(); + try { + for (java.nio.file.Path path : roots) { + Files.walkFileTree(path, new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (file.getNameCount()>3 && file.toString().endsWith(".class")) { + String withClassSuffix = file.subpath(2, file.getNameCount()).toString(); + result.add(withClassSuffix.substring(0,withClassSuffix.length()-".class".length())); + } + return FileVisitResult.CONTINUE; + } + }); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + return result; + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/WeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/WeaveTestCase.java index e3d62faa3..109d7ed06 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/WeaveTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/WeaveTestCase.java @@ -29,6 +29,7 @@ import org.aspectj.apache.bcel.generic.InvokeInstruction; import org.aspectj.apache.bcel.generic.Type; import org.aspectj.testing.util.TestUtil; import org.aspectj.util.FileUtil; +import org.aspectj.util.LangUtil; import org.aspectj.weaver.Advice; import org.aspectj.weaver.BcweaverTests; import org.aspectj.weaver.ShadowMunger; @@ -115,7 +116,12 @@ public abstract class WeaveTestCase extends TestCase { gen = classType.getLazyClassGen(); // new LazyClassGen(classType); } try { - checkClass(gen, outDirPath, outName + ".txt"); + File possibleVmSpecificFile = new File(TESTDATA_DIR,outName + "." + LangUtil.getVmVersionString()+".txt"); + if (possibleVmSpecificFile.exists()) { + checkClass(gen, outDirPath, outName + "." + LangUtil.getVmVersionString()+".txt"); + } else { + checkClass(gen, outDirPath, outName + ".txt"); + } if (runTests) { System.out.println("*******RUNNING: " + outName + " " + name + " *******"); TestUtil.runMain(makeClassPath(outDirPath), name); diff --git a/weaver/weaver.mf.txt b/weaver/weaver.mf.txt index f0153fd1c..2c054494f 100644 --- a/weaver/weaver.mf.txt +++ b/weaver/weaver.mf.txt @@ -1,4 +1,5 @@ Manifest-Version: 1.0 +Automatic-Module-Name: org.aspectj.weaver Name: org/aspectj/weaver/ Specification-Title: AspectJ Weaver Classes diff --git a/weaver5/.settings/org.eclipse.jdt.core.prefs b/weaver5/.settings/org.eclipse.jdt.core.prefs index f43877843..1099c7bdc 100644 --- a/weaver5/.settings/org.eclipse.jdt.core.prefs +++ b/weaver5/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,8 @@ -#Tue Jan 16 09:21:24 GMT 2007 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.compliance=1.7 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -59,4 +58,4 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=di org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=ignore -org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/ArgNameFinder.java b/weaver5/java5-src/org/aspectj/weaver/reflect/ArgNameFinder.java index dc295eb2b..25945a90a 100644 --- a/weaver5/java5-src/org/aspectj/weaver/reflect/ArgNameFinder.java +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/ArgNameFinder.java @@ -1,28 +1,25 @@ /* ******************************************************************* - * Copyright (c) 2005 Contributors. + * Copyright (c) 2005-2017 Contributors. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer Initial implementation * ******************************************************************/ package org.aspectj.weaver.reflect; import java.lang.reflect.Member; /** - * @author Adrian - * + * @author Adrian Colyer + * @author Andy Clement */ public interface ArgNameFinder { /** - * Attempt to discover the parameter names for a reflectively obtained member - * @param forMember - * @return null if names can't be determined + * Attempt to discover the parameter names for a reflectively obtained member. + * @param forMember the member for which parameter names are being looked up + * @return parameter names or null if names can't be determined */ String[] getParameterNames(Member forMember); diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java index a978d9605..016becf87 100644 --- a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java @@ -1,13 +1,10 @@ /* ******************************************************************* - * Copyright (c) 2005 Contributors. + * Copyright (c) 2005, 2017 Contributors. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer Initial implementation * ******************************************************************/ package org.aspectj.weaver.reflect; @@ -17,15 +14,13 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; import org.aspectj.apache.bcel.classfile.AnnotationDefault; import org.aspectj.apache.bcel.classfile.Attribute; import org.aspectj.apache.bcel.classfile.JavaClass; import org.aspectj.apache.bcel.classfile.LocalVariable; import org.aspectj.apache.bcel.classfile.LocalVariableTable; +import org.aspectj.apache.bcel.util.ClassLoaderRepository; import org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository; import org.aspectj.apache.bcel.util.Repository; import org.aspectj.weaver.AnnotationAJ; @@ -36,36 +31,44 @@ import org.aspectj.weaver.bcel.BcelAnnotation; import org.aspectj.weaver.bcel.BcelWeakClassLoaderReference; /** - * Find the given annotation (if present) on the given object * + * @author Adrian Colyer + * @author Andy Clement */ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder { + public static final ResolvedType[][] NO_PARAMETER_ANNOTATIONS = new ResolvedType[][] {}; + private Repository bcelRepository; private BcelWeakClassLoaderReference classLoaderRef; private World world; + private static boolean useCachingClassLoaderRepository; + + static { + try { + useCachingClassLoaderRepository = System.getProperty("Xset:bcelRepositoryCaching","true").equalsIgnoreCase("true"); + } catch (Throwable t) { + useCachingClassLoaderRepository = false; + } + } // must have no-arg constructor for reflective construction public Java15AnnotationFinder() { } public void setClassLoader(ClassLoader aLoader) { - // TODO: No easy way to ask the world factory for the right kind of - // repository so - // default to the safe one! (pr160674) this.classLoaderRef = new BcelWeakClassLoaderReference(aLoader); - this.bcelRepository = new NonCachingClassLoaderRepository(classLoaderRef); + if (useCachingClassLoaderRepository) { + this.bcelRepository = new ClassLoaderRepository(classLoaderRef); + } else { + this.bcelRepository = new NonCachingClassLoaderRepository(classLoaderRef); + } } public void setWorld(World aWorld) { this.world = aWorld; } - /* - * (non-Javadoc) - * - * @see org.aspectj.weaver.reflect.AnnotationFinder#getAnnotation(org.aspectj .weaver.ResolvedType, java.lang.Object) - */ public Object getAnnotation(ResolvedType annotationType, Object onObject) { try { Class<? extends Annotation> annotationClass = (Class<? extends Annotation>) Class.forName(annotationType.getName(), @@ -155,7 +158,6 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder { } catch (ClassNotFoundException cnfEx) { // just use reflection then } - return null; } @@ -186,80 +188,76 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder { } catch (ClassNotFoundException cnfEx) { // just use reflection then } - return null; } - public Set getAnnotations(Member onMember) { - if (!(onMember instanceof AccessibleObject)) - return Collections.EMPTY_SET; - // here we really want both the runtime visible AND the class visible - // annotations - // so we bail out to Bcel and then chuck away the JavaClass so that we - // don't hog - // memory. - try { - JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass()); - org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[] anns = new org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[0]; - if (onMember instanceof Method) { - org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember); - if (bcelMethod == null) { - // fallback on reflection - see pr220430 - // System.err.println( - // "Unexpected problem in Java15AnnotationFinder: cannot retrieve annotations on method '" - // + - // onMember.getName()+"' in class '"+jc.getClassName()+"'"); - } else { - anns = bcelMethod.getAnnotations(); + public ResolvedType[] getAnnotations(Member onMember, boolean areRuntimeAnnotationsSufficient) { + if (!(onMember instanceof AccessibleObject)) { + return ResolvedType.NONE; + } + // If annotations with class level retention are required then we need to open + // open the class file. If only runtime retention annotations are required + // we can just use reflection. + if (!areRuntimeAnnotationsSufficient) { + try { + JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass()); + org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[] anns = null; + if (onMember instanceof Method) { + org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember); + if (bcelMethod != null) { + anns = bcelMethod.getAnnotations(); + } + } else if (onMember instanceof Constructor) { + org.aspectj.apache.bcel.classfile.Method bcelCons = jc.getMethod((Constructor) onMember); + anns = bcelCons.getAnnotations(); + } else if (onMember instanceof Field) { + org.aspectj.apache.bcel.classfile.Field bcelField = jc.getField((Field) onMember); + anns = bcelField.getAnnotations(); } - } else if (onMember instanceof Constructor) { - org.aspectj.apache.bcel.classfile.Method bcelCons = jc.getMethod((Constructor) onMember); - anns = bcelCons.getAnnotations(); - } else if (onMember instanceof Field) { - org.aspectj.apache.bcel.classfile.Field bcelField = jc.getField((Field) onMember); - anns = bcelField.getAnnotations(); - } - // the answer is cached and we don't want to hold on to memory - bcelRepository.clear(); - // OPTIMIZE make this a constant 0 size array - if (anns == null) - anns = new org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[0]; - // convert to our Annotation type - Set<ResolvedType> annSet = new HashSet<ResolvedType>(); - for (int i = 0; i < anns.length; i++) { - annSet.add(world.resolve(UnresolvedType.forSignature(anns[i].getTypeSignature()))); + // the answer is cached and we don't want to hold on to memory + bcelRepository.clear(); + if (anns == null || anns.length == 0) { + return ResolvedType.NONE; + } + ResolvedType[] annotationTypes = new ResolvedType[anns.length]; + for (int i = 0; i < anns.length; i++) { + annotationTypes[i] = world.resolve(UnresolvedType.forSignature(anns[i].getTypeSignature())); + } + return annotationTypes; + } catch (ClassNotFoundException cnfEx) { + // just use reflection then } - return annSet; - } catch (ClassNotFoundException cnfEx) { - // just use reflection then } AccessibleObject ao = (AccessibleObject) onMember; Annotation[] anns = ao.getDeclaredAnnotations(); - Set<UnresolvedType> annSet = new HashSet<UnresolvedType>(); + if (anns.length == 0) { + return ResolvedType.NONE; + } + ResolvedType[] annotationTypes = new ResolvedType[anns.length]; for (int i = 0; i < anns.length; i++) { - annSet.add(UnresolvedType.forName(anns[i].annotationType().getName()).resolve(world)); + annotationTypes[i] = UnresolvedType.forName(anns[i].annotationType().getName()).resolve(world); } - return annSet; + return annotationTypes; } public ResolvedType[] getAnnotations(Class forClass, World inWorld) { // here we really want both the runtime visible AND the class visible - // annotations - // so we bail out to Bcel and then chuck away the JavaClass so that we - // don't hog - // memory. + // annotations so we bail out to Bcel and then chuck away the JavaClass so that we + // don't hog memory. try { JavaClass jc = bcelRepository.loadClass(forClass); org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[] anns = jc.getAnnotations(); bcelRepository.clear(); - if (anns == null) + if (anns == null) { return ResolvedType.NONE; - ResolvedType[] ret = new ResolvedType[anns.length]; - for (int i = 0; i < ret.length; i++) { - ret[i] = inWorld.resolve(UnresolvedType.forSignature(anns[i].getTypeSignature())); + } else { + ResolvedType[] ret = new ResolvedType[anns.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = inWorld.resolve(UnresolvedType.forSignature(anns[i].getTypeSignature())); + } + return ret; } - return ret; } catch (ClassNotFoundException cnfEx) { // just use reflection then } @@ -313,8 +311,6 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder { return ret; } - public static final ResolvedType[][] NO_PARAMETER_ANNOTATIONS = new ResolvedType[][] {}; - public ResolvedType[][] getParameterAnnotationTypes(Member onMember) { if (!(onMember instanceof AccessibleObject)) return NO_PARAMETER_ANNOTATIONS; diff --git a/weaver5/java5-testsrc/org/aspectj/weaver/TestJava5ReflectionBasedReferenceTypeDelegate.java b/weaver5/java5-testsrc/org/aspectj/weaver/TestJava5ReflectionBasedReferenceTypeDelegate.java index 3eb59cad6..f5061e32b 100644 --- a/weaver5/java5-testsrc/org/aspectj/weaver/TestJava5ReflectionBasedReferenceTypeDelegate.java +++ b/weaver5/java5-testsrc/org/aspectj/weaver/TestJava5ReflectionBasedReferenceTypeDelegate.java @@ -1,5 +1,5 @@ /* ******************************************************************* - * Copyright (c) 2005 Contributors. + * Copyright (c) 2005-2017 Contributors. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 @@ -15,6 +15,10 @@ package org.aspectj.weaver; import junit.framework.Test; import junit.framework.TestSuite; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Field; + import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegateTest; public class TestJava5ReflectionBasedReferenceTypeDelegate extends ReflectionBasedReferenceTypeDelegateTest { @@ -74,4 +78,70 @@ public class TestJava5ReflectionBasedReferenceTypeDelegate extends ReflectionBas assertTrue("Superclass for Map generic type should be Object but was " + rt2, rt2.equals(UnresolvedType.OBJECT)); } + /** + * This is testing the optimization in the reflective annotation finder to verify that if you only want runtime + * annotation info then we use reflection and don't go digging through the classfile bytes. + */ + public void testAnnotationFinderClassRetention() throws Exception { + ResolvedType type = world.resolve(AnnoTesting.class.getName()); + ResolvedMember[] ms = type.getDeclaredMethods(); + int findMethod = findMethod("a", ms); + + ResolvedMember methodWithOnlyClassLevelAnnotation = ms[findMethod("a", ms)]; + ResolvedMember methodWithOnlyRuntimeLevelAnnotation = ms[findMethod("b", ms)]; + ResolvedMember methodWithClassAndRuntimeLevelAnnotations = ms[findMethod("c", ms)]; + ResolvedMember methodWithClassAndRuntimeLevelAnnotations2 = ms[findMethod("d", ms)]; + + assertTrue(methodWithOnlyClassLevelAnnotation.hasAnnotation(world.resolve(AnnoClass.class.getName()))); + assertTrue(methodWithOnlyRuntimeLevelAnnotation.hasAnnotation(world.resolve(AnnoRuntime.class.getName()))); + + // This is the tricky scenario. + + // When asking about the runtime level annotations it should not go digging into bcel + assertTrue(methodWithClassAndRuntimeLevelAnnotations.hasAnnotation(world.resolve(AnnoRuntime.class.getName()))); + + Field annotationsField = ResolvedMemberImpl.class.getDeclaredField("annotationTypes"); + annotationsField.setAccessible(true); + ResolvedType[] annoTypes = (ResolvedType[])annotationsField.get(methodWithClassAndRuntimeLevelAnnotations); + + // Should only be the runtime one here + assertEquals(1, annoTypes.length); + + // But when you do ask again and this time for class level, it should redo the unpack and pull both runtime and class out + assertTrue(methodWithClassAndRuntimeLevelAnnotations.hasAnnotation(world.resolve(AnnoClass.class.getName()))); + + annotationsField.setAccessible(true); + annoTypes = (ResolvedType[])annotationsField.get(methodWithClassAndRuntimeLevelAnnotations); + + // Now both should be there + assertEquals(2, annoTypes.length); + + assertTrue(methodWithClassAndRuntimeLevelAnnotations2.hasAnnotation(world.resolve(AnnoRuntime.class.getName()))); + // now ask for 'all annotations' via another route, this should reunpack and get them all + ResolvedType[] annotations = methodWithClassAndRuntimeLevelAnnotations2.getAnnotationTypes(); + assertEquals(2,annotations.length); + } + + @Retention(RetentionPolicy.CLASS) + @interface AnnoClass {} + + @Retention(RetentionPolicy.RUNTIME) + @interface AnnoRuntime {} + + class AnnoTesting { + + @AnnoClass + public void a() {} + + @AnnoRuntime + public void b() {} + + @AnnoClass @AnnoRuntime + public void c() {} + + @AnnoClass @AnnoRuntime + public void d() {} + + } + }
\ No newline at end of file diff --git a/weaver5/java5-testsrc/org/aspectj/weaver/reflect/ReflectionWorldTest.java b/weaver5/java5-testsrc/org/aspectj/weaver/reflect/ReflectionWorldTest.java index 3dcbf45b2..1108ca13c 100644 --- a/weaver5/java5-testsrc/org/aspectj/weaver/reflect/ReflectionWorldTest.java +++ b/weaver5/java5-testsrc/org/aspectj/weaver/reflect/ReflectionWorldTest.java @@ -1,29 +1,36 @@ /* ******************************************************************* - * Copyright (c) 2005 Contributors. + * Copyright (c) 2005,2017 Contributors. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer Initial implementation * ******************************************************************/ package org.aspectj.weaver.reflect; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.List; +import java.util.Map; import org.aspectj.bridge.IMessageHandler; import org.aspectj.weaver.ReferenceType; import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.WeakClassLoaderReference; import org.aspectj.weaver.World; import org.aspectj.weaver.bcel.BcelWorld; import junit.framework.TestCase; +/** + * @author Andy Clement + * @author Adrian Colyer + */ public class ReflectionWorldTest extends TestCase { public void testDelegateCreation() { @@ -32,6 +39,66 @@ public class ReflectionWorldTest extends TestCase { assertNotNull(rt); assertEquals("Ljava/lang/Object;", rt.getSignature()); } + + // Removed for now. In Spring the reflection worlds are customized by introducing new + // PCD handlers. It means more thought needs to be put into reusing worlds. + public void xtestReflectionWorldFactory() throws Exception { + ClassLoader parent = getClass().getClassLoader(); + ClassLoader cl1 = new URLClassLoader(new URL[] {}, parent); + ClassLoader cl2 = new URLClassLoader(new URL[] {}, parent); + + WeakClassLoaderReference wcl1 = new WeakClassLoaderReference(cl1); + WeakClassLoaderReference wcl2 = new WeakClassLoaderReference(cl2); + ReflectionWorld a = ReflectionWorld.getReflectionWorldFor(wcl1); + + ResolvedType stringClass1 = a.resolve(String.class); + assertNotNull(stringClass1); + + ReflectionWorld b = ReflectionWorld.getReflectionWorldFor(wcl1); + + // They should be the same because the classloader has not gone away + assertTrue(a==b); + + cl1 = null; + for (int i=0;i<100;i++) { + System.gc(); // How robust is it that this should be causing the reference to be collected? + } + b = ReflectionWorld.getReflectionWorldFor(wcl1); + + assertFalse(a==b); + + cl1 = new URLClassLoader(new URL[] {}, parent); + wcl1 = new WeakClassLoaderReference(cl1); + a = ReflectionWorld.getReflectionWorldFor(wcl1); + b = ReflectionWorld.getReflectionWorldFor(wcl2); + assertFalse(a==b); + + Field declaredField = ReflectionWorld.class.getDeclaredField("rworlds"); + declaredField.setAccessible(true); + Map worlds = (Map)declaredField.get(null); + assertEquals(2, worlds.size()); + + cl2 = null; + for (int i=0;i<100;i++) { + System.gc(); // How robust is it that this should be causing the reference to be collected? + } + ReflectionWorld.getReflectionWorldFor(wcl1); // need to call this to trigger tidyup + assertEquals(1, worlds.size()); + + cl1 = null; + for (int i=0;i<100;i++) { + System.gc(); // How robust is it that this should be causing the reference to be collected? + } + ReflectionWorld.getReflectionWorldFor(wcl1); // need to call this to trigger tidyup + assertEquals(0, worlds.size()); + + cl1 = new URLClassLoader(new URL[] {}, parent); + wcl1 = new WeakClassLoaderReference(cl1); + ReflectionWorld reflectionWorldFor = ReflectionWorld.getReflectionWorldFor(wcl1); + assertEquals(1, worlds.size()); + ReflectionWorld.cleanUpWorlds(); + assertEquals(0, worlds.size()); + } public void testArrayTypes() { IReflectionWorld world = new ReflectionWorld(getClass().getClassLoader()); @@ -46,6 +113,28 @@ public class ReflectionWorldTest extends TestCase { assertEquals("void", UnresolvedType.VOID, world.resolve(void.class)); } + static class AbstractSuperClass<A,B> {} + static interface InterfaceOne {} + static interface InterfaceTwo<A> {} + static class ID {} + static abstract class AbstractTestClass<T> extends AbstractSuperClass<T,ID> implements InterfaceOne, InterfaceTwo<T> { + + } + static class TestType {} +// static class ConcreteClass extends AbstractTestClass<TestType> { + static class ConcreteClass extends AbstractTestClass<List<TestType>> { + } + + static class Bar extends ConcreteClass {} + + public void testGenerics() { + ReflectionWorld world = new ReflectionWorld(getClass().getClassLoader()); +// world.lookupOrCreateName(UnresolvedType.forName(AbstractTestClass.class.getName())); +// ResolvedType resolvedType = world.resolve(AbstractTestClass.class); + JavaLangTypeToResolvedTypeConverter converter = new JavaLangTypeToResolvedTypeConverter(world); + ResolvedType resolvedType2 = converter.fromType(ConcreteClass.class); + } + public void testTypeConversions_509327() throws Exception { ReflectionWorld rWorld = new ReflectionWorld(getClass().getClassLoader()); JavaLangTypeToResolvedTypeConverter converter = new JavaLangTypeToResolvedTypeConverter(rWorld); @@ -198,5 +287,4 @@ public class ReflectionWorldTest extends TestCase { return null; } - } |