@@ -71,18 +71,17 @@ public class AsmManager { | |||
// } | |||
protected AsmManager() { | |||
hierarchy = new AspectJElementHierarchy(); | |||
// List relationships = new ArrayList(); | |||
mapper = new RelationshipMap(hierarchy); | |||
handleProvider = new OptimizedFullPathHandleProvider(); | |||
handleProvider = new OptimizedFullPathHandleProvider(); | |||
createNewASM(); | |||
} | |||
public void createNewASM() { | |||
hierarchy = new AspectJElementHierarchy(); | |||
mapper = new RelationshipMap(hierarchy); | |||
// call initialize on the handleProvider when we create a new ASM | |||
// to give handleProviders the chance to reset any state | |||
handleProvider.initialize(); | |||
} | |||
public IHierarchy getHierarchy() { | |||
return hierarchy; | |||
@@ -490,10 +489,6 @@ public class AsmManager { | |||
//===================== DELTA PROCESSING CODE ============== start ==========// | |||
private String getFilename(String hid) { | |||
return getHandleProvider().getFileForHandle(hid); | |||
} | |||
/** | |||
* Removes the hierarchy structure for the specified files from the structure model. | |||
* Returns true if it deleted anything | |||
@@ -515,7 +510,7 @@ public class AsmManager { | |||
fw.write("Deleting "+progElem+" node for file "+fileForCompilation+"\n"); | |||
} | |||
removeNode(progElem); | |||
deletedNodes.add(getFilename(progElem.getHandleIdentifier())); | |||
deletedNodes.add(getCanonicalFilePath(progElem.getSourceLocation().getSourceFile())); | |||
if (!model.removeFromFileMap(correctedPath.toString())) | |||
throw new RuntimeException("Whilst repairing model, couldn't remove entry for file: "+correctedPath.toString()+" from the filemap"); | |||
modelModified = true; | |||
@@ -557,7 +552,7 @@ public class AsmManager { | |||
fw.write("Deleting "+progElem+" node for file "+fileForCompilation+"\n"); | |||
} | |||
removeNode(progElem); | |||
deletedNodes.add(getFilename(progElem.getHandleIdentifier())); | |||
deletedNodes.add(getCanonicalFilePath(progElem.getSourceLocation().getSourceFile())); | |||
if (!model.removeFromFileMap(correctedPath.toString())) | |||
throw new RuntimeException("Whilst repairing model, couldn't remove entry for file: "+correctedPath.toString()+" from the filemap"); | |||
modelModified = true; |
@@ -60,4 +60,18 @@ public interface IElementHandleProvider { | |||
public int getOffSetForHandle(String handle); | |||
// See pr134471 | |||
/** | |||
* @return true if the handles produced by the provider | |||
* depend on ISourceLocations and false otherwise | |||
*/ | |||
public boolean dependsOnLocation(); | |||
/** | |||
* Initializes handle provider state. | |||
* | |||
* The initializer is invoked when a new ASM is | |||
* created on a full build. | |||
*/ | |||
public void initialize(); | |||
} |
@@ -406,7 +406,8 @@ public class AspectJElementHierarchy implements IHierarchy { | |||
Set k = handleMap.keySet(); | |||
for (Iterator iter = k.iterator(); iter.hasNext();) { | |||
String handle = (String) iter.next(); | |||
if (deletedFiles.contains(getFilename(handle))) forRemoval.add(handle); | |||
IProgramElement ipe = (IProgramElement)handleMap.get(handle); | |||
if (deletedFiles.contains(getCanonicalFilePath(ipe)))forRemoval.add(handle); | |||
} | |||
for (Iterator iter = forRemoval.iterator(); iter.hasNext();) { | |||
String handle = (String) iter.next(); | |||
@@ -415,31 +416,37 @@ public class AspectJElementHierarchy implements IHierarchy { | |||
forRemoval.clear(); | |||
k = typeMap.keySet(); | |||
for (Iterator iter = k.iterator(); iter.hasNext();) { | |||
String element = (String) iter.next(); | |||
IProgramElement ipe = (IProgramElement)typeMap.get(element); | |||
if (deletedFiles.contains(getFilename(ipe.getHandleIdentifier()))) forRemoval.add(element); | |||
String typeName = (String) iter.next(); | |||
IProgramElement ipe = (IProgramElement)typeMap.get(typeName); | |||
if (deletedFiles.contains(getCanonicalFilePath(ipe))) forRemoval.add(typeName); | |||
} | |||
for (Iterator iter = forRemoval.iterator(); iter.hasNext();) { | |||
String handle = (String) iter.next(); | |||
typeMap.remove(handle); | |||
String typeName = (String) iter.next(); | |||
typeMap.remove(typeName); | |||
} | |||
forRemoval.clear(); | |||
k = fileMap.keySet(); | |||
for (Iterator iter = k.iterator(); iter.hasNext();) { | |||
String element = (String) iter.next(); | |||
IProgramElement ipe = (IProgramElement)fileMap.get(element); | |||
if (deletedFiles.contains(getFilename(ipe.getHandleIdentifier()))) forRemoval.add(element); | |||
String filePath = (String) iter.next(); | |||
IProgramElement ipe = (IProgramElement)fileMap.get(filePath); | |||
if (deletedFiles.contains(getCanonicalFilePath(ipe))) forRemoval.add(filePath); | |||
} | |||
for (Iterator iter = forRemoval.iterator(); iter.hasNext();) { | |||
String handle = (String) iter.next(); | |||
fileMap.remove(handle); | |||
String filePath = (String) iter.next(); | |||
fileMap.remove(filePath); | |||
} | |||
} | |||
private String getFilename(String hid) { | |||
return AsmManager.getDefault().getHandleProvider().getFileForHandle(hid); | |||
} | |||
private String getCanonicalFilePath(IProgramElement ipe) { | |||
if (ipe.getSourceLocation() != null) { | |||
return AsmManager.getDefault().getCanonicalFilePath(ipe.getSourceLocation().getSourceFile()); | |||
} | |||
return ""; | |||
} | |||
} | |||
@@ -0,0 +1,213 @@ | |||
/******************************************************************** | |||
* Copyright (c) 2006 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: IBM Corporation - initial API and implementation | |||
* Helen Hawkins - initial version | |||
*******************************************************************/ | |||
package org.aspectj.asm.internal; | |||
import java.io.File; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import org.aspectj.asm.AsmManager; | |||
import org.aspectj.asm.IElementHandleProvider; | |||
import org.aspectj.asm.IProgramElement; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.util.CharOperation; | |||
import org.aspectj.util.NameConvertor; | |||
/** | |||
* Creates JDT-like handles, for example | |||
* | |||
* method with string argument: <tjp{Demo.java[Demo~main~\[QString; | |||
* method with generic argument: <pkg{MyClass.java[MyClass~myMethod~QList\<QString;>; | |||
* an aspect: <pkg*A1.aj}A1 | |||
* advice with Integer arg: <pkg*A8.aj}A8&afterReturning&QInteger; | |||
* method call: <pkg*A10.aj[C~m1?method-call(void pkg.C.m2()) | |||
* | |||
*/ | |||
public class JDTLikeHandleProvider implements IElementHandleProvider { | |||
// Need to keep our own count of the number of initializers | |||
// because this information cannot be gained from the ipe. | |||
private int initializerCounter = 0; | |||
private char[] empty = new char[]{}; | |||
private char[] countDelim = new char[]{HandleProviderDelimiter.COUNT.getDelimiter()}; | |||
private String backslash = "\\"; | |||
private String emptyString = ""; | |||
public String createHandleIdentifier(IProgramElement ipe) { | |||
// AjBuildManager.setupModel --> top of the tree is either | |||
// <root> or the .lst file | |||
if (ipe == null || | |||
(ipe.getKind().equals(IProgramElement.Kind.FILE_JAVA) | |||
&& ipe.getName().equals("<root>"))) { | |||
return ""; | |||
} else if (ipe.getHandleIdentifier(false) != null) { | |||
// have already created the handle for this ipe | |||
// therefore just return it | |||
return ipe.getHandleIdentifier(); | |||
} else if (ipe.getKind().equals(IProgramElement.Kind.FILE_LST)) { | |||
String configFile = AsmManager.getDefault().getHierarchy().getConfigFile(); | |||
int start = configFile.lastIndexOf(File.separator); | |||
int end = configFile.lastIndexOf(".lst"); | |||
String fileName = configFile.substring(start + 1,end); | |||
ipe.setHandleIdentifier(fileName); | |||
return fileName; | |||
} | |||
IProgramElement parent = ipe.getParent(); | |||
if (parent != null && | |||
parent.getKind().equals(IProgramElement.Kind.IMPORT_REFERENCE)) { | |||
// want to miss out '#import declaration' in the handle | |||
parent = ipe.getParent().getParent(); | |||
} | |||
StringBuffer handle = new StringBuffer(); | |||
// add the handle for the parent | |||
handle.append(createHandleIdentifier(parent)); | |||
// add the correct delimiter for this ipe | |||
handle.append(HandleProviderDelimiter.getDelimiter(ipe)); | |||
// add the name and any parameters unless we're an initializer | |||
// (initializer's names are '...') | |||
if (!ipe.getKind().equals(IProgramElement.Kind.INITIALIZER)) { | |||
handle.append(ipe.getName() + getParameters(ipe)); | |||
} | |||
// add the count, for example '!2' if its the second ipe of its | |||
// kind in the aspect | |||
handle.append(getCount(ipe)); | |||
ipe.setHandleIdentifier(handle.toString()); | |||
return handle.toString(); | |||
} | |||
private String getParameters(IProgramElement ipe) { | |||
if (ipe.getParameterSignatures() == null || ipe.getParameterSignatures().isEmpty()) return ""; | |||
StringBuffer sb = new StringBuffer(); | |||
List parameterTypes = ipe.getParameterSignatures(); | |||
for (Iterator iter = parameterTypes.iterator(); iter.hasNext();) { | |||
char[] element = (char[]) iter.next(); | |||
sb.append(HandleProviderDelimiter.getDelimiter(ipe)); | |||
if (element[0] == HandleProviderDelimiter.TYPE.getDelimiter()) { | |||
// its an array | |||
sb.append(HandleProviderDelimiter.ESCAPE.getDelimiter()); | |||
sb.append(HandleProviderDelimiter.TYPE.getDelimiter()); | |||
sb.append(NameConvertor.getTypeName( | |||
CharOperation.subarray(element,1,element.length))); | |||
} else if (element[0] == NameConvertor.PARAMETERIZED) { | |||
// its a parameterized type | |||
sb.append(NameConvertor.createShortName(element)); | |||
} else { | |||
sb.append(NameConvertor.getTypeName(element)); | |||
} | |||
} | |||
return sb.toString(); | |||
} | |||
private char[] getCount(IProgramElement ipe) { | |||
char[] byteCodeName = ipe.getBytecodeName().toCharArray(); | |||
if (ipe.getKind().isDeclare()) { | |||
int index = CharOperation.lastIndexOf('_',byteCodeName); | |||
if (index != -1) { | |||
return convertCount(CharOperation.subarray(byteCodeName, | |||
index+1,byteCodeName.length)); | |||
} | |||
} else if (ipe.getKind().equals(IProgramElement.Kind.ADVICE)) { | |||
int lastDollar = CharOperation.lastIndexOf('$',byteCodeName); | |||
if (lastDollar != -1) { | |||
char[] upToDollar = CharOperation.subarray(byteCodeName,0,lastDollar); | |||
int secondToLastDollar = CharOperation.lastIndexOf('$',upToDollar); | |||
if (secondToLastDollar != -1) { | |||
return convertCount(CharOperation.subarray(upToDollar, | |||
secondToLastDollar+1,upToDollar.length)); | |||
} | |||
} | |||
} else if (ipe.getKind().equals(IProgramElement.Kind.INITIALIZER)) { | |||
return String.valueOf(++initializerCounter).toCharArray(); | |||
} | |||
return empty; | |||
} | |||
/** | |||
* Only returns the count if it's not equal to 1 | |||
*/ | |||
private char[] convertCount(char[] c) { | |||
if ((c.length == 1 && c[0] != ' ' && c[0] != '1') || c.length > 1) { | |||
return CharOperation.concat(countDelim,c); | |||
} | |||
return empty; | |||
} | |||
public String getFileForHandle(String handle) { | |||
IProgramElement node = AsmManager.getDefault().getHierarchy().getElement(handle); | |||
if (node != null) { | |||
return AsmManager.getDefault().getCanonicalFilePath(node.getSourceLocation().getSourceFile()); | |||
} else if (handle.charAt(0) == HandleProviderDelimiter.ASPECT_CU.getDelimiter() | |||
|| handle.charAt(0) == HandleProviderDelimiter.COMPILATIONUNIT.getDelimiter()) { | |||
// it's something like *MyAspect.aj or {MyClass.java. In other words | |||
// it's a file node that's been created with no children and no parent | |||
return backslash + handle.substring(1); | |||
} | |||
return emptyString; | |||
} | |||
public int getLineNumberForHandle(String handle) { | |||
IProgramElement node = AsmManager.getDefault().getHierarchy().getElement(handle); | |||
if (node != null) { | |||
return node.getSourceLocation().getLine(); | |||
} else if (handle.charAt(0) == HandleProviderDelimiter.ASPECT_CU.getDelimiter() | |||
|| handle.charAt(0) == HandleProviderDelimiter.COMPILATIONUNIT.getDelimiter()) { | |||
// it's something like *MyAspect.aj or {MyClass.java. In other words | |||
// it's a file node that's been created with no children and no parent | |||
return 1; | |||
} | |||
return -1; | |||
} | |||
public int getOffSetForHandle(String handle) { | |||
IProgramElement node = AsmManager.getDefault().getHierarchy().getElement(handle); | |||
if (node != null) { | |||
return node.getSourceLocation().getOffset(); | |||
} else if (handle.charAt(0) == HandleProviderDelimiter.ASPECT_CU.getDelimiter() | |||
|| handle.charAt(0) == HandleProviderDelimiter.COMPILATIONUNIT.getDelimiter()) { | |||
// it's something like *MyAspect.aj or {MyClass.java. In other words | |||
// it's a file node that's been created with no children and no parent | |||
return 0; | |||
} | |||
return -1; | |||
} | |||
public String createHandleIdentifier(ISourceLocation location) { | |||
IProgramElement node = AsmManager.getDefault().getHierarchy().findElementForSourceLine(location); | |||
if (node != null) { | |||
return createHandleIdentifier(node); | |||
} | |||
return null; | |||
} | |||
public String createHandleIdentifier(File sourceFile, int line, int column, int offset) { | |||
IProgramElement node = AsmManager.getDefault().getHierarchy().findElementForOffSet(sourceFile.getAbsolutePath(),line,offset); | |||
if (node != null) { | |||
return createHandleIdentifier(node); | |||
} | |||
return null; | |||
} | |||
public boolean dependsOnLocation() { | |||
// handles are independent of soureLocations therefore return false | |||
return false; | |||
} | |||
public void initialize() { | |||
// reset the initializer count. This ensures we return the | |||
// same handle as JDT for initializers. | |||
initializerCounter = 0; | |||
} | |||
} |
@@ -330,7 +330,8 @@ public class AnnotationBinding extends XMLBasedAjcTestCase { | |||
Relationship rel = (Relationship)l.get(0); | |||
assertTrue("Should have 1 target but has "+rel.getTargets().size(),rel.getTargets().size()==1); | |||
String tgt = (String)rel.getTargets().get(0); | |||
assertTrue("Should point to line 10 but doesnt: "+tgt,tgt.indexOf("|10|")!=-1); | |||
int lineNumber = AsmManager.getDefault().getHandleProvider().getLineNumberForHandle(tgt); | |||
assertTrue("Should point to line 10 but doesnt: "+lineNumber,lineNumber == 10); | |||
} | |||
} | |||
@@ -360,7 +361,9 @@ public class AnnotationBinding extends XMLBasedAjcTestCase { | |||
Relationship rel = (Relationship)l.get(0); | |||
assertTrue("Should have 1 target but has "+rel.getTargets().size(),rel.getTargets().size()==1); | |||
String tgt = (String)rel.getTargets().get(0); | |||
assertTrue("Should point to line 10 but doesnt: "+tgt,tgt.indexOf("|10|")!=-1); | |||
int lineNumber = AsmManager.getDefault().getHandleProvider().getLineNumberForHandle(tgt); | |||
assertTrue("Should point to line 10 but doesnt: "+lineNumber,lineNumber == 10); | |||
} | |||
} | |||
@@ -390,7 +393,9 @@ public class AnnotationBinding extends XMLBasedAjcTestCase { | |||
Relationship rel = (Relationship)l.get(0); | |||
assertTrue("Should have 1 target but has "+rel.getTargets().size(),rel.getTargets().size()==1); | |||
String tgt = (String)rel.getTargets().get(0); | |||
assertTrue("Should point to line 10 but doesnt: "+tgt,tgt.indexOf("|10|")!=-1); | |||
int lineNumber = AsmManager.getDefault().getHandleProvider().getLineNumberForHandle(tgt); | |||
assertTrue("Should point to line 10 but doesnt: "+lineNumber,lineNumber == 10); | |||
} | |||
} | |||
@@ -19,6 +19,7 @@ public class AllTestsAspectJ153 { | |||
TestSuite suite = new TestSuite("AspectJ 1.5.3 tests"); | |||
//$JUnit-BEGIN$ | |||
suite.addTest(Ajc153Tests.suite()); | |||
suite.addTest(JDTLikeHandleProviderTests.suite()); | |||
//$JUnit-END$ | |||
return suite; | |||
} |
@@ -0,0 +1,506 @@ | |||
/******************************************************************** | |||
* Copyright (c) 2006 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: IBM Corporation - initial API and implementation | |||
* Helen Hawkins - initial version | |||
*******************************************************************/ | |||
package org.aspectj.systemtest.ajc153; | |||
import java.io.File; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import junit.framework.Test; | |||
import org.aspectj.asm.AsmManager; | |||
import org.aspectj.asm.IElementHandleProvider; | |||
import org.aspectj.asm.IHierarchy; | |||
import org.aspectj.asm.IProgramElement; | |||
import org.aspectj.asm.internal.JDTLikeHandleProvider; | |||
import org.aspectj.testing.XMLBasedAjcTestCase; | |||
public class JDTLikeHandleProviderTests extends XMLBasedAjcTestCase { | |||
IElementHandleProvider handleProvider; | |||
protected void setUp() throws Exception { | |||
super.setUp(); | |||
handleProvider = AsmManager.getDefault().getHandleProvider(); | |||
AsmManager.getDefault().setHandleProvider(new JDTLikeHandleProvider()); | |||
} | |||
protected void tearDown() throws Exception { | |||
super.tearDown(); | |||
AsmManager.getDefault().setHandleProvider(handleProvider); | |||
} | |||
public void testMoreThanOneNamedPointcut() { | |||
runTest("More than one named pointcut"); | |||
} | |||
public void testAspectHandle() { | |||
runTest("aspect handle"); | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement pe = top.findElementForType("pkg", "A1"); | |||
String expected = "<pkg*A1.aj}A1"; | |||
String found = pe.getHandleIdentifier(); | |||
assertEquals("handleIdentifier - expected " + expected + ", but found " | |||
+ found, expected, found); | |||
} | |||
public void testAdviceHandle() { | |||
runTest("advice handle"); | |||
compareHandles(IProgramElement.Kind.ADVICE, | |||
"before(): <anonymous pointcut>", | |||
"<pkg*A2.aj}A2&before"); | |||
} | |||
public void testPointcutHandle() { | |||
runTest("pointcut handle"); | |||
compareHandles(IProgramElement.Kind.POINTCUT, | |||
"p()", | |||
"<pkg*A4.aj}A4+p"); | |||
} | |||
public void testGetIPEWithAspectHandle() { | |||
runTest("get IProgramElement with aspect handle"); | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
String handle = "<pkg*A1.aj}A1"; | |||
IProgramElement ipe = top.getElement(handle); | |||
assertNotNull("should have found ipe with handle " + handle, ipe); | |||
IProgramElement ipe2 = top.getElement(handle); | |||
assertEquals("should be the same IPE",ipe,ipe2); | |||
} | |||
public void testAdviceHandleWithCrossCutting() { | |||
runTest("advice handle with crosscutting"); | |||
compareHandles(IProgramElement.Kind.ADVICE, | |||
"before(): <anonymous pointcut>", | |||
"<pkg*A3.aj}A3&before"); | |||
} | |||
public void testPointcutHandleWithArgs() { | |||
runTest("pointcut handle with args"); | |||
compareHandles(IProgramElement.Kind.POINTCUT, | |||
"p(java.lang.Integer)", | |||
"*A6.aj}A6+p+QInteger;"); | |||
} | |||
public void testAdviceHandleWithArgs() { | |||
runTest("advice handle with args"); | |||
compareHandles(IProgramElement.Kind.ADVICE, | |||
"afterReturning(java.lang.Integer): p..", | |||
"<pkg*A8.aj}A8&afterReturning&QInteger;"); | |||
} | |||
public void testFieldITD() { | |||
runTest("field itd handle"); | |||
compareHandles(IProgramElement.Kind.INTER_TYPE_FIELD, | |||
"C.x", | |||
"<pkg*A9.aj}A9)C.x"); | |||
} | |||
public void testMethodITD() { | |||
runTest("method itd handle"); | |||
compareHandles(IProgramElement.Kind.INTER_TYPE_METHOD, | |||
"C.method()", | |||
"<pkg*A9.aj}A9)C.method"); | |||
} | |||
public void testMethodITDWithArgs() { | |||
runTest("method itd with args handle"); | |||
compareHandles(IProgramElement.Kind.INTER_TYPE_METHOD, | |||
"C.methodWithArgs(int)", | |||
"<pkg*A9.aj}A9)C.methodWithArgs)I"); | |||
} | |||
public void testConstructorITDWithArgs() { | |||
runTest("constructor itd with args"); | |||
compareHandles(IProgramElement.Kind.INTER_TYPE_CONSTRUCTOR, | |||
"C.C(int,java.lang.String)", | |||
"<pkg*A13.aj}A13)C.C)I)QString;"); | |||
} | |||
public void testDeclareParentsHandle() { | |||
runTest("declare parents handle"); | |||
compareHandles(IProgramElement.Kind.DECLARE_PARENTS, | |||
"declare parents: implements C2", | |||
"<pkg*A7.aj}A7`declare parents"); | |||
} | |||
public void testTwoDeclareParents() { | |||
runTest("two declare parents in same file"); | |||
compareHandles(IProgramElement.Kind.DECLARE_PARENTS, | |||
"declare parents: extends C5", | |||
"<pkg*A7.aj}A7`declare parents!2"); | |||
} | |||
public void testMethodCallHandle() { | |||
runTest("method call handle"); | |||
compareHandles(IProgramElement.Kind.CODE, | |||
"method-call(void pkg.C.m2())", | |||
"<pkg*A10.aj[C~m1?method-call(void pkg.C.m2())"); | |||
} | |||
public void testDeclareAtType() { | |||
// AJDT: =AJHandleProject/src<pkg*A.aj}A`declare \@type | |||
runTest("declare @type"); | |||
compareHandles(IProgramElement.Kind.DECLARE_ANNOTATION_AT_TYPE, | |||
"declare @type: pkg.C : @MyAnnotation", | |||
"<pkg*A12.aj}A`declare @type"); | |||
} | |||
public void testDeclareAtField() { | |||
// AJDT: =AJHandleProject/src<pkg*A.aj}A`declare \@field | |||
runTest("declare @field"); | |||
compareHandles(IProgramElement.Kind.DECLARE_ANNOTATION_AT_FIELD, | |||
"declare @field: int pkg.C.someField : @MyAnnotation", | |||
"<pkg*A12.aj}A`declare @field!2"); | |||
} | |||
public void testDeclareAtMethod() { | |||
// AJDT: =AJHandleProject/src<pkg*A.aj}A`declare \@method | |||
runTest("declare @method"); | |||
compareHandles(IProgramElement.Kind.DECLARE_ANNOTATION_AT_METHOD, | |||
"declare @method: public void pkg.C.method1() : @MyAnnotation", | |||
"<pkg*A12.aj}A`declare @method!3"); | |||
} | |||
public void testDeclareAtConstructor() { | |||
// AJDT: =AJHandleProject/src<pkg*A.aj}A`declare \@constructor | |||
runTest("declare @constructor"); | |||
compareHandles(IProgramElement.Kind.DECLARE_ANNOTATION_AT_CONSTRUCTOR, | |||
"declare @constructor: pkg.C.new() : @MyAnnotation", | |||
"<pkg*A12.aj}A`declare @constructor!4"); | |||
} | |||
// what about 2 pieces of before advice with the same | |||
// signature and the same pointcut | |||
public void testTwoPiecesOfAdviceWithSameSignatureAndPointcut() { | |||
runTest("two pieces of advice with the same signature and pointcut"); | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement parent = top.findElementForLabel(top.getRoot(), | |||
IProgramElement.Kind.ASPECT, "A5"); | |||
List children = parent.getChildren(); | |||
String handle1 = null; | |||
String handle2 = null; | |||
for (Iterator iter = children.iterator(); iter.hasNext();) { | |||
IProgramElement element = (IProgramElement) iter.next(); | |||
if (element.getKind().equals(IProgramElement.Kind.ADVICE)) { | |||
if (handle1 == null) { | |||
handle1 = element.getHandleIdentifier(); | |||
} else { | |||
handle2 = element.getHandleIdentifier(); | |||
} | |||
} | |||
} | |||
String expected1 = "<pkg*A5.aj}A5&before"; | |||
String expected2 = "<pkg*A5.aj}A5&before!2"; | |||
boolean b = expected1.equals(handle1); | |||
if (b) { | |||
assertEquals("handleIdentifier - expected " + expected2 + ", but found " | |||
+ handle2, expected2, handle2); | |||
} else { | |||
assertEquals("handleIdentifier - expected " + expected1 + ", but found " | |||
+ handle2, expected1, handle2); | |||
assertEquals("handleIdentifier - expected " + expected2 + ", but found " | |||
+ handle1, expected2, handle1); | |||
} | |||
} | |||
public void testDeclareWarningHandle() { | |||
runTest("declare warning handle"); | |||
compareHandles(IProgramElement.Kind.DECLARE_WARNING, | |||
"declare warning: \"Illegal call.\"", | |||
"<pkg*A11.aj}A11`declare warning"); | |||
} | |||
public void testTwoDeclareWarningHandles() { | |||
runTest("two declare warning handles"); | |||
compareHandles(IProgramElement.Kind.DECLARE_WARNING, | |||
"declare warning: \"blah\"", | |||
"<pkg*A11.aj}A11`declare warning!2"); | |||
} | |||
// this is to ensure the logic for not including '1' in the count | |||
// works correctly. We don't want a decw ipe with count 1 but we do | |||
// want one with count 10. | |||
public void testTenDeclareWarningHandles() { | |||
runTest("ten declare warning handles"); | |||
compareHandles(IProgramElement.Kind.DECLARE_WARNING, | |||
"declare warning: \"warning 1\"", | |||
"*DeclareWarnings.aj}DeclareWarnings`declare warning"); | |||
compareHandles(IProgramElement.Kind.DECLARE_WARNING, | |||
"declare warning: \"warning 10\"", | |||
"*DeclareWarnings.aj}DeclareWarnings`declare warning!10"); | |||
} | |||
//---------- following tests ensure we produce the same handles as jdt -----// | |||
//---------- (apart from the prefix) | |||
// NOTES: there is no ipe equivalent to a package fragment root or | |||
// | |||
public void testCompilationUnitSameAsJDT() { | |||
// JDT: =TJP Example/src<tjp{Demo.java | |||
runTest("compilation unit same as jdt"); | |||
compareHandles(IProgramElement.Kind.FILE_JAVA, | |||
"Demo.java", | |||
"<tjp{Demo.java"); | |||
} | |||
public void testClassSameAsJDT() { | |||
// JDT: =Java5 Handles/src<pkg{C.java[C | |||
runTest("class same as jdt"); | |||
compareHandles(IProgramElement.Kind.CLASS, | |||
"C","<pkg{C.java[C"); | |||
} | |||
public void testInterfaceSameAsJDT() { | |||
// JDT: =Java5 Handles/src<pkg{C.java[MyInterface | |||
runTest("interface same as jdt"); | |||
compareHandles(IProgramElement.Kind.INTERFACE, | |||
"MyInterface","<pkg{C.java[MyInterface"); | |||
} | |||
public void testConstructorSameAsJDT() { | |||
// JDT: =Java5 Handles/src<pkg{C.java[C~C | |||
runTest("constructor same as jdt"); | |||
compareHandles(IProgramElement.Kind.CONSTRUCTOR, | |||
"C()","<pkg{C.java[C~C"); | |||
} | |||
public void testConstructorWithArgsSameAsJDT() { | |||
// JDT: =Java5 Handles/src<pkg{C.java[C~C~QString; | |||
runTest("constructor with args same as jdt"); | |||
compareHandles(IProgramElement.Kind.CONSTRUCTOR, | |||
"C(java.lang.String)","<pkg{C.java[C~C~QString;"); | |||
} | |||
// public void testPackageDeclarationSameAsJDT() { | |||
// // JDT: =TJP Example/src<tjp{Demo.java%tjp | |||
// fail("package declaration isn't the same"); | |||
// runTest("package declaration same as jdt"); | |||
// compareHandles(IProgramElement.Kind.PACKAGE, | |||
// "tjp", | |||
// "<tjp{Demo.java%tjp"); | |||
// } | |||
public void testImportDeclarationSameAsJDT() { | |||
// JDT: =TJP Example/src<tjp{Demo.java#java.io.* | |||
runTest("import declaration same as jdt"); | |||
compareHandles(IProgramElement.Kind.IMPORT_REFERENCE, | |||
"java.io.*", | |||
"<tjp{Demo.java#java.io.*"); | |||
} | |||
public void testTypeSameAsJDT() { | |||
// JDT: =TJP Example/src<tjp{Demo.java[Demo | |||
runTest("type same as jdt"); | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement pe = top.findElementForType("tjp", "Demo"); | |||
String expected = "<tjp{Demo.java[Demo"; | |||
String found = pe.getHandleIdentifier(); | |||
assertEquals("handleIdentifier - expected " + expected + ", but found " | |||
+ found, expected, found); | |||
} | |||
public void testFieldSameAsJDT() { | |||
// JDT: =TJP Example/src<tjp{Demo.java[Demo^d | |||
runTest("field same as jdt"); | |||
compareHandles(IProgramElement.Kind.FIELD, | |||
"d", | |||
"<tjp{Demo.java[Demo^d"); | |||
} | |||
public void testInitializationSameAsJDT() { | |||
// JDT: =TJP Example/src<tjp{Demo.java[Demo|1 | |||
// and =TJP Example/src<tjp{Demo.java[Demo|2 | |||
runTest("initialization same as jdt"); | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement parent = top.findElementForLabel(top.getRoot(), | |||
IProgramElement.Kind.CLASS, "Demo"); | |||
List children = parent.getChildren(); | |||
String handle1 = null; | |||
String handle2 = null; | |||
for (Iterator iter = children.iterator(); iter.hasNext();) { | |||
IProgramElement element = (IProgramElement) iter.next(); | |||
if (element.getKind().equals(IProgramElement.Kind.INITIALIZER)) { | |||
if (handle1 == null) { | |||
handle1 = element.getHandleIdentifier(); | |||
} else { | |||
handle2 = element.getHandleIdentifier(); | |||
} | |||
} | |||
} | |||
String expected1 = "<tjp{Demo.java[Demo|1"; | |||
String expected2 = "<tjp{Demo.java[Demo|2"; | |||
boolean b = expected1.equals(handle1); | |||
System.err.println("actual: " + handle1); | |||
System.err.println("actual: " + handle2); | |||
if (b) { | |||
assertEquals("handleIdentifier - expected " + expected2 + ", but found " | |||
+ handle2, expected2, handle2); | |||
} else { | |||
assertEquals("handleIdentifier - expected " + expected1 + ", but found " | |||
+ handle2, expected1, handle2); | |||
assertEquals("handleIdentifier - expected " + expected2 + ", but found " | |||
+ handle1, expected2, handle1); | |||
} | |||
} | |||
public void testMethodWithStringArrayArgsSameAsJDT() { | |||
// JDT: =TJP Example/src<tjp{Demo.java[Demo~main~\[QString; | |||
runTest("method with string array as argument same as jdt"); | |||
compareHandles(IProgramElement.Kind.METHOD, | |||
"main(java.lang.String[])", | |||
"<tjp{Demo.java[Demo~main~\\[QString;"); | |||
} | |||
public void testMethodWithIntArrayArgsSameAsJDT() { | |||
// JDT: =TJP Example/src<tjp{Demo.java[Demo~m~\[I | |||
runTest("method with int array as argument same as jdt"); | |||
compareHandles(IProgramElement.Kind.METHOD, | |||
"m(int[])", | |||
"<tjp{Demo.java[Demo~m~\\[I"); | |||
} | |||
public void testMethodWithNoArgsSameAsJDT() { | |||
// JDT: =TJP Example/src<tjp{Demo.java[Demo~go | |||
runTest("method with no args same as jdt"); | |||
compareHandles(IProgramElement.Kind.METHOD, | |||
"go()", | |||
"<tjp{Demo.java[Demo~go"); | |||
} | |||
public void testMethodWithTwoArgsSameAsJDT() { | |||
// JDT: =TJP Example/src<tjp{Demo.java[Demo~foo~I~QObject; | |||
runTest("method with two args same as jdt"); | |||
compareHandles(IProgramElement.Kind.METHOD, | |||
"foo(int,java.lang.Object)", | |||
"<tjp{Demo.java[Demo~foo~I~QObject;"); | |||
} | |||
public void testMethodWithTwoStringArgsSameAsJDT() { | |||
// JDT: =TJP Example/src<tjp{Demo.java[Demo~m2~QString;~QString; | |||
runTest("method with two string args same as jdt"); | |||
compareHandles(IProgramElement.Kind.METHOD, | |||
"m2(java.lang.String,java.lang.String)", | |||
"<tjp{Demo.java[Demo~m2~QString;~QString;"); | |||
} | |||
public void testEnumSameAsJDT() { | |||
// JDT: =Java5 Handles/src<pkg{E.java[E | |||
runTest("enum same as jdt"); | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement pe = top.findElementForType("pkg", "E"); | |||
String expected = "<pkg{E.java[E"; | |||
String found = pe.getHandleIdentifier(); | |||
assertEquals("handleIdentifier - expected " + expected + ", but found " | |||
+ found, expected, found); | |||
} | |||
public void testEnumValueSameAsJDT() { | |||
// JDT: =Java5 Handles/src<pkg{E.java[E^A | |||
runTest("enum value same as jdt"); | |||
compareHandles(IProgramElement.Kind.ENUM_VALUE, | |||
"A","<pkg{E.java[E^A"); | |||
} | |||
public void testAnnotationSameAsJDT() { | |||
// JDT: =Java5 Handles/src<pkg{MyAnnotation.java[MyAnnotation | |||
runTest("annotation same as jdt"); | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement pe = top.findElementForType("pkg", "MyAnnotation"); | |||
String expected = "<pkg{MyAnnotation.java[MyAnnotation"; | |||
String found = pe.getHandleIdentifier(); | |||
assertEquals("handleIdentifier - expected " + expected + ", but found " | |||
+ found, expected, found); | |||
} | |||
public void testMethodWithListArgSameAsJDT() { | |||
// JDT: =Java5 Handles/src<pkg{Java5Class.java[Java5Class~method2~QList; | |||
runTest("method with list arg same as jdt"); | |||
compareHandles(IProgramElement.Kind.METHOD, | |||
"method2(java.util.List)", | |||
"<pkg{Java5Class.java[Java5Class~method2~QList;"); | |||
} | |||
public void testMethodWithGenericArgSameAsJDT() { | |||
// JDT: =Java5 Handles/src<pkg{Java5Class.java[Java5Class | |||
// ~genericMethod1~QList\<QString;>; | |||
runTest("method with generic arg same as jdt"); | |||
compareHandles(IProgramElement.Kind.METHOD, | |||
"genericMethod1(java.util.List<java.lang.String>)", | |||
"<pkg{Java5Class.java[Java5Class~genericMethod1~QList\\<QString;>;"); | |||
} | |||
public void testMethodWithTwoGenericArgsSameAsJDT() { | |||
// JDT: =Java5 Handles/src<pkg{Java5Class.java[Java5Class | |||
// ~genericMethod2~QList\<QString;>;~QMyGenericClass\<QInteger;>; | |||
runTest("method with two generic args same as jdt"); | |||
compareHandles(IProgramElement.Kind.METHOD, | |||
"genericMethod2(java.util.List<java.lang.String>," | |||
+"pkg.MyGenericClass<java.lang.Integer>)", | |||
"<pkg{Java5Class.java[Java5Class~genericMethod2~QList" | |||
+"\\<QString;>;~QMyGenericClass\\<QInteger;>;"); | |||
} | |||
public void testMethodWithTwoTypeParametersSameAsJDT() { | |||
// JDT: =Java5 Handles/src<pkg{Java5Class.java[Java5Class~genericMethod4 | |||
// ~QMyGenericClass2\<QString;QInteger;>; | |||
runTest("method with two type parameters same as jdt"); | |||
compareHandles(IProgramElement.Kind.METHOD, | |||
"genericMethod4(pkg.MyGenericClass2<java.lang.String,java.lang.Integer>)", | |||
"<pkg{Java5Class.java[Java5Class~genericMethod4" + | |||
"~QMyGenericClass2\\<QString;QInteger;>;"); | |||
} | |||
public void testMethodWithTwoArgsSameAsJDT_2() { | |||
// JDT: =Java5 Handles/src<pkg{Java5Class.java[Java5Class | |||
// ~genericMethod3~I~QList\<QString;>; | |||
runTest("method with two args one of which is generic same as jdt"); | |||
compareHandles(IProgramElement.Kind.METHOD, | |||
"genericMethod3(int,java.util.List<java.lang.String>)", | |||
"<pkg{Java5Class.java[Java5Class~genericMethod3~I~QList\\<QString;>;"); | |||
} | |||
/* | |||
* Still to do; | |||
* PROJECT, | |||
PACKAGE, | |||
FILE, | |||
FILE_ASPECTJ, | |||
FILE_LST, | |||
DECLARE_ERROR, | |||
DECLARE_SOFT, | |||
DECLARE_PRECEDENCE, | |||
*/ | |||
// ----------- helper methods --------------- | |||
private void compareHandles(IProgramElement.Kind kind, String ipeName, String expectedHandle) { | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement pe = top.findElementForLabel(top.getRoot(),kind,ipeName); | |||
String found = pe.getHandleIdentifier(); | |||
System.err.println("expected: " + expectedHandle); | |||
System.err.println("actual: " + found); | |||
assertEquals("handleIdentifier - expected " + expectedHandle + ", but found " | |||
+ found, expectedHandle, found); | |||
} | |||
// /////////////////////////////////////// | |||
public static Test suite() { | |||
return XMLBasedAjcTestCase.loadSuite(JDTLikeHandleProviderTests.class); | |||
} | |||
protected File getSpecFile() { | |||
return new File( | |||
"../tests/src/org/aspectj/systemtest/ajc152/jdtlikehandleprovider.xml"); | |||
} | |||
} |
@@ -25,13 +25,15 @@ import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory; | |||
import org.aspectj.ajdt.internal.core.builder.AjState; | |||
import org.aspectj.ajdt.internal.core.builder.IncrementalStateManager; | |||
import org.aspectj.asm.AsmManager; | |||
import org.aspectj.asm.IElementHandleProvider; | |||
import org.aspectj.asm.IHierarchy; | |||
import org.aspectj.asm.IProgramElement; | |||
import org.aspectj.asm.IRelationship; | |||
import org.aspectj.asm.IRelationshipMap; | |||
import org.aspectj.asm.internal.JDTLikeHandleProvider; | |||
import org.aspectj.asm.internal.Relationship; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.tools.ajc.Ajc; | |||
import org.aspectj.weaver.World; | |||
/** | |||
* The superclass knows all about talking through Ajde to the compiler. | |||
@@ -1040,7 +1042,7 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
((IMessage)MyTaskListManager.getWarningMessages().get(0)).getSourceLocation().getLine()); | |||
alter("PR134541","inc1"); | |||
build("PR134541"); | |||
if (World.compareLocations) | |||
if (AsmManager.getDefault().getHandleProvider().dependsOnLocation()) | |||
checkWasFullBuild(); // the line number has changed... but nothing structural about the code | |||
else | |||
checkWasntFullBuild(); // the line number has changed... but nothing structural about the code | |||
@@ -1048,6 +1050,131 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
((IMessage)MyTaskListManager.getWarningMessages().get(0)).getSourceLocation().getLine()); | |||
} | |||
public void testJDTLikeHandleProviderWithLstFile_pr141730() { | |||
IElementHandleProvider handleProvider = AsmManager.getDefault().getHandleProvider(); | |||
AsmManager.getDefault().setHandleProvider(new JDTLikeHandleProvider()); | |||
configureBuildStructureModel(true); | |||
try { | |||
// The JDTLike-handles should start with the name | |||
// of the buildconfig file | |||
initialiseProject("JDTLikeHandleProvider"); | |||
build("JDTLikeHandleProvider"); | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement pe = top.findElementForType("pkg","A"); | |||
String expectedHandle = "build<pkg*A.aj}A"; | |||
assertEquals("expected handle to be " + expectedHandle + ", but found " | |||
+ pe.getHandleIdentifier(),expectedHandle,pe.getHandleIdentifier()); | |||
} finally { | |||
AsmManager.getDefault().setHandleProvider(handleProvider); | |||
configureBuildStructureModel(false); | |||
} | |||
} | |||
public void testMovingAdviceDoesntChangeHandles_pr141730() { | |||
IElementHandleProvider handleProvider = AsmManager.getDefault().getHandleProvider(); | |||
AsmManager.getDefault().setHandleProvider(new JDTLikeHandleProvider()); | |||
configureBuildStructureModel(true); | |||
try { | |||
initialiseProject("JDTLikeHandleProvider"); | |||
build("JDTLikeHandleProvider"); | |||
checkWasFullBuild(); | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement pe = top.findElementForLabel(top.getRoot(), | |||
IProgramElement.Kind.ADVICE,"before(): <anonymous pointcut>"); | |||
// add a line which shouldn't change the handle | |||
alter("JDTLikeHandleProvider","inc1"); | |||
build("JDTLikeHandleProvider"); | |||
checkWasntFullBuild(); | |||
IHierarchy top2 = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement pe2 = top.findElementForLabel(top2.getRoot(), | |||
IProgramElement.Kind.ADVICE,"before(): <anonymous pointcut>"); | |||
assertEquals("expected advice to be on line " + pe.getSourceLocation().getLine() + 1 | |||
+ " but was on " + pe2.getSourceLocation().getLine(), | |||
pe.getSourceLocation().getLine()+1,pe2.getSourceLocation().getLine()); | |||
assertEquals("expected advice to have handle " + pe.getHandleIdentifier() | |||
+ " but found handle " + pe2.getHandleIdentifier(), | |||
pe.getHandleIdentifier(),pe2.getHandleIdentifier()); | |||
} finally { | |||
AsmManager.getDefault().setHandleProvider(handleProvider); | |||
configureBuildStructureModel(false); | |||
} | |||
} | |||
public void testSwappingAdviceAndHandles_pr141730() { | |||
IElementHandleProvider handleProvider = AsmManager.getDefault().getHandleProvider(); | |||
AsmManager.getDefault().setHandleProvider(new JDTLikeHandleProvider()); | |||
configureBuildStructureModel(true); | |||
try { | |||
initialiseProject("JDTLikeHandleProvider"); | |||
build("JDTLikeHandleProvider"); | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement call = top.findElementForLabel(top.getRoot(), | |||
IProgramElement.Kind.ADVICE, "after(): callPCD.."); | |||
IProgramElement exec = top.findElementForLabel(top.getRoot(), | |||
IProgramElement.Kind.ADVICE, "after(): execPCD.."); | |||
// swap the two after advice statements over. This forces | |||
// a full build which means 'after(): callPCD..' will now | |||
// be the second after advice in the file and have the same | |||
// handle as 'after(): execPCD..' originally did. | |||
alter("JDTLikeHandleProvider","inc2"); | |||
build("JDTLikeHandleProvider"); | |||
checkWasFullBuild(); | |||
IHierarchy top2 = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement newCall = top2.findElementForLabel(top2.getRoot(), | |||
IProgramElement.Kind.ADVICE, "after(): callPCD.."); | |||
IProgramElement newExec = top2.findElementForLabel(top2.getRoot(), | |||
IProgramElement.Kind.ADVICE, "after(): execPCD.."); | |||
assertEquals("after swapping places, expected 'after(): callPCD..' " + | |||
"to be on line " + newExec.getSourceLocation().getLine() + | |||
" but was on line " + call.getSourceLocation().getLine(), | |||
newExec.getSourceLocation().getLine(), | |||
call.getSourceLocation().getLine()); | |||
assertEquals("after swapping places, expected 'after(): callPCD..' " + | |||
"to have handle " + exec.getHandleIdentifier() + | |||
" (because was full build) but had " + newCall.getHandleIdentifier(), | |||
exec.getHandleIdentifier(), newCall.getHandleIdentifier()); | |||
} finally { | |||
AsmManager.getDefault().setHandleProvider(handleProvider); | |||
configureBuildStructureModel(false); | |||
} | |||
} | |||
public void testInitializerCountForJDTLikeHandleProvider_pr141730() { | |||
IElementHandleProvider handleProvider = AsmManager.getDefault().getHandleProvider(); | |||
AsmManager.getDefault().setHandleProvider(new JDTLikeHandleProvider()); | |||
configureBuildStructureModel(true); | |||
try { | |||
initialiseProject("JDTLikeHandleProvider"); | |||
build("JDTLikeHandleProvider"); | |||
String expected = "build<pkg*A.aj[C|1"; | |||
IHierarchy top = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement init = top.findElementForLabel(top.getRoot(), | |||
IProgramElement.Kind.INITIALIZER, "..."); | |||
assertEquals("expected initializers handle to be " + expected + "," + | |||
" but found " + init.getHandleIdentifier(true), | |||
expected,init.getHandleIdentifier(true)); | |||
alter("JDTLikeHandleProvider","inc2"); | |||
build("JDTLikeHandleProvider"); | |||
checkWasFullBuild(); | |||
IHierarchy top2 = AsmManager.getDefault().getHierarchy(); | |||
IProgramElement init2 = top2.findElementForLabel(top2.getRoot(), | |||
IProgramElement.Kind.INITIALIZER, "..."); | |||
assertEquals("expected initializers handle to still be " + expected + "," + | |||
" but found " + init2.getHandleIdentifier(true), | |||
expected,init2.getHandleIdentifier(true)); | |||
} finally { | |||
AsmManager.getDefault().setHandleProvider(handleProvider); | |||
configureBuildStructureModel(false); | |||
} | |||
} | |||
// 134471 related tests perform incremental compilation and verify features of the structure model post compile | |||
public void testPr134471_IncrementalCompilationAndModelUpdates() { | |||
@@ -1105,7 +1232,12 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
// Step3. No structural change to the aspect but the advice has moved down a few lines... (change in source location) | |||
alter("PR134471_2","inc1"); | |||
build("PR134471_2"); | |||
checkWasFullBuild(); // this is true whilst we consider sourcelocation in the type/shadow munger equals() method - have to until the handles are independent of location | |||
if (AsmManager.getDefault().getHandleProvider().dependsOnLocation()) | |||
checkWasFullBuild(); // the line number has changed... but nothing structural about the code | |||
else | |||
checkWasntFullBuild(); // the line number has changed... but nothing structural about the code | |||
//checkWasFullBuild(); // this is true whilst we consider sourcelocation in the type/shadow munger equals() method - have to until the handles are independent of location | |||
// Step4. Check we have correctly realised the advice moved to line 11 | |||
programElement = getFirstRelatedElement(findCode(checkForNode("pkg","C",true))); | |||
@@ -1134,38 +1266,38 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
public void testPr134471_IncrementallyRecompilingTheAffectedClass() { | |||
try { | |||
// see pr148027 AsmHierarchyBuilder.shouldAddUsesPointcut=false; | |||
configureBuildStructureModel(true); | |||
configureNonStandardCompileOptions("-showWeaveInfo -emacssym"); | |||
// Step1. build the project | |||
initialiseProject("PR134471"); | |||
build("PR134471"); | |||
// Step2. confirm advice is from correct location | |||
IProgramElement programElement = getFirstRelatedElement(findCode(checkForNode("pkg","C",true))); | |||
int line = programElement.getSourceLocation().getLine(); | |||
assertTrue("advice should be at line 7 - but is at line "+line,line==7); | |||
// Step3. No change to the aspect at all | |||
alter("PR134471","inc1"); | |||
build("PR134471"); | |||
// Step4. Quick check that the advice points to something... | |||
IProgramElement nodeForTypeA = checkForNode("pkg","A",true); | |||
IProgramElement nodeForAdvice = findAdvice(nodeForTypeA); | |||
List relatedElements = getRelatedElements(nodeForAdvice,1); | |||
configureBuildStructureModel(true); | |||
configureNonStandardCompileOptions("-showWeaveInfo -emacssym"); | |||
// Step1. build the project | |||
initialiseProject("PR134471"); | |||
build("PR134471"); | |||
// Step2. confirm advice is from correct location | |||
IProgramElement programElement = getFirstRelatedElement(findCode(checkForNode("pkg","C",true))); | |||
int line = programElement.getSourceLocation().getLine(); | |||
assertTrue("advice should be at line 7 - but is at line "+line,line==7); | |||
// Step3. No change to the aspect at all | |||
alter("PR134471","inc1"); | |||
build("PR134471"); | |||
// Step4. Quick check that the advice points to something... | |||
IProgramElement nodeForTypeA = checkForNode("pkg","A",true); | |||
IProgramElement nodeForAdvice = findAdvice(nodeForTypeA); | |||
List relatedElements = getRelatedElements(nodeForAdvice,1); | |||
// Step5. No change to the file C but it should still be advised afterwards | |||
alter("PR134471","inc2"); | |||
build("PR134471"); | |||
checkWasntFullBuild(); | |||
// Step5. No change to the file C but it should still be advised afterwards | |||
alter("PR134471","inc2"); | |||
build("PR134471"); | |||
checkWasntFullBuild(); | |||
// Step6. confirm advice is from correct location | |||
programElement = getFirstRelatedElement(findCode(checkForNode("pkg","C",true))); | |||
line = programElement.getSourceLocation().getLine(); | |||
assertTrue("advice should be at line 7 - but is at line "+line,line==7); | |||
} finally { | |||
// see pr148027 AsmHierarchyBuilder.shouldAddUsesPointcut=true; | |||
// Step6. confirm advice is from correct location | |||
programElement = getFirstRelatedElement(findCode(checkForNode("pkg","C",true))); | |||
line = programElement.getSourceLocation().getLine(); | |||
assertTrue("advice should be at line 7 - but is at line "+line,line==7); | |||
} finally { | |||
// see pr148027 AsmHierarchyBuilder.shouldAddUsesPointcut=true; | |||
} | |||
} | |||
@@ -1193,7 +1325,12 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
// Step4. Move declare warning in the aspect | |||
alter("PR134471_3","inc1"); | |||
build("PR134471_3"); | |||
checkWasFullBuild(); | |||
if (AsmManager.getDefault().getHandleProvider().dependsOnLocation()) | |||
checkWasFullBuild(); // the line number has changed... but nothing structural about the code | |||
else | |||
checkWasntFullBuild(); // the line number has changed... but nothing structural about the code | |||
//checkWasFullBuild(); | |||
// Step5. confirm declare warning is from correct location, decw (now at line 12) in pkg.A matches line 7 in pkg.C | |||
programElement = getFirstRelatedElement(findCode(checkForNode("pkg","C",true),7)); | |||
@@ -1210,6 +1347,7 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
line = programElement.getSourceLocation().getLine(); | |||
assertTrue("declare warning should be at line 12 - but is at line "+line,line==12); | |||
configureBuildStructureModel(false); | |||
} | |||
// similar to previous test but with 'declare warning' as well as advice | |||
@@ -1235,7 +1373,12 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
// Step4. Move declare warning in the aspect | |||
alter("PR134471_3","inc1"); | |||
build("PR134471_3"); | |||
checkWasFullBuild(); | |||
if (AsmManager.getDefault().getHandleProvider().dependsOnLocation()) | |||
checkWasFullBuild(); // the line number has changed... but nothing structural about the code | |||
else | |||
checkWasntFullBuild(); // the line number has changed... but nothing structural about the code | |||
//checkWasFullBuild(); | |||
// Step5. confirm declare warning is from correct location, decw (now at line 12) in pkg.A matches line 7 in pkg.C | |||
programElement = getFirstRelatedElement(findCode(checkForNode("pkg","C",true),7)); | |||
@@ -1262,8 +1405,9 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa | |||
line = programElement.getSourceLocation().getLine(); | |||
assertTrue("declare warning should be at line 12 - but is at line "+line,line==12); | |||
configureBuildStructureModel(false); | |||
} | |||
// --- helper code --- | |||
/** |
@@ -16,6 +16,7 @@ package org.aspectj.weaver; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import org.aspectj.asm.AsmManager; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.weaver.bcel.Utility; | |||
@@ -391,7 +392,8 @@ public abstract class Advice extends ShadowMunger { | |||
return o.kind.equals(kind) | |||
&& ((o.pointcut == null) ? (pointcut == null) : o.pointcut.equals(pointcut)) | |||
&& ((o.signature == null) ? (signature == null) : o.signature.equals(signature)) | |||
&& (World.compareLocations?((o.getSourceLocation()==null) ? (getSourceLocation()==null): o.getSourceLocation().equals(getSourceLocation())):true) // pr134471 - remove when handles are improved to be independent of location | |||
&& (AsmManager.getDefault().getHandleProvider().dependsOnLocation() | |||
?((o.getSourceLocation()==null) ? (getSourceLocation()==null): o.getSourceLocation().equals(getSourceLocation())):true) // pr134471 - remove when handles are improved to be independent of location | |||
; | |||
} |
@@ -17,6 +17,7 @@ import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.Map; | |||
import org.aspectj.asm.AsmManager; | |||
import org.aspectj.asm.IRelationship; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.ISourceLocation; | |||
@@ -114,7 +115,8 @@ public class Checker extends ShadowMunger { | |||
return | |||
o.isError == isError && | |||
((o.pointcut == null) ? (pointcut == null) : o.pointcut.equals(pointcut)) && | |||
(World.compareLocations?((o.getSourceLocation()==null) ? (getSourceLocation()==null): o.getSourceLocation().equals(getSourceLocation())):true) // pr134471 - remove when handles are improved to be independent of location | |||
(AsmManager.getDefault().getHandleProvider().dependsOnLocation() | |||
?((o.getSourceLocation()==null) ? (getSourceLocation()==null): o.getSourceLocation().equals(getSourceLocation())):true) // pr134471 - remove when handles are improved to be independent of location | |||
; | |||
} | |||
@@ -21,6 +21,7 @@ import java.util.List; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import org.aspectj.asm.AsmManager; | |||
import org.aspectj.weaver.patterns.CflowPointcut; | |||
import org.aspectj.weaver.patterns.DeclareParents; | |||
import org.aspectj.weaver.patterns.IVerificationRequired; | |||
@@ -76,7 +77,8 @@ public class CrosscuttingMembersSet { | |||
CflowPointcut.clearCaches(aspectType); | |||
change = true; | |||
} else { | |||
if (!World.compareLocations && inWeavingPhase) { | |||
if (!AsmManager.getDefault().getHandleProvider().dependsOnLocation() | |||
&& inWeavingPhase) { | |||
// bug 134541 - even though we haven't changed we may have updated the | |||
// sourcelocation for the shadowMunger which we need to pick up | |||
shadowMungers = null; |
@@ -54,12 +54,7 @@ public abstract class World implements Dump.INode { | |||
/** The heart of the world, a map from type signatures to resolved types */ | |||
protected TypeMap typeMap = new TypeMap(this); // Signature to ResolvedType | |||
// See pr134471 - we would like to set this false but need for handles in the structure model | |||
// to be independent of location before we can do that. | |||
/** Should we take into account source location when comparing mungers - which may trigger full builds */ | |||
public final static boolean compareLocations = true; | |||
// see pr145963 | |||
/** Should we create the hierarchy for binary classes and aspects*/ | |||
public static boolean createInjarHierarchy = true; |
@@ -31,6 +31,7 @@ import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
import org.aspectj.apache.bcel.generic.Type; | |||
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; | |||
import org.aspectj.asm.AsmManager; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.bridge.Message; | |||
@@ -1679,7 +1680,8 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
BcelTypeMunger o = (BcelTypeMunger) other; | |||
return ((o.getMunger() == null) ? (getMunger() == null) : o.getMunger().equals(getMunger())) | |||
&& ((o.getAspectType() == null) ? (getAspectType() == null) : o.getAspectType().equals(getAspectType())) | |||
&& (World.compareLocations?((o.getSourceLocation()==null)? (getSourceLocation()==null): o.getSourceLocation().equals(getSourceLocation())):true); // pr134471 - remove when handles are improved to be independent of location | |||
&& (AsmManager.getDefault().getHandleProvider().dependsOnLocation() | |||
?((o.getSourceLocation()==null)? (getSourceLocation()==null): o.getSourceLocation().equals(getSourceLocation())):true); // pr134471 - remove when handles are improved to be independent of location | |||
} | |||