From d0c299daf6a8ac2e52c33ab4140257fbd60712dd Mon Sep 17 00:00:00 2001 From: aclement Date: Thu, 6 Jul 2006 07:58:43 +0000 Subject: [PATCH] last patches for 141730 --- asm/src/org/aspectj/asm/AsmManager.java | 19 +- .../aspectj/asm/IElementHandleProvider.java | 14 + .../asm/internal/AspectJElementHierarchy.java | 31 +- .../asm/internal/JDTLikeHandleProvider.java | 213 ++++++++ .../systemtest/ajc150/AnnotationBinding.java | 11 +- .../systemtest/ajc153/AllTestsAspectJ153.java | 1 + .../ajc153/JDTLikeHandleProviderTests.java | 506 ++++++++++++++++++ .../tools/MultiProjectIncrementalTests.java | 218 ++++++-- weaver/src/org/aspectj/weaver/Advice.java | 4 +- weaver/src/org/aspectj/weaver/Checker.java | 4 +- .../weaver/CrosscuttingMembersSet.java | 4 +- weaver/src/org/aspectj/weaver/World.java | 7 +- .../aspectj/weaver/bcel/BcelTypeMunger.java | 4 +- 13 files changed, 962 insertions(+), 74 deletions(-) create mode 100644 asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java create mode 100644 tests/src/org/aspectj/systemtest/ajc153/JDTLikeHandleProviderTests.java diff --git a/asm/src/org/aspectj/asm/AsmManager.java b/asm/src/org/aspectj/asm/AsmManager.java index e28cedf48..baa3225bf 100644 --- a/asm/src/org/aspectj/asm/AsmManager.java +++ b/asm/src/org/aspectj/asm/AsmManager.java @@ -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; diff --git a/asm/src/org/aspectj/asm/IElementHandleProvider.java b/asm/src/org/aspectj/asm/IElementHandleProvider.java index 3e5ef9570..79cd6bfab 100644 --- a/asm/src/org/aspectj/asm/IElementHandleProvider.java +++ b/asm/src/org/aspectj/asm/IElementHandleProvider.java @@ -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(); } diff --git a/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java b/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java index cb483acd0..e0bb070dd 100644 --- a/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java +++ b/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java @@ -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 ""; + } } diff --git a/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java b/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java new file mode 100644 index 000000000..e7912f7be --- /dev/null +++ b/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java @@ -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: ; + * an aspect: top of the tree is either + // or the .lst file + if (ipe == null || + (ipe.getKind().equals(IProgramElement.Kind.FILE_JAVA) + && ipe.getName().equals(""))) { + 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; + } +} diff --git a/tests/src/org/aspectj/systemtest/ajc150/AnnotationBinding.java b/tests/src/org/aspectj/systemtest/ajc150/AnnotationBinding.java index 8766bfa98..99c285158 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/AnnotationBinding.java +++ b/tests/src/org/aspectj/systemtest/ajc150/AnnotationBinding.java @@ -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); + } } diff --git a/tests/src/org/aspectj/systemtest/ajc153/AllTestsAspectJ153.java b/tests/src/org/aspectj/systemtest/ajc153/AllTestsAspectJ153.java index 46aabab95..8bc30d5d2 100644 --- a/tests/src/org/aspectj/systemtest/ajc153/AllTestsAspectJ153.java +++ b/tests/src/org/aspectj/systemtest/ajc153/AllTestsAspectJ153.java @@ -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; } diff --git a/tests/src/org/aspectj/systemtest/ajc153/JDTLikeHandleProviderTests.java b/tests/src/org/aspectj/systemtest/ajc153/JDTLikeHandleProviderTests.java new file mode 100644 index 000000000..a56036b10 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc153/JDTLikeHandleProviderTests.java @@ -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 = "", + "", + "; + runTest("method with generic arg same as jdt"); + compareHandles(IProgramElement.Kind.METHOD, + "genericMethod1(java.util.List)", + ";"); + } + + public void testMethodWithTwoGenericArgsSameAsJDT() { + // JDT: =Java5 Handles/src;~QMyGenericClass\; + runTest("method with two generic args same as jdt"); + compareHandles(IProgramElement.Kind.METHOD, + "genericMethod2(java.util.List," + +"pkg.MyGenericClass)", + ";~QMyGenericClass\\;"); + } + + public void testMethodWithTwoTypeParametersSameAsJDT() { + // JDT: =Java5 Handles/src; + runTest("method with two type parameters same as jdt"); + compareHandles(IProgramElement.Kind.METHOD, + "genericMethod4(pkg.MyGenericClass2)", + ";"); + } + + public void testMethodWithTwoArgsSameAsJDT_2() { + // JDT: =Java5 Handles/src; + runTest("method with two args one of which is generic same as jdt"); + compareHandles(IProgramElement.Kind.METHOD, + "genericMethod3(int,java.util.List)", + ";"); + } + + /* + * 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"); + } + +} diff --git a/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java b/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java index 53f35fba9..6459e5a3a 100644 --- a/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java +++ b/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java @@ -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"); + // 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(): "); + 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