aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Clement <aclement@gopivotal.com>2014-03-18 22:21:20 -0700
committerAndy Clement <aclement@gopivotal.com>2014-03-18 22:21:20 -0700
commitc1c4a4d41f3173bb72040d91d42d07662ab703bd (patch)
treeee5f5bb17e86908b93504db85d2886e0375a94c5
parentbedb85ee870c2c0dad34d68662c83ff7033dd746 (diff)
downloadaspectj-c1c4a4d41f3173bb72040d91d42d07662ab703bd.tar.gz
aspectj-c1c4a4d41f3173bb72040d91d42d07662ab703bd.zip
merging 1.7.4 fixes into 1.8.0
-rw-r--r--docs/dist/doc/README-174.html51
-rw-r--r--docs/dist/doc/README-180.html29
-rw-r--r--docs/dist/doc/index.html3
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties2
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java60
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java3
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java354
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/Checker.java16
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/Lint.java12
-rw-r--r--testing/newsrc/org/aspectj/testing/CompileSpec.java3
-rw-r--r--tests/bugs174/ajdt_markers/Code.java20
-rw-r--r--tests/bugs174/extra_inserts/Code.java18
-rw-r--r--tests/bugs174/pr419279/Code.java10
-rw-r--r--tests/src/org/aspectj/systemtest/ajc174/Ajc174Tests.java14
-rw-r--r--tests/src/org/aspectj/systemtest/ajc174/ajc174.xml41
15 files changed, 595 insertions, 41 deletions
diff --git a/docs/dist/doc/README-174.html b/docs/dist/doc/README-174.html
new file mode 100644
index 000000000..24b53318f
--- /dev/null
+++ b/docs/dist/doc/README-174.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html> <head>
+<title>AspectJ 1.7.4 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>
+&copy; Copyright 2013 Contributors.
+All rights reserved.
+</small></div>
+
+<h1>AspectJ 1.7.4 Readme</h1>
+
+<p>Available 24-Oct-2013</p>
+
+<p>The list of resolved issues in 1.7.4 is available
+<a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced;bug_status=RESOLVED;bug_status=VERIFIED;bug_status=CLOSED;product=AspectJ;target_milestone=1.7.4;">here</a></h2>.</p>
+
+<b>Notes</b>
+<ul>
+<li>This release includes an important fix for using loadtime weaving in a JVM where JMX is turned on (<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=415266">415266</a>)
+<p>
+<li>There are some new message insert keys usable in declare error/warning (<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=420210">420210</a>)
+The new keys are:
+<tt>
+<pre>
+joinpoint.enclosingclass // Bar
+joinpoint.enclosingmember // void Bar.foo(String)
+joinpoint.enclosingmember.name // foo
+</pre>
+</tt>
+All keys are case insensitive.
+<p>
+<li>It is now possible to specify individual xlint settings without needing to supply a file (<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=419279">419279</a>)
+<tt><pre>ajc -Xlint:adviceDidNotMatch=error,noGuardForLazyTjp=ignore Foo.java</pre></tt>
+</ul>
+
+
+<!-- ============================== -->
+</body>
+</html>
+
diff --git a/docs/dist/doc/README-180.html b/docs/dist/doc/README-180.html
index f28a5ed66..78b55d8cb 100644
--- a/docs/dist/doc/README-180.html
+++ b/docs/dist/doc/README-180.html
@@ -24,36 +24,18 @@ All rights reserved.
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced;bug_status=RESOLVED;bug_status=VERIFIED;bug_status=CLOSED;product=AspectJ;target_milestone=1.8.0;">here</a></h2>.</p>
<ul>
+<li>1.8.0.RC1 available 18-Mar-2014
<li>1.8.0.M1 available 29-Jul-2013
</ul>
-<h2>Overview</h2>
-
-<p>In previous AspectJ major releases the first milestone normally tolerates weaving bytecode for the
-comparable Java level whilst the ability to compile source code for that Java level comes later.
-However, AspectJ 1.8.0.M1 is a Java 8 compiler. So why change the approach this time? Some
-consumers of AspectJ are choosing to exploit Java8 library features even though they are not
-using Java8 language constructs in their source. The Eclipse JDT compiler (in eclipse 4.3) actually
-includes a number of changes to facilitate this (basically compiling with -source 1.7 but on top
-of a 1.8 JRE). The changes are necessary because the 1.8 classes include metadata that the 1.7
-compiler just isn't expecting. For example default method implementations in interfaces. In order
-to support this mode of working AspectJ would need to update to the Eclipse 4.3 compiler. However,
-performing upgrades of the compiler inside AspectJ is non trivial and to avoid doing the
-upgrade to 4.3 and then doing a further upgrade to the Java8 compiler, we decided to jump straight
-to the Java8 compiler which already includes these changes.
-</p>
-
<h2>Notable changes</h2>
<h3>Java 8 compilation</h3>
-<p>AspectJ has been updated to the latest available BETA_JAVA8 support level in the Eclipse Java
-compiler. The BETA_JAVA8 tag chosen was commit #3D6E745.</p>
-<p><b>NOTE:</b>The Java8 libraries are still in flux and changing regularly. If you are going to
-use AspectJ 1.8.0.M1 you must run with a compatible level of Java8. We have been testing with
-beta 97. Code compiled with this compiler is not guaranteed to run on a later JDK level.
+<p>AspectJ has been updated to the latest available Eclipse Java
+compiler version that compiles Java8 code.</p>
</p>
-<p>AspectJ 1.8.0.M1 will now compile Java 8 code, here is a sample:</p>
+<p>Here is a sample AspectJ8 program:</p>
<pre><code>
=== 8< ==== C.java ==== 8< ===
@@ -105,6 +87,9 @@ class MyClass {
</code></pre>
<h4>
+<h3>Other</h3>
+<p>The fixes in the 1.7 branch which have occurred since this 1.8 branch was created
+have been merged into the 1.8 release.</p>
<!-- ============================== -->
</body>
</html>
diff --git a/docs/dist/doc/index.html b/docs/dist/doc/index.html
index ad2bdd71d..6040bc034 100644
--- a/docs/dist/doc/index.html
+++ b/docs/dist/doc/index.html
@@ -138,7 +138,8 @@
<tr> <td>README's
</td>
<td>Changes and porting guide for AspectJ
- <a href="README-180.html">1.8.0.M1</a>,
+ <a href="README-180.html">1.8.0</a>,
+ <a href="README-174.html">1.7.4</a>,
<a href="README-173.html">1.7.3</a>,
<a href="README-172.html">1.7.2</a>,
<a href="README-171.html">1.7.1</a>,
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 c9a2bf417..c52a6d545 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
@@ -5,7 +5,7 @@
org/aspectj/weaver/XlintDefault.properties for the default behavior and a template to copy.
### AspectJ-specific messages
compiler.name = AspectJ Compiler 1.8.0
-compiler.version = Eclipse Compiler BETA_JAVA8_3D6E745, 3.9
+compiler.version = Eclipse Compiler BETA_JAVA8_8661797, 3.9
compiler.copyright =
## this next one superceded by above...
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 ffd2c61af..c6cdd88e7 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
@@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.StringTokenizer;
import org.aspectj.ajdt.internal.compiler.CompilationResultDestinationManager;
import org.aspectj.util.FileUtil;
@@ -59,6 +60,7 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
private File configFile;
private String lintMode = AJLINT_DEFAULT;
+ private Map<String,String> lintOptionsMap = null;
private File lintSpecFile = null;
private int changes = EVERYTHING; // bitflags, see CompilerConfigurationChangeFlags
@@ -443,35 +445,71 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
public String getLintMode() {
return lintMode;
}
+
+ public Map<String,String> getLintOptionsMap() {
+ return lintOptionsMap;
+ }
// options...
public void setLintMode(String lintMode) {
- this.lintMode = lintMode;
String lintValue = null;
+ this.lintMode = lintMode;
if (AJLINT_IGNORE.equals(lintMode)) {
lintValue = AjCompilerOptions.IGNORE;
} else if (AJLINT_WARN.equals(lintMode)) {
lintValue = AjCompilerOptions.WARNING;
} else if (AJLINT_ERROR.equals(lintMode)) {
lintValue = AjCompilerOptions.ERROR;
+ } else {
+ // Possibly a name=value comma separated list of configurations
+ if (lintMode.indexOf("=")!=-1) {
+ this.lintMode = AJLINT_DEFAULT;
+ lintOptionsMap = new HashMap<String,String>();
+ StringTokenizer tokenizer = new StringTokenizer(lintMode,",");
+ while (tokenizer.hasMoreElements()) {
+ String option = tokenizer.nextToken();
+ int equals = option.indexOf("=");
+ if (equals!=-1) {
+ String key = option.substring(0,equals);
+ String value = option.substring(equals+1);
+ lintOptionsMap.put(key,value);
+ }
+ }
+ }
}
- if (lintValue != null) {
+ if (lintValue != null || lintOptionsMap != null ) {
Map<String, String> lintOptions = new HashMap<String, String>();
- lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName, lintValue);
- lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName, lintValue);
- lintOptions.put(AjCompilerOptions.OPTION_ReportUnresolvableMember, lintValue);
- lintOptions.put(AjCompilerOptions.OPTION_ReportTypeNotExposedToWeaver, lintValue);
- lintOptions.put(AjCompilerOptions.OPTION_ReportShadowNotInStructure, lintValue);
- lintOptions.put(AjCompilerOptions.OPTION_ReportUnmatchedSuperTypeInCall, lintValue);
- lintOptions.put(AjCompilerOptions.OPTION_ReportCannotImplementLazyTJP, lintValue);
- lintOptions.put(AjCompilerOptions.OPTION_ReportNeedSerialVersionUIDField, lintValue);
- lintOptions.put(AjCompilerOptions.OPTION_ReportIncompatibleSerialVersion, lintValue);
+ setOption(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName, lintValue, lintOptions);
+ setOption(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName, lintValue, lintOptions);
+ setOption(AjCompilerOptions.OPTION_ReportUnresolvableMember, lintValue, lintOptions);
+ setOption(AjCompilerOptions.OPTION_ReportTypeNotExposedToWeaver, lintValue, lintOptions);
+ setOption(AjCompilerOptions.OPTION_ReportShadowNotInStructure, lintValue, lintOptions);
+ setOption(AjCompilerOptions.OPTION_ReportUnmatchedSuperTypeInCall, lintValue, lintOptions);
+ setOption(AjCompilerOptions.OPTION_ReportCannotImplementLazyTJP, lintValue, lintOptions);
+ setOption(AjCompilerOptions.OPTION_ReportNeedSerialVersionUIDField, lintValue, lintOptions);
+ setOption(AjCompilerOptions.OPTION_ReportIncompatibleSerialVersion, lintValue, lintOptions);
options.set(lintOptions);
}
}
+ private void setOption(String optionKey, String lintValue, Map<String,String> lintOptionsAccumulator) {
+ if (lintOptionsMap!=null && lintOptionsMap.containsKey(optionKey)) {
+ String v = lintOptionsMap.get(lintOptionsMap);
+ if (AJLINT_IGNORE.equals(v)) {
+ lintValue = AjCompilerOptions.IGNORE;
+ } else if (AJLINT_WARN.equals(v)) {
+ lintValue = AjCompilerOptions.WARNING;
+ } else if (AJLINT_ERROR.equals(v)) {
+ lintValue = AjCompilerOptions.ERROR;
+ }
+ }
+ if (lintValue != null) {
+ lintOptionsAccumulator.put(optionKey,lintValue);
+ }
+ }
+
public boolean isTerminateAfterCompilation() {
return options.terminateAfterCompilation;
}
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 dfa878d96..76b9f5b9e 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
@@ -858,6 +858,9 @@ public class AjBuildManager implements IOutputClassFileNameProvider, IBinarySour
} else {
bcelWorld.getLint().setAll(buildConfig.getLintMode());
}
+ if (buildConfig.getLintOptionsMap() != null) {
+ bcelWorld.getLint().setFromMap(buildConfig.getLintOptionsMap());
+ }
if (buildConfig.getLintSpecFile() != null) {
bcelWorld.getLint().setFromProperties(buildConfig.getLintSpecFile());
}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java
index 88b81ebc1..965e87732 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java
@@ -35,6 +35,7 @@ import java.util.Set;
import org.aspectj.ajdt.internal.compiler.CompilationResultDestinationManager;
import org.aspectj.ajdt.internal.compiler.InterimCompilationResult;
+import org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment;
import org.aspectj.ajdt.internal.core.builder.AjBuildConfig.BinarySourceFile;
import org.aspectj.apache.bcel.classfile.ClassParser;
import org.aspectj.asm.AsmManager;
@@ -451,7 +452,7 @@ public class AjState implements CompilerConfigurationChangeFlags, TypeDelegateRe
if (state != null) {
recordDecision("ClassFileChangeChecking: found state instance managing output location : " + dir);
} else {
- recordDecision("ClassFileChangeChecking: failed to find a state instance managing output location : " + dir);
+ recordDecision("ClassFileChangeChecking: failed to find a state instance managing output location : " + dir + " (could be getting managed by JDT)");
}
}
@@ -1534,8 +1535,10 @@ public class AjState implements CompilerConfigurationChangeFlags, TypeDelegateRe
// ignore local types since they're only visible inside a single method
if (!(reader.isLocal() || reader.isAnonymous())) {
if (hasStructuralChanges(reader, existingStructure)) {
- if (world.forDEBUG_structuralChangesCode) {
- System.err.println("Detected a structural change in " + thisTime.getFilename());
+ if (listenerDefined()) {
+// if (world.forDEBUG_structuralChangesCode) {
+// System.err.println("Detected a structural change in " + thisTime.getFilename());
+ printStructuralChanges(thisTime.getFilename(),reader, existingStructure);
}
structuralChangesSinceLastFullBuild.put(thisTime.getFilename(), new Long(currentBuildTime));
recordTypeChanged(new String(reader.getName()).replace('/', '.'));
@@ -1802,6 +1805,348 @@ public class AjState implements CompilerConfigurationChangeFlags, TypeDelegateRe
return false;
}
+ private void logAnalysis(String filename, String info) {
+ if (listenerDefined()) {
+ getListener().recordDecision("StructuralAnalysis["+filename+"]: "+info);
+ }
+ }
+
+ private boolean printStructuralChanges(String filename, ClassFileReader reader, CompactTypeStructureRepresentation existingType) {
+ logAnalysis(filename,"appears to have structurally changed, printing changes:");
+ if (existingType == null) {
+ logAnalysis(filename,"have not seen this type before");
+ return true;
+ }
+
+ // modifiers
+ if (!modifiersEqual(reader.getModifiers(), existingType.modifiers)) {
+ logAnalysis(filename,"modifiers changed. old=0x"+Integer.toHexString(existingType.getModifiers())+" new=0x"+Integer.toHexString(reader.getModifiers()));
+ return true;
+ }
+
+ // generic signature
+ if (!CharOperation.equals(reader.getGenericSignature(), existingType.genericSignature)) {
+ logAnalysis(filename,"generic signature changed. old="+stringify(existingType.genericSignature)+" new="+stringify(reader.getGenericSignature()));
+ return true;
+ }
+
+ // superclass name
+ if (!CharOperation.equals(reader.getSuperclassName(), existingType.superclassName)) {
+ logAnalysis(filename,"superclass name changed. old="+stringify(existingType.superclassName)+" new="+stringify(reader.getSuperclassName()));
+ return true;
+ }
+
+ // have annotations changed on the type?
+ IBinaryAnnotation[] newAnnos = reader.getAnnotations();
+ if (newAnnos == null || newAnnos.length == 0) {
+ if (existingType.annotations != null && existingType.annotations.length != 0) {
+ logAnalysis(filename,"type used to have annotations and now does not: "+stringify(existingType.annotations));
+ return true;
+ }
+ } else {
+ IBinaryAnnotation[] existingAnnos = existingType.annotations;
+ if (existingAnnos == null || existingAnnos.length != newAnnos.length) {
+ logAnalysis(filename,"type now has annotations which it did not used to have: "+stringify(newAnnos));
+ return true;
+ }
+ // Does not allow for an order switch
+ // Does not cope with a change in values set on the annotation (hard to create a testcase where this is a problem tho)
+ for (int i = 0; i < newAnnos.length; i++) {
+ if (!CharOperation.equals(newAnnos[i].getTypeName(), existingAnnos[i].getTypeName())) {
+ logAnalysis(filename,"type annotation change at position "+i+" old="+new String(existingAnnos[i].getTypeName())+" new="+new String(newAnnos[i].getTypeName()));
+ return true;
+ }
+ }
+
+ }
+
+ // interfaces
+ char[][] existingIfs = existingType.interfaces;
+ char[][] newIfsAsChars = reader.getInterfaceNames();
+ if (newIfsAsChars == null) {
+ newIfsAsChars = EMPTY_CHAR_ARRAY;
+ } // damn I'm lazy...
+ if (existingIfs == null) {
+ existingIfs = EMPTY_CHAR_ARRAY;
+ }
+ if (existingIfs.length != newIfsAsChars.length) {
+ return true;
+ }
+ new_interface_loop: for (int i = 0; i < newIfsAsChars.length; i++) {
+ for (int j = 0; j < existingIfs.length; j++) {
+ if (CharOperation.equals(existingIfs[j], newIfsAsChars[i])) {
+ continue new_interface_loop;
+ }
+ }
+ logAnalysis(filename,"set of interfaces changed. old="+stringify(existingIfs)+" new="+stringify(newIfsAsChars));
+ return true;
+ }
+
+ // fields
+ // CompactMemberStructureRepresentation[] existingFields = existingType.fields;
+ IBinaryField[] newFields = reader.getFields();
+ if (newFields == null) {
+ newFields = CompactTypeStructureRepresentation.NoField;
+ }
+
+ // all redundant for now ... could be an optimization at some point...
+ // remove any ajc$XXX fields from those we compare with
+ // the existing fields - bug 129163
+ // List nonGenFields = new ArrayList();
+ // for (int i = 0; i < newFields.length; i++) {
+ // IBinaryField field = newFields[i];
+ // //if (!CharOperation.prefixEquals(NameMangler.AJC_DOLLAR_PREFIX,field.getName())) { // this would skip ajc$ fields
+ // //if ((field.getModifiers()&0x1000)==0) // 0x1000 => synthetic - this will skip synthetic fields (eg. this$0)
+ // nonGenFields.add(field);
+ // //}
+ // }
+ IBinaryField[] existingFs = existingType.binFields;
+ if (newFields.length != existingFs.length) {
+ logAnalysis(filename,"number of fields changed. old="+stringify(existingFs)+" new="+stringify(newFields));
+ return true;
+ }
+ new_field_loop: for (int i = 0; i < newFields.length; i++) {
+ IBinaryField field = newFields[i];
+ char[] fieldName = field.getName();
+ for (int j = 0; j < existingFs.length; j++) {
+ if (CharOperation.equals(existingFs[j].getName(), fieldName)) {
+ IBinaryField existing = existingFs[j];
+ if (!modifiersEqual(field.getModifiers(), existing.getModifiers())) {
+ logAnalysis(filename,"field modifiers changed '"+existing+"' old=0x"+Integer.toHexString(existing.getModifiers())+" new=0x"+Integer.toHexString(field.getModifiers()));
+ return true;
+ }
+ if (!CharOperation.equals(existing.getTypeName(), field.getTypeName())) {
+ logAnalysis(filename,"field type changed '"+existing+"' old="+new String(existing.getTypeName())+" new="+new String(field.getTypeName()));
+ return true;
+ }
+
+ char[] existingGSig = existing.getGenericSignature();
+ char[] fieldGSig = field.getGenericSignature();
+ if ((existingGSig == null && fieldGSig != null) || (existingGSig != null && fieldGSig == null)) {
+ logAnalysis(filename,"field generic sig changed '"+existing+"' old="+
+ (existingGSig==null?"null":new String(existingGSig))+" new="+(fieldGSig==null?"null":new String(fieldGSig)));
+ return true;
+ }
+ if (existingGSig != null) {
+ if (!CharOperation.equals(existingGSig, fieldGSig)) {
+ logAnalysis(filename,"field generic sig changed '"+existing+"' old="+
+ (existingGSig==null?"null":new String(existingGSig))+" new="+(fieldGSig==null?"null":new String(fieldGSig)));
+ return true;
+ }
+ }
+
+ continue new_field_loop;
+ }
+ }
+ logAnalysis(filename,"field changed. New field detected '"+field+"'");
+ return true;
+ }
+
+ // methods
+ // CompactMemberStructureRepresentation[] existingMethods = existingType.methods;
+ IBinaryMethod[] newMethods = reader.getMethods();
+ if (newMethods == null) {
+ newMethods = CompactTypeStructureRepresentation.NoMethod;
+ }
+
+ // all redundant for now ... could be an optimization at some point...
+
+ // Ctors in a non-static inner type have an 'extra parameter' of the enclosing type.
+ // If skippableDescriptorPrefix gets set here then it is set to the descriptor portion
+ // for this 'extra parameter'. For an inner class of pkg.Foo the skippable descriptor
+ // prefix will be '(Lpkg/Foo;' - so later when comparing <init> methods we know what to
+ // compare.
+ // IF THIS CODE NEEDS TO GET MORE COMPLICATED, I THINK ITS WORTH RIPPING IT ALL OUT AND
+ // CREATING THE STRUCTURAL CHANGES OBJECT BASED ON CLASSREADER OUTPUT RATHER THAN
+ // THE RESOLVEDTYPE - THEN THERE WOULD BE NO NEED TO TREAT SOME METHODS IN A PECULIAR
+ // WAY.
+ // char[] skippableDescriptorPrefix = null;
+ // char[] enclosingTypeName = reader.getEnclosingTypeName();
+ // boolean isStaticType = Modifier.isStatic(reader.getModifiers());
+ // if (!isStaticType && enclosingTypeName!=null) {
+ // StringBuffer sb = new StringBuffer();
+ // sb.append("(L").append(new String(enclosingTypeName)).append(";");
+ // skippableDescriptorPrefix = sb.toString().toCharArray();
+ // }
+ //
+ //
+ // // remove the aspectOf, hasAspect, clinit and ajc$XXX methods
+ // // from those we compare with the existing methods - bug 129163
+ // List nonGenMethods = new ArrayList();
+ // for (int i = 0; i < newMethods.length; i++) {
+ // IBinaryMethod method = newMethods[i];
+ // // if ((method.getModifiers() & 0x1000)!=0) continue; // 0x1000 => synthetic - will cause us to skip access$0 - is this
+ // always safe?
+ // char[] methodName = method.getSelector();
+ // // if (!CharOperation.equals(methodName,NameMangler.METHOD_ASPECTOF) &&
+ // // !CharOperation.equals(methodName,NameMangler.METHOD_HASASPECT) &&
+ // // !CharOperation.equals(methodName,NameMangler.STATIC_INITIALIZER) &&
+ // // !CharOperation.prefixEquals(NameMangler.AJC_DOLLAR_PREFIX,methodName) &&
+ // // !CharOperation.prefixEquals(NameMangler.CLINIT,methodName)) {
+ // nonGenMethods.add(method);
+ // // }
+ // }
+ IBinaryMethod[] existingMs = existingType.binMethods;
+ if (newMethods.length != existingMs.length) {
+ logAnalysis(filename,"number of methods changed. old="+stringify(existingMs)+" new="+stringify(newMethods));
+ return true;
+ }
+ new_method_loop: for (int i = 0; i < newMethods.length; i++) {
+ IBinaryMethod method = newMethods[i];
+ char[] methodName = method.getSelector();
+ for (int j = 0; j < existingMs.length; j++) {
+ if (CharOperation.equals(existingMs[j].getSelector(), methodName)) {
+ // candidate match
+ if (!CharOperation.equals(method.getMethodDescriptor(), existingMs[j].getMethodDescriptor())) {
+ // ok, the descriptors don't match, but is this a funky ctor on a non-static inner
+ // type?
+ // boolean mightBeOK =
+ // skippableDescriptorPrefix!=null && // set for inner types
+ // CharOperation.equals(methodName,NameMangler.INIT) && // ctor
+ // CharOperation.prefixEquals(skippableDescriptorPrefix,method.getMethodDescriptor()); // checking for
+ // prefix on the descriptor
+ // if (mightBeOK) {
+ // // OK, so the descriptor starts something like '(Lpkg/Foo;' - we now may need to look at the rest of the
+ // // descriptor if it takes >1 parameter.
+ // // eg. could be (Lpkg/C;Ljava/lang/String;) where the skippablePrefix is (Lpkg/C;
+ // char [] md = method.getMethodDescriptor();
+ // char[] remainder = CharOperation.subarray(md, skippableDescriptorPrefix.length, md.length);
+ // if (CharOperation.equals(remainder,BRACKET_V)) continue new_method_loop; // no other parameters to worry
+ // about
+ // char[] comparableSig = CharOperation.subarray(existingMethods[j].signature, 1,
+ // existingMethods[j].signature.length);
+ // boolean match = CharOperation.equals(comparableSig, remainder);
+ // if (match) continue new_method_loop;
+ // }
+ continue; // might be overloading
+ } else {
+ // matching sigs
+ IBinaryMethod existing = existingMs[j];
+ if (!modifiersEqual(method.getModifiers(), existing.getModifiers())) {
+ logAnalysis(filename,"method modifiers changed '"+existing+"' old=0x"+Integer.toHexString(existing.getModifiers())+" new=0x"+Integer.toHexString(method.getModifiers()));
+ return true;
+ }
+
+ if (exceptionClausesDiffer(existing, method)) {
+ logAnalysis(filename,"method exception clauses changed '"+existing+"' old="+existing+" new="+method);
+ return true;
+ }
+
+ char[] existingGSig = existing.getGenericSignature();
+ char[] methodGSig = method.getGenericSignature();
+ if ((existingGSig == null && methodGSig != null) || (existingGSig != null && methodGSig == null)) {
+ logAnalysis(filename,"method generic sig changed '"+existing+"' old="+
+ (existingGSig==null?"null":new String(existingGSig))+" new="+(methodGSig==null?"null":new String(methodGSig)));
+ return true;
+ }
+ if (existingGSig != null) {
+ if (!CharOperation.equals(existingGSig, methodGSig)) {
+ logAnalysis(filename,"method generic sig changed '"+existing+"' old="+
+ (existingGSig==null?"null":new String(existingGSig))+" new="+(methodGSig==null?"null":new String(methodGSig)));
+ return true;
+ }
+ }
+
+ continue new_method_loop;
+ }
+ }
+ // TODO missing a return true here? Meaning we have a field in the new that we can't find in the old!
+ }
+
+ logAnalysis(filename,"method changed. New method detected '"+stringify(method)+"' (might be a rename)");
+ return true; // (no match found)
+ }
+
+ // check for differences in inner types
+ // TODO could make order insensitive
+ IBinaryNestedType[] binaryNestedTypes = reader.getMemberTypes();
+ IBinaryNestedType[] existingBinaryNestedTypes = existingType.getMemberTypes();
+ if ((binaryNestedTypes == null && existingBinaryNestedTypes != null)
+ || (binaryNestedTypes != null && existingBinaryNestedTypes == null)) {
+ logAnalysis(filename,"nested types changed");
+ return true;
+ }
+ if (binaryNestedTypes != null) {
+ int bnLength = binaryNestedTypes.length;
+ if (existingBinaryNestedTypes.length != bnLength) {
+ logAnalysis(filename,"nested types changed. old="+stringify(existingBinaryNestedTypes)+" new="+stringify(binaryNestedTypes));
+ return true;
+ }
+ for (int m = 0; m < bnLength; m++) {
+ IBinaryNestedType bnt = binaryNestedTypes[m];
+ IBinaryNestedType existingBnt = existingBinaryNestedTypes[m];
+ if (!CharOperation.equals(bnt.getName(), existingBnt.getName())) {
+ logAnalysis(filename,"nested type changed name at position "+m+" old="+stringify(existingBinaryNestedTypes)+" new="+stringify(binaryNestedTypes));
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private String stringify(char[] chars) {
+ if (chars == null) {
+ return "null";
+ }
+ return new String(chars);
+ }
+
+ private String stringify(IBinaryNestedType[] binaryNestedTypes) {
+ StringBuilder buf = new StringBuilder();
+ for (IBinaryNestedType binaryNestedType: binaryNestedTypes) {
+ buf.append(binaryNestedType).append(" ");
+ }
+ return buf.toString().trim();
+ }
+
+ private String stringify(IBinaryMethod[] methods) {
+ StringBuilder buf = new StringBuilder();
+ for (IBinaryMethod method: methods) {
+ buf.append(stringify(method)).append(" ");
+ }
+ return "["+buf.toString().trim()+"]";
+ }
+
+ private String stringify(IBinaryMethod m) {
+ StringBuilder buf = new StringBuilder();
+ buf.append("0x").append(Integer.toHexString(m.getModifiers())).append(" ");
+ buf.append(m.getSelector()).append(m.getMethodDescriptor());
+ // IBinaryAnnotation[] annos = m.getAnnotations();
+ // TODO include annotations, generic sig, etc
+ return buf.toString().trim();
+ }
+
+ private String stringify(IBinaryField[] fields) {
+ StringBuilder buf = new StringBuilder();
+ for (IBinaryField field: fields) {
+ buf.append(stringify(field)).append(" ");
+ }
+ return "["+buf.toString().trim()+"]";
+ }
+
+ private Object stringify(IBinaryField f) {
+ StringBuilder buf = new StringBuilder();
+ buf.append("0x").append(Integer.toHexString(f.getModifiers())).append(" ");
+ buf.append(f.getTypeName()).append(f.getName());
+ return buf.toString().trim();
+ }
+
+ private String stringify(char[][] arrayOfCharArrays) {
+ StringBuilder buf = new StringBuilder();
+ for (char[] charArray: arrayOfCharArrays) {
+ buf.append(charArray).append(" ");
+ }
+ return buf.toString().trim();
+ }
+
+ private String stringify(IBinaryAnnotation[] annotations) {
+ StringBuilder buf = new StringBuilder();
+ for (IBinaryAnnotation anno: annotations) {
+ buf.append(anno).append(" ");
+ }
+ return buf.toString().trim();
+ }
+
/**
* For two methods, discover if there has been a change in the exception types specified.
*
@@ -2204,8 +2549,7 @@ public class AjState implements CompilerConfigurationChangeFlags, TypeDelegateRe
ClassParser parser = new ClassParser(f.toString());
return world.buildBcelDelegate(referenceType, parser.parse(), true, false);
} catch (IOException e) {
- IMessage msg = new Message("Failed to recover " + referenceType,
- referenceType.getDelegate()==null?null:referenceType.getSourceLocation(), false);
+ IMessage msg = new Message("Failed to recover " + referenceType, referenceType.getDelegate()!=null?referenceType.getSourceLocation():null, false);
buildManager.handler.handleMessage(msg);
}
return null;
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/Checker.java b/org.aspectj.matcher/src/org/aspectj/weaver/Checker.java
index 384c5d6cd..4a765a9e5 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/Checker.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/Checker.java
@@ -222,6 +222,22 @@ public class Checker extends ShadowMunger {
return shadow.toString();
} else if (key.equalsIgnoreCase("joinpoint.kind")) {
return shadow.getKind().getName();
+ } else if (key.equalsIgnoreCase("joinpoint.enclosingclass")) {
+ return shadow.getEnclosingType().getName();
+ } else if (key.equalsIgnoreCase("joinpoint.enclosingmember.name")) {
+ Member member = shadow.getEnclosingCodeSignature();
+ if (member==null) {
+ return "";
+ } else {
+ return member.getName();
+ }
+ } else if (key.equalsIgnoreCase("joinpoint.enclosingmember")) {
+ Member member = shadow.getEnclosingCodeSignature();
+ if (member==null) {
+ return "";
+ } else {
+ return member.toString();
+ }
} else if (key.equalsIgnoreCase("joinpoint.signature")) {
return shadow.getSignature().toString();
} else if (key.equalsIgnoreCase("joinpoint.signature.declaringtype")) {
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/Lint.java b/org.aspectj.matcher/src/org/aspectj/weaver/Lint.java
index d68ce4142..36d647512 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/Lint.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/Lint.java
@@ -166,6 +166,18 @@ public class Lint {
kind.setKind(messageKind);
}
}
+
+ public void setFromMap(Map<String,String> lintOptionsMap) {
+ for (String key: lintOptionsMap.keySet()) {
+ String value = lintOptionsMap.get(key);
+ Kind kind = kinds.get(key);
+ if (kind == null) {
+ MessageUtil.error(world.getMessageHandler(), WeaverMessages.format(WeaverMessages.XLINT_KEY_ERROR, key));
+ } else {
+ kind.setKind(getMessageKind(value));
+ }
+ }
+ }
public void setFromProperties(File file) {
if (trace.isTraceEnabled()) {
diff --git a/testing/newsrc/org/aspectj/testing/CompileSpec.java b/testing/newsrc/org/aspectj/testing/CompileSpec.java
index 897e41228..6d42149ff 100644
--- a/testing/newsrc/org/aspectj/testing/CompileSpec.java
+++ b/testing/newsrc/org/aspectj/testing/CompileSpec.java
@@ -234,7 +234,8 @@ public class CompileSpec implements ITestStep {
if (getOptions() != null) {
StringTokenizer strTok = new StringTokenizer(getOptions(),",");
while (strTok.hasMoreTokens()) {
- args.append(strTok.nextToken());
+ // For an option containing a comma, pass in a { in its place
+ args.append(strTok.nextToken().replace('{', ','));
args.append(" ");
}
}
diff --git a/tests/bugs174/ajdt_markers/Code.java b/tests/bugs174/ajdt_markers/Code.java
new file mode 100644
index 000000000..b5b52c1e9
--- /dev/null
+++ b/tests/bugs174/ajdt_markers/Code.java
@@ -0,0 +1,20 @@
+public class Code extends A implements I {
+
+ public static void main(String[] argv) {
+ Code code = new Code();
+ code.am();
+ code.im();
+ }
+}
+
+class A {
+ public void am() {}
+}
+
+interface I {
+}
+
+aspect X {
+ public void I.im() {}
+ before(): call(* A+.*m(..)) {}
+}
diff --git a/tests/bugs174/extra_inserts/Code.java b/tests/bugs174/extra_inserts/Code.java
new file mode 100644
index 000000000..fa4d85990
--- /dev/null
+++ b/tests/bugs174/extra_inserts/Code.java
@@ -0,0 +1,18 @@
+public aspect Code {
+ declare warning: call(* foo(..)): "Call to foo made inside class {joinpoint.enclosingclass}";
+ declare warning: call(* foo(..)): "Call to foo made inside member {joinpoint.enclosingmember.name}";
+ declare warning: call(* foo(..)): "Call to foo made inside member {joinpoint.enclosingmember}";
+}
+class Bar {
+ public void booble() {
+ foo();
+ }
+ public void foo() {}
+}
+
+class Boo {
+ public void m() {
+ foo();
+ }
+ public void foo() {}
+}
diff --git a/tests/bugs174/pr419279/Code.java b/tests/bugs174/pr419279/Code.java
new file mode 100644
index 000000000..672d720ef
--- /dev/null
+++ b/tests/bugs174/pr419279/Code.java
@@ -0,0 +1,10 @@
+public aspect Code {
+ before(): execution(* *(String)) { }
+ before(): call(* someMethod(..)) {
+ System.out.println(thisJoinPoint);
+ }
+ public void foo() {
+ someMethod();
+ }
+ public void someMethod(){}
+}
diff --git a/tests/src/org/aspectj/systemtest/ajc174/Ajc174Tests.java b/tests/src/org/aspectj/systemtest/ajc174/Ajc174Tests.java
index 1e300dd0a..e647532fd 100644
--- a/tests/src/org/aspectj/systemtest/ajc174/Ajc174Tests.java
+++ b/tests/src/org/aspectj/systemtest/ajc174/Ajc174Tests.java
@@ -21,6 +21,20 @@ import org.aspectj.testing.XMLBasedAjcTestCase;
*/
public class Ajc174Tests extends org.aspectj.testing.XMLBasedAjcTestCase {
+/* wip
+ public void testAjdtMarkers() throws Exception {
+ runTest("ajdt markers");
+ }
+*/
+
+ public void testExtraInserts() throws Exception {
+ runTest("extra inserts");
+ }
+
+ public void testMoreConfigurableLint_419279() throws Exception {
+ runTest("more configurable lint");
+ }
+
public void testAnnotatedItd_418129() throws Exception {
runTest("annotated itd");
}
diff --git a/tests/src/org/aspectj/systemtest/ajc174/ajc174.xml b/tests/src/org/aspectj/systemtest/ajc174/ajc174.xml
index 5b47cf4d3..2ee09c456 100644
--- a/tests/src/org/aspectj/systemtest/ajc174/ajc174.xml
+++ b/tests/src/org/aspectj/systemtest/ajc174/ajc174.xml
@@ -2,6 +2,47 @@
<suite>
+ <ajc-test dir="bugs174/ajdt_markers" title="ajdt markers">
+ <compile files="Code.java" options="-1.5 -showWeaveInfo">
+ </compile>
+ </ajc-test>
+
+
+ <ajc-test dir="bugs174/extra_inserts" title="extra inserts">
+ <compile files="Code.java" options="-1.5">
+ <message kind="warning" line="8" text="Call to foo made inside class Bar"/>
+ <message kind="warning" line="15" text="Call to foo made inside class Boo"/>
+ <message kind="warning" line="8" text="Call to foo made inside member booble"/>
+ <message kind="warning" line="15" text="Call to foo made inside member m"/>
+ <message kind="warning" line="8" text="Call to foo made inside member void Bar.booble()"/>
+ <message kind="warning" line="15" text="Call to foo made inside member void Boo.m()"/>
+ </compile>
+ </ajc-test>
+
+ <ajc-test dir="bugs174/pr419279" title="more configurable lint">
+ <compile files="Code.java" options="-1.5">
+ <message kind="warning" text="advice defined in Code has not been applied [Xlint:adviceDidNotMatch]"/>
+ </compile>
+ <compile files="Code.java" options="-1.5 -Xlint:adviceDidNotMatch=ignore">
+ </compile>
+ <compile files="Code.java" options="-1.5 -Xlint:adviceDidNotMatch=error">
+ <message kind="error" text="advice defined in Code has not been applied [Xlint:adviceDidNotMatch]"/>
+ </compile>
+ <compile files="Code.java" options="-1.5 -Xlint:foo=bar">
+ <message kind="error" text="invalid Xlint key: foo"/>
+ </compile>
+ <compile files="Code.java" options="-1.5 -Xlint:adviceDidNotMatch=wibble">
+ <message kind="error" text="invalid Xlint message kind (must be one of ignore, warning, error): wibble"/>
+ </compile>
+ <compile files="Code.java" options="-1.5 -Xlint:adviceDidNotMatch=ignore{adviceDidNotMatch=error">
+ <message kind="error" text="advice defined in Code has not been applied [Xlint:adviceDidNotMatch]"/>
+ </compile>
+ <compile files="Code.java" options="-1.5 -Xlint:adviceDidNotMatch=error{noGuardForLazyTjp=error">
+ <message kind="error" text="advice defined in Code has not been applied [Xlint:adviceDidNotMatch]"/>
+ <message kind="error" text="can not build thisJoinPoint lazily for this advice since it has no suitable guard [Xlint:noGuardForLazyTjp]"/>
+ </compile>
+ </ajc-test>
+
<ajc-test dir="bugs174/pr418129" title="annotated itd">
<compile files="Target.java" options="-1.5 -showWeaveInfo">
<message kind="weave" text="Type 'Behavior' (Target.java) has intertyped method from 'Trait' (Target.java:'java.lang.String Behavior.hello()')"/>