// } | // } | ||||
protected AsmManager() { | protected AsmManager() { | ||||
hierarchy = new AspectJElementHierarchy(); | |||||
// List relationships = new ArrayList(); | |||||
mapper = new RelationshipMap(hierarchy); | |||||
handleProvider = new OptimizedFullPathHandleProvider(); | |||||
handleProvider = new OptimizedFullPathHandleProvider(); | |||||
createNewASM(); | |||||
} | } | ||||
public void createNewASM() { | public void createNewASM() { | ||||
hierarchy = new AspectJElementHierarchy(); | hierarchy = new AspectJElementHierarchy(); | ||||
mapper = new RelationshipMap(hierarchy); | 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() { | public IHierarchy getHierarchy() { | ||||
return hierarchy; | return hierarchy; | ||||
//===================== DELTA PROCESSING CODE ============== start ==========// | //===================== 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. | * Removes the hierarchy structure for the specified files from the structure model. | ||||
* Returns true if it deleted anything | * Returns true if it deleted anything | ||||
fw.write("Deleting "+progElem+" node for file "+fileForCompilation+"\n"); | fw.write("Deleting "+progElem+" node for file "+fileForCompilation+"\n"); | ||||
} | } | ||||
removeNode(progElem); | removeNode(progElem); | ||||
deletedNodes.add(getFilename(progElem.getHandleIdentifier())); | |||||
deletedNodes.add(getCanonicalFilePath(progElem.getSourceLocation().getSourceFile())); | |||||
if (!model.removeFromFileMap(correctedPath.toString())) | if (!model.removeFromFileMap(correctedPath.toString())) | ||||
throw new RuntimeException("Whilst repairing model, couldn't remove entry for file: "+correctedPath.toString()+" from the filemap"); | throw new RuntimeException("Whilst repairing model, couldn't remove entry for file: "+correctedPath.toString()+" from the filemap"); | ||||
modelModified = true; | modelModified = true; | ||||
fw.write("Deleting "+progElem+" node for file "+fileForCompilation+"\n"); | fw.write("Deleting "+progElem+" node for file "+fileForCompilation+"\n"); | ||||
} | } | ||||
removeNode(progElem); | removeNode(progElem); | ||||
deletedNodes.add(getFilename(progElem.getHandleIdentifier())); | |||||
deletedNodes.add(getCanonicalFilePath(progElem.getSourceLocation().getSourceFile())); | |||||
if (!model.removeFromFileMap(correctedPath.toString())) | if (!model.removeFromFileMap(correctedPath.toString())) | ||||
throw new RuntimeException("Whilst repairing model, couldn't remove entry for file: "+correctedPath.toString()+" from the filemap"); | throw new RuntimeException("Whilst repairing model, couldn't remove entry for file: "+correctedPath.toString()+" from the filemap"); | ||||
modelModified = true; | modelModified = true; |
public int getOffSetForHandle(String handle); | 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(); | |||||
} | } |
Set k = handleMap.keySet(); | Set k = handleMap.keySet(); | ||||
for (Iterator iter = k.iterator(); iter.hasNext();) { | for (Iterator iter = k.iterator(); iter.hasNext();) { | ||||
String handle = (String) iter.next(); | 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();) { | for (Iterator iter = forRemoval.iterator(); iter.hasNext();) { | ||||
String handle = (String) iter.next(); | String handle = (String) iter.next(); | ||||
forRemoval.clear(); | forRemoval.clear(); | ||||
k = typeMap.keySet(); | k = typeMap.keySet(); | ||||
for (Iterator iter = k.iterator(); iter.hasNext();) { | 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();) { | 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(); | forRemoval.clear(); | ||||
k = fileMap.keySet(); | k = fileMap.keySet(); | ||||
for (Iterator iter = k.iterator(); iter.hasNext();) { | 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();) { | 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) { | private String getFilename(String hid) { | ||||
return AsmManager.getDefault().getHandleProvider().getFileForHandle(hid); | return AsmManager.getDefault().getHandleProvider().getFileForHandle(hid); | ||||
} | } | ||||
private String getCanonicalFilePath(IProgramElement ipe) { | |||||
if (ipe.getSourceLocation() != null) { | |||||
return AsmManager.getDefault().getCanonicalFilePath(ipe.getSourceLocation().getSourceFile()); | |||||
} | |||||
return ""; | |||||
} | |||||
} | } | ||||
/******************************************************************** | |||||
* 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; | |||||
} | |||||
} |
Relationship rel = (Relationship)l.get(0); | Relationship rel = (Relationship)l.get(0); | ||||
assertTrue("Should have 1 target but has "+rel.getTargets().size(),rel.getTargets().size()==1); | assertTrue("Should have 1 target but has "+rel.getTargets().size(),rel.getTargets().size()==1); | ||||
String tgt = (String)rel.getTargets().get(0); | 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); | |||||
} | } | ||||
} | } | ||||
Relationship rel = (Relationship)l.get(0); | Relationship rel = (Relationship)l.get(0); | ||||
assertTrue("Should have 1 target but has "+rel.getTargets().size(),rel.getTargets().size()==1); | assertTrue("Should have 1 target but has "+rel.getTargets().size(),rel.getTargets().size()==1); | ||||
String tgt = (String)rel.getTargets().get(0); | 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); | |||||
} | } | ||||
} | } | ||||
Relationship rel = (Relationship)l.get(0); | Relationship rel = (Relationship)l.get(0); | ||||
assertTrue("Should have 1 target but has "+rel.getTargets().size(),rel.getTargets().size()==1); | assertTrue("Should have 1 target but has "+rel.getTargets().size(),rel.getTargets().size()==1); | ||||
String tgt = (String)rel.getTargets().get(0); | 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); | |||||
} | } | ||||
} | } | ||||
TestSuite suite = new TestSuite("AspectJ 1.5.3 tests"); | TestSuite suite = new TestSuite("AspectJ 1.5.3 tests"); | ||||
//$JUnit-BEGIN$ | //$JUnit-BEGIN$ | ||||
suite.addTest(Ajc153Tests.suite()); | suite.addTest(Ajc153Tests.suite()); | ||||
suite.addTest(JDTLikeHandleProviderTests.suite()); | |||||
//$JUnit-END$ | //$JUnit-END$ | ||||
return suite; | return suite; | ||||
} | } |
/******************************************************************** | |||||
* 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"); | |||||
} | |||||
} |
import org.aspectj.ajdt.internal.core.builder.AjState; | import org.aspectj.ajdt.internal.core.builder.AjState; | ||||
import org.aspectj.ajdt.internal.core.builder.IncrementalStateManager; | import org.aspectj.ajdt.internal.core.builder.IncrementalStateManager; | ||||
import org.aspectj.asm.AsmManager; | import org.aspectj.asm.AsmManager; | ||||
import org.aspectj.asm.IElementHandleProvider; | |||||
import org.aspectj.asm.IHierarchy; | |||||
import org.aspectj.asm.IProgramElement; | import org.aspectj.asm.IProgramElement; | ||||
import org.aspectj.asm.IRelationship; | import org.aspectj.asm.IRelationship; | ||||
import org.aspectj.asm.IRelationshipMap; | import org.aspectj.asm.IRelationshipMap; | ||||
import org.aspectj.asm.internal.JDTLikeHandleProvider; | |||||
import org.aspectj.asm.internal.Relationship; | import org.aspectj.asm.internal.Relationship; | ||||
import org.aspectj.bridge.IMessage; | import org.aspectj.bridge.IMessage; | ||||
import org.aspectj.tools.ajc.Ajc; | import org.aspectj.tools.ajc.Ajc; | ||||
import org.aspectj.weaver.World; | |||||
/** | /** | ||||
* The superclass knows all about talking through Ajde to the compiler. | * The superclass knows all about talking through Ajde to the compiler. | ||||
((IMessage)MyTaskListManager.getWarningMessages().get(0)).getSourceLocation().getLine()); | ((IMessage)MyTaskListManager.getWarningMessages().get(0)).getSourceLocation().getLine()); | ||||
alter("PR134541","inc1"); | alter("PR134541","inc1"); | ||||
build("PR134541"); | build("PR134541"); | ||||
if (World.compareLocations) | |||||
if (AsmManager.getDefault().getHandleProvider().dependsOnLocation()) | |||||
checkWasFullBuild(); // the line number has changed... but nothing structural about the code | checkWasFullBuild(); // the line number has changed... but nothing structural about the code | ||||
else | else | ||||
checkWasntFullBuild(); // the line number has changed... but nothing structural about the code | checkWasntFullBuild(); // the line number has changed... but nothing structural about the code | ||||
((IMessage)MyTaskListManager.getWarningMessages().get(0)).getSourceLocation().getLine()); | ((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 | // 134471 related tests perform incremental compilation and verify features of the structure model post compile | ||||
public void testPr134471_IncrementalCompilationAndModelUpdates() { | public void testPr134471_IncrementalCompilationAndModelUpdates() { | ||||
// Step3. No structural change to the aspect but the advice has moved down a few lines... (change in source location) | // Step3. No structural change to the aspect but the advice has moved down a few lines... (change in source location) | ||||
alter("PR134471_2","inc1"); | alter("PR134471_2","inc1"); | ||||
build("PR134471_2"); | 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 | // Step4. Check we have correctly realised the advice moved to line 11 | ||||
programElement = getFirstRelatedElement(findCode(checkForNode("pkg","C",true))); | programElement = getFirstRelatedElement(findCode(checkForNode("pkg","C",true))); | ||||
public void testPr134471_IncrementallyRecompilingTheAffectedClass() { | public void testPr134471_IncrementallyRecompilingTheAffectedClass() { | ||||
try { | try { | ||||
// see pr148027 AsmHierarchyBuilder.shouldAddUsesPointcut=false; | // 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; | |||||
} | } | ||||
} | } | ||||
// Step4. Move declare warning in the aspect | // Step4. Move declare warning in the aspect | ||||
alter("PR134471_3","inc1"); | alter("PR134471_3","inc1"); | ||||
build("PR134471_3"); | 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 | // 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)); | programElement = getFirstRelatedElement(findCode(checkForNode("pkg","C",true),7)); | ||||
line = programElement.getSourceLocation().getLine(); | line = programElement.getSourceLocation().getLine(); | ||||
assertTrue("declare warning should be at line 12 - but is at line "+line,line==12); | 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 | // similar to previous test but with 'declare warning' as well as advice | ||||
// Step4. Move declare warning in the aspect | // Step4. Move declare warning in the aspect | ||||
alter("PR134471_3","inc1"); | alter("PR134471_3","inc1"); | ||||
build("PR134471_3"); | 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 | // 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)); | programElement = getFirstRelatedElement(findCode(checkForNode("pkg","C",true),7)); | ||||
line = programElement.getSourceLocation().getLine(); | line = programElement.getSourceLocation().getLine(); | ||||
assertTrue("declare warning should be at line 12 - but is at line "+line,line==12); | assertTrue("declare warning should be at line 12 - but is at line "+line,line==12); | ||||
configureBuildStructureModel(false); | |||||
} | } | ||||
// --- helper code --- | // --- helper code --- | ||||
/** | /** |
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.List; | import java.util.List; | ||||
import org.aspectj.asm.AsmManager; | |||||
import org.aspectj.bridge.IMessage; | import org.aspectj.bridge.IMessage; | ||||
import org.aspectj.bridge.ISourceLocation; | import org.aspectj.bridge.ISourceLocation; | ||||
import org.aspectj.weaver.bcel.Utility; | import org.aspectj.weaver.bcel.Utility; | ||||
return o.kind.equals(kind) | return o.kind.equals(kind) | ||||
&& ((o.pointcut == null) ? (pointcut == null) : o.pointcut.equals(pointcut)) | && ((o.pointcut == null) ? (pointcut == null) : o.pointcut.equals(pointcut)) | ||||
&& ((o.signature == null) ? (signature == null) : o.signature.equals(signature)) | && ((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 | |||||
; | ; | ||||
} | } |
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.Map; | import java.util.Map; | ||||
import org.aspectj.asm.AsmManager; | |||||
import org.aspectj.asm.IRelationship; | import org.aspectj.asm.IRelationship; | ||||
import org.aspectj.bridge.IMessage; | import org.aspectj.bridge.IMessage; | ||||
import org.aspectj.bridge.ISourceLocation; | import org.aspectj.bridge.ISourceLocation; | ||||
return | return | ||||
o.isError == isError && | o.isError == isError && | ||||
((o.pointcut == null) ? (pointcut == null) : o.pointcut.equals(pointcut)) && | ((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 | |||||
; | ; | ||||
} | } | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Set; | import java.util.Set; | ||||
import org.aspectj.asm.AsmManager; | |||||
import org.aspectj.weaver.patterns.CflowPointcut; | import org.aspectj.weaver.patterns.CflowPointcut; | ||||
import org.aspectj.weaver.patterns.DeclareParents; | import org.aspectj.weaver.patterns.DeclareParents; | ||||
import org.aspectj.weaver.patterns.IVerificationRequired; | import org.aspectj.weaver.patterns.IVerificationRequired; | ||||
CflowPointcut.clearCaches(aspectType); | CflowPointcut.clearCaches(aspectType); | ||||
change = true; | change = true; | ||||
} else { | } else { | ||||
if (!World.compareLocations && inWeavingPhase) { | |||||
if (!AsmManager.getDefault().getHandleProvider().dependsOnLocation() | |||||
&& inWeavingPhase) { | |||||
// bug 134541 - even though we haven't changed we may have updated the | // bug 134541 - even though we haven't changed we may have updated the | ||||
// sourcelocation for the shadowMunger which we need to pick up | // sourcelocation for the shadowMunger which we need to pick up | ||||
shadowMungers = null; | shadowMungers = null; |
/** The heart of the world, a map from type signatures to resolved types */ | /** The heart of the world, a map from type signatures to resolved types */ | ||||
protected TypeMap typeMap = new TypeMap(this); // Signature to ResolvedType | 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 | // see pr145963 | ||||
/** Should we create the hierarchy for binary classes and aspects*/ | /** Should we create the hierarchy for binary classes and aspects*/ | ||||
public static boolean createInjarHierarchy = true; | public static boolean createInjarHierarchy = true; |
import org.aspectj.apache.bcel.generic.InstructionList; | import org.aspectj.apache.bcel.generic.InstructionList; | ||||
import org.aspectj.apache.bcel.generic.Type; | import org.aspectj.apache.bcel.generic.Type; | ||||
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; | import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; | ||||
import org.aspectj.asm.AsmManager; | |||||
import org.aspectj.bridge.IMessage; | import org.aspectj.bridge.IMessage; | ||||
import org.aspectj.bridge.ISourceLocation; | import org.aspectj.bridge.ISourceLocation; | ||||
import org.aspectj.bridge.Message; | import org.aspectj.bridge.Message; | ||||
BcelTypeMunger o = (BcelTypeMunger) other; | BcelTypeMunger o = (BcelTypeMunger) other; | ||||
return ((o.getMunger() == null) ? (getMunger() == null) : o.getMunger().equals(getMunger())) | return ((o.getMunger() == null) ? (getMunger() == null) : o.getMunger().equals(getMunger())) | ||||
&& ((o.getAspectType() == null) ? (getAspectType() == null) : o.getAspectType().equals(getAspectType())) | && ((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 | |||||
} | } | ||||