]> source.dussan.org Git - aspectj.git/commitdiff
246125: moving structure model related stuff out of org.aspectj.weaver into org.aspec...
authoraclement <aclement>
Mon, 20 Oct 2008 18:51:09 +0000 (18:51 +0000)
committeraclement <aclement>
Mon, 20 Oct 2008 18:51:09 +0000 (18:51 +0000)
weaver/src/org/aspectj/weaver/AsmRelationshipProvider.java [deleted file]
weaver/src/org/aspectj/weaver/AsmRelationshipUtils.java [deleted file]
weaver/src/org/aspectj/weaver/Checker.java
weaver/src/org/aspectj/weaver/Shadow.java
weaver/src/org/aspectj/weaver/ShadowMunger.java
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
weaver/src/org/aspectj/weaver/model/AsmRelationshipProvider.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/model/AsmRelationshipUtils.java [new file with mode: 0644]

diff --git a/weaver/src/org/aspectj/weaver/AsmRelationshipProvider.java b/weaver/src/org/aspectj/weaver/AsmRelationshipProvider.java
deleted file mode 100644 (file)
index 52336bf..0000000
+++ /dev/null
@@ -1,487 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved. 
- * This program and the accompanying materials are made available 
- * under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     PARC     initial implementation 
- * ******************************************************************/
-
-package org.aspectj.weaver;
-
-import java.util.Iterator;
-
-import org.aspectj.asm.AsmManager;
-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.ProgramElement;
-import org.aspectj.bridge.ISourceLocation;
-import org.aspectj.bridge.SourceLocation;
-
-public class AsmRelationshipProvider {
-
-       protected static AsmRelationshipProvider INSTANCE = new AsmRelationshipProvider();
-
-       public static final String ADVISES = "advises";
-       public static final String ADVISED_BY = "advised by";
-       public static final String DECLARES_ON = "declares on";
-       public static final String DECLAREDY_BY = "declared by";
-       public static final String SOFTENS = "softens";
-       public static final String SOFTENED_BY = "softened by";
-       public static final String MATCHED_BY = "matched by";
-       public static final String MATCHES_DECLARE = "matches declare";
-       public static final String INTER_TYPE_DECLARES = "declared on";
-       public static final String INTER_TYPE_DECLARED_BY = "aspect declarations";
-
-       public static final String ANNOTATES = "annotates";
-       public static final String ANNOTATED_BY = "annotated by";
-
-       public void checkerMunger(AsmManager asm, Shadow shadow, Checker checker) {
-               if (asm == null) // !AsmManager.isCreatingModel())
-                       return;
-               if (shadow.getSourceLocation() == null || checker.getSourceLocation() == null)
-                       return;
-
-               if (World.createInjarHierarchy) {
-                       checker.createHierarchy(asm);
-               }
-
-               // Ensure a node for the target exists
-               IProgramElement targetNode = getNode(asm, shadow);
-               if (targetNode == null)
-                       return;
-               String targetHandle = asm.getHandleProvider().createHandleIdentifier(targetNode);
-               if (targetHandle == null)
-                       return;
-
-               IProgramElement sourceNode = asm.getHierarchy().findElementForSourceLine(checker.getSourceLocation());
-               String sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
-               if (sourceHandle == null)
-                       return;
-
-               IRelationshipMap mapper = asm.getRelationshipMap();
-               IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE, MATCHED_BY, false, true);
-               foreward.addTarget(targetHandle);
-
-               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE, MATCHES_DECLARE, false, true);
-               if (back != null && back.getTargets() != null) {
-                       back.addTarget(sourceHandle);
-               }
-               if (sourceNode.getSourceLocation() != null) {
-                       asm.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
-               }
-
-       }
-
-       // For ITDs
-       public void addRelationship(AsmManager asm, ResolvedType onType, ResolvedTypeMunger munger, ResolvedType originatingAspect) {
-
-               if (asm == null)// !AsmManager.isCreatingModel())
-                       return;
-               if (originatingAspect.getSourceLocation() != null) {
-                       String sourceHandle = "";
-                       IProgramElement sourceNode = null;
-                       if (munger.getSourceLocation() != null && munger.getSourceLocation().getOffset() != -1) {
-                               sourceNode = asm.getHierarchy().findElementForSourceLine(munger.getSourceLocation());
-                               sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
-                       } else {
-                               sourceNode = asm.getHierarchy().findElementForSourceLine(originatingAspect.getSourceLocation());
-                               sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
-                       }
-                       if (sourceHandle == null)
-                               return;
-                       IProgramElement targetNode = asm.getHierarchy().findElementForSourceLine(onType.getSourceLocation());
-                       String targetHandle = asm.getHandleProvider().createHandleIdentifier(targetNode);
-                       if (targetHandle == null)
-                               return;
-
-                       IRelationshipMap mapper = asm.getRelationshipMap();
-                       IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARES, false,
-                                       true);
-                       foreward.addTarget(targetHandle);
-
-                       IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARED_BY, false,
-                                       true);
-                       back.addTarget(sourceHandle);
-                       asm.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
-               }
-       }
-
-       // public void addDeclareParentsRelationship(ISourceLocation decp,
-       // ResolvedType targetType, List newParents) {
-       // if (!AsmManager.isCreatingModel())
-       // return;
-       //
-       // IProgramElement sourceNode =
-       // AsmManager.getDefault().getHierarchy().findElementForSourceLine(decp);
-       // String sourceHandle =
-       // AsmManager.getDefault().getHandleProvider().createHandleIdentifier
-       // (sourceNode);
-       // if (sourceHandle == null)
-       // return;
-       //
-       // IProgramElement targetNode = AsmManager.getDefault().getHierarchy()
-       // .findElementForSourceLine(targetType.getSourceLocation());
-       // String targetHandle =
-       // AsmManager.getDefault().getHandleProvider().createHandleIdentifier
-       // (targetNode);
-       // if (targetHandle == null)
-       // return;
-       //
-       // IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap();
-       // IRelationship foreward = mapper.get(sourceHandle,
-       // IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARES, false, true);
-       // foreward.addTarget(targetHandle);
-       //
-       // IRelationship back = mapper.get(targetHandle,
-       // IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARED_BY, false,
-       // true);
-       // back.addTarget(sourceHandle);
-       // }
-
-       /**
-        * Adds a declare annotation relationship, sometimes entities don't have source locs (methods/fields) so use other variants of
-        * this method if that is the case as they will look the entities up in the structure model.
-        */
-       public void addDeclareAnnotationRelationship(AsmManager asm, ISourceLocation declareAnnotationLocation,
-                       ISourceLocation annotatedLocation) {
-               if (asm == null) // !AsmManager.isCreatingModel())
-                       return;
-
-               IProgramElement sourceNode = asm.getHierarchy().findElementForSourceLine(declareAnnotationLocation);
-               String sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
-               if (sourceHandle == null)
-                       return;
-
-               IProgramElement targetNode = asm.getHierarchy().findElementForSourceLine(annotatedLocation);
-               String targetHandle = asm.getHandleProvider().createHandleIdentifier(targetNode);
-               if (targetHandle == null)
-                       return;
-
-               IRelationshipMap mapper = asm.getRelationshipMap();
-               IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
-               foreward.addTarget(targetHandle);
-
-               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true);
-               back.addTarget(sourceHandle);
-               if (sourceNode.getSourceLocation() != null) {
-                       asm.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
-               }
-       }
-
-       public void adviceMunger(AsmManager asm, Shadow shadow, ShadowMunger munger) {
-               if (asm == null) // !AsmManager.isCreatingModel())
-                       return;
-               if (munger instanceof Advice) {
-                       Advice advice = (Advice) munger;
-
-                       if (advice.getKind().isPerEntry() || advice.getKind().isCflow()) {
-                               // TODO: might want to show these in the future
-                               return;
-                       }
-
-                       if (World.createInjarHierarchy) {
-                               munger.createHierarchy(asm);
-                       }
-
-                       IRelationshipMap mapper = asm.getRelationshipMap();
-                       IProgramElement targetNode = getNode(asm, shadow);
-                       if (targetNode == null)
-                               return;
-                       boolean runtimeTest = advice.hasDynamicTests();
-
-                       // Work out extra info to inform interested UIs !
-                       IProgramElement.ExtraInformation ai = new IProgramElement.ExtraInformation();
-
-                       String adviceHandle = advice.getHandle(asm);
-                       if (adviceHandle == null)
-                               return;
-
-                       // What kind of advice is it?
-                       // TODO: Prob a better way to do this but I just want to
-                       // get it into CVS !!!
-                       AdviceKind ak = ((Advice) munger).getKind();
-                       ai.setExtraAdviceInformation(ak.getName());
-                       IProgramElement adviceElement = asm.getHierarchy().findElementForHandle(adviceHandle);
-                       if (adviceElement != null) {
-                               adviceElement.setExtraInfo(ai);
-                       }
-                       String targetHandle = targetNode.getHandleIdentifier();
-                       if (advice.getKind().equals(AdviceKind.Softener)) {
-                               IRelationship foreward = mapper.get(adviceHandle, IRelationship.Kind.DECLARE_SOFT, SOFTENS, runtimeTest, true);
-                               if (foreward != null)
-                                       foreward.addTarget(targetHandle);// foreward.getTargets().add
-                               // (targetHandle);
-
-                               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE, SOFTENED_BY, runtimeTest, true);
-                               if (back != null)
-                                       back.addTarget(adviceHandle);// back.getTargets().add(
-                               // adviceHandle);
-                       } else {
-                               IRelationship foreward = mapper.get(adviceHandle, IRelationship.Kind.ADVICE, ADVISES, runtimeTest, true);
-                               if (foreward != null)
-                                       foreward.addTarget(targetHandle);// foreward.getTargets().add
-                               // (targetHandle);
-
-                               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.ADVICE, ADVISED_BY, runtimeTest, true);
-                               if (back != null)
-                                       back.addTarget(adviceHandle);// back.getTargets().add(
-                               // adviceHandle);
-                       }
-                       if (adviceElement.getSourceLocation() != null) {
-                               asm.addAspectInEffectThisBuild(adviceElement.getSourceLocation().getSourceFile());
-                       }
-               }
-       }
-
-       protected IProgramElement getNode(AsmManager model, Shadow shadow) {
-               Member enclosingMember = shadow.getEnclosingCodeSignature();
-
-               IProgramElement enclosingNode = lookupMember(model.getHierarchy(), enclosingMember);
-               if (enclosingNode == null) {
-                       Lint.Kind err = shadow.getIWorld().getLint().shadowNotInStructure;
-                       if (err.isEnabled()) {
-                               err.signal(shadow.toString(), shadow.getSourceLocation());
-                       }
-                       return null;
-               }
-
-               Member shadowSig = shadow.getSignature();
-               // pr235204
-               if (shadow.getKind() == Shadow.MethodCall || !shadowSig.equals(enclosingMember)) {
-                       IProgramElement bodyNode = findOrCreateCodeNode(model, enclosingNode, shadowSig, shadow);
-                       return bodyNode;
-               } else {
-                       return enclosingNode;
-               }
-       }
-
-       private boolean sourceLinesMatch(ISourceLocation loc1, ISourceLocation loc2) {
-               if (loc1.getLine() != loc2.getLine())
-                       return false;
-               return true;
-       }
-
-       /**
-        * Finds or creates a code IProgramElement for the given shadow.
-        * 
-        * The byteCodeName of the created node is set to 'shadowSig.getName() + "!" + counter', eg "println!3". The counter is the
-        * occurence count of children within the enclosingNode which have the same name. So, for example, if a method contains two
-        * System.out.println statements, the first one will have byteCodeName 'println!1' and the second will have byteCodeName
-        * 'println!2'. This is to ensure the two nodes have unique handles when the handles do not depend on sourcelocations.
-        * 
-        * Currently the shadows are examined in the sequence they appear in the source file. This means that the counters are
-        * consistent over incremental builds. All aspects are compiled up front and any new aspect created will force a full build.
-        * Moreover, if the body of the enclosingShadow is changed, then the model for this is rebuilt from scratch.
-        */
-       private IProgramElement findOrCreateCodeNode(AsmManager asm, IProgramElement enclosingNode, Member shadowSig, Shadow shadow) {
-               for (Iterator it = enclosingNode.getChildren().iterator(); it.hasNext();) {
-                       IProgramElement node = (IProgramElement) it.next();
-                       int excl = node.getBytecodeName().lastIndexOf('!');
-                       if (((excl != -1 && shadowSig.getName().equals(node.getBytecodeName().substring(0, excl))) || shadowSig.getName()
-                                       .equals(node.getBytecodeName()))
-                                       && shadowSig.getSignature().equals(node.getBytecodeSignature())
-                                       && sourceLinesMatch(node.getSourceLocation(), shadow.getSourceLocation())) {
-                               return node;
-                       }
-               }
-
-               ISourceLocation sl = shadow.getSourceLocation();
-
-               // XXX why not use shadow file? new SourceLocation(sl.getSourceFile(),
-               // sl.getLine()),
-               SourceLocation peLoc = new SourceLocation(enclosingNode.getSourceLocation().getSourceFile(), sl.getLine());
-               peLoc.setOffset(sl.getOffset());
-               IProgramElement peNode = new ProgramElement(asm, shadow.toString(), IProgramElement.Kind.CODE, peLoc, 0, null, null);
-
-               // check to see if the enclosing shadow already has children with the
-               // same name. If so we want to add a counter to the byteCodeName
-               // otherwise
-               // we wont get unique handles
-               int numberOfChildrenWithThisName = 0;
-               for (Iterator it = enclosingNode.getChildren().iterator(); it.hasNext();) {
-                       IProgramElement child = (IProgramElement) it.next();
-                       if (child.getName().equals(shadow.toString())) {
-                               numberOfChildrenWithThisName++;
-                       }
-               }
-               peNode.setBytecodeName(shadowSig.getName() + "!" + String.valueOf(numberOfChildrenWithThisName + 1));
-               peNode.setBytecodeSignature(shadowSig.getSignature());
-               enclosingNode.addChild(peNode);
-               return peNode;
-       }
-
-       protected IProgramElement lookupMember(IHierarchy model, Member member) {
-               UnresolvedType declaringType = member.getDeclaringType();
-               IProgramElement classNode = model.findElementForType(declaringType.getPackageName(), declaringType.getClassName());
-               return findMemberInClass(classNode, member);
-       }
-
-       protected IProgramElement findMemberInClass(IProgramElement classNode, Member member) {
-               if (classNode == null)
-                       return null; // XXX remove this check
-               for (Iterator it = classNode.getChildren().iterator(); it.hasNext();) {
-                       IProgramElement node = (IProgramElement) it.next();
-                       if (member.getName().equals(node.getBytecodeName()) && member.getSignature().equals(node.getBytecodeSignature())) {
-                               return node;
-                       }
-               }
-               // if we can't find the member, we'll just put it in the class
-               return classNode;
-       }
-
-       // private static IProgramElement.Kind genShadowKind(Shadow shadow) {
-       // IProgramElement.Kind shadowKind;
-       // if (shadow.getKind() == Shadow.MethodCall
-       // || shadow.getKind() == Shadow.ConstructorCall
-       // || shadow.getKind() == Shadow.FieldGet
-       // || shadow.getKind() == Shadow.FieldSet
-       // || shadow.getKind() == Shadow.ExceptionHandler) {
-       // return IProgramElement.Kind.CODE;
-       //                      
-       // } else if (shadow.getKind() == Shadow.MethodExecution) {
-       // return IProgramElement.Kind.METHOD;
-       //                      
-       // } else if (shadow.getKind() == Shadow.ConstructorExecution) {
-       // return IProgramElement.Kind.CONSTRUCTOR;
-       //                      
-       // } else if (shadow.getKind() == Shadow.PreInitialization
-       // || shadow.getKind() == Shadow.Initialization) {
-       // return IProgramElement.Kind.CLASS;
-       //                      
-       // } else if (shadow.getKind() == Shadow.AdviceExecution) {
-       // return IProgramElement.Kind.ADVICE;
-       //                      
-       // } else {
-       // return IProgramElement.Kind.ERROR;
-       // }
-       // }
-
-       public static AsmRelationshipProvider getDefault() {
-               return INSTANCE;
-       }
-
-       /**
-        * Add a relationship to the known set for a declare @method/@constructor construct. Locating the method is a messy (for messy
-        * read 'fragile') bit of code that could break at any moment but it's working for my simple testcase. Currently just fails
-        * silently if any of the lookup code doesn't find anything...
-        * 
-        * @param hierarchy
-        */
-       public void addDeclareAnnotationMethodRelationship(ISourceLocation sourceLocation, String typename, ResolvedMember method,
-                       AsmManager structureModel) {
-               if (structureModel == null) // !AsmManager.isCreatingModel())
-                       return;
-
-               String pkg = null;
-               String type = typename;
-               int packageSeparator = typename.lastIndexOf(".");
-               if (packageSeparator != -1) {
-                       pkg = typename.substring(0, packageSeparator);
-                       type = typename.substring(packageSeparator + 1);
-               }
-
-               IHierarchy hierarchy = structureModel.getHierarchy();
-
-               IProgramElement typeElem = hierarchy.findElementForType(pkg, type);
-               if (typeElem == null)
-                       return;
-
-               StringBuffer parmString = new StringBuffer("(");
-               UnresolvedType[] args = method.getParameterTypes();
-               // Type[] args = method.getArgumentTypes();
-               for (int i = 0; i < args.length; i++) {
-                       String s = args[i].getName();// Utility.signatureToString(args[i].
-                       // getName()getSignature(), false);
-                       parmString.append(s);
-                       if ((i + 1) < args.length)
-                               parmString.append(",");
-               }
-               parmString.append(")");
-               IProgramElement methodElem = null;
-
-               if (method.getName().startsWith("<init>")) {
-                       // its a ctor
-                       methodElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.CONSTRUCTOR, type + parmString);
-                       if (methodElem == null && args.length == 0)
-                               methodElem = typeElem; // assume default ctor
-               } else {
-                       // its a method
-                       methodElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.METHOD, method.getName() + parmString);
-               }
-
-               if (methodElem == null)
-                       return;
-
-               try {
-                       String targetHandle = methodElem.getHandleIdentifier();
-                       if (targetHandle == null)
-                               return;
-
-                       IProgramElement sourceNode = hierarchy.findElementForSourceLine(sourceLocation);
-                       String sourceHandle = structureModel.getHandleProvider().createHandleIdentifier(sourceNode);
-                       if (sourceHandle == null)
-                               return;
-
-                       IRelationshipMap mapper = structureModel.getRelationshipMap();
-                       IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
-                       foreward.addTarget(targetHandle);
-
-                       IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true);
-                       back.addTarget(sourceHandle);
-               } catch (Throwable t) { // I'm worried about that code above, this will
-                       // make sure we don't explode if it plays up
-                       t.printStackTrace(); // I know I know .. but I don't want to lose
-                       // it!
-               }
-       }
-
-       /**
-        * Add a relationship to the known set for a declare @field construct. Locating the field is trickier than it might seem since
-        * we have no line number info for it, we have to dig through the structure model under the fields' type in order to locate it.
-        * Currently just fails silently if any of the lookup code doesn't find anything...
-        */
-       public void addDeclareAnnotationFieldRelationship(AsmManager asm, ISourceLocation sourceLocation, String typename,
-                       ResolvedMember field) {
-               if (asm == null) // !AsmManager.isCreatingModel())
-                       return;
-
-               String pkg = null;
-               String type = typename;
-               int packageSeparator = typename.lastIndexOf(".");
-               if (packageSeparator != -1) {
-                       pkg = typename.substring(0, packageSeparator);
-                       type = typename.substring(packageSeparator + 1);
-               }
-               IHierarchy hierarchy = asm.getHierarchy();
-               IProgramElement typeElem = hierarchy.findElementForType(pkg, type);
-               if (typeElem == null)
-                       return;
-
-               IProgramElement fieldElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.FIELD, field.getName());
-               if (fieldElem == null)
-                       return;
-
-               String targetHandle = fieldElem.getHandleIdentifier();
-               if (targetHandle == null)
-                       return;
-
-               IProgramElement sourceNode = hierarchy.findElementForSourceLine(sourceLocation);
-               String sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
-               if (sourceHandle == null)
-                       return;
-
-               IRelationshipMap mapper = asm.getRelationshipMap();
-               IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
-               foreward.addTarget(targetHandle);
-
-               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true);
-               back.addTarget(sourceHandle);
-       }
-
-}
diff --git a/weaver/src/org/aspectj/weaver/AsmRelationshipUtils.java b/weaver/src/org/aspectj/weaver/AsmRelationshipUtils.java
deleted file mode 100644 (file)
index 722ddb0..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/********************************************************************
- * 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.weaver;
-
-import org.aspectj.weaver.patterns.AndPointcut;
-import org.aspectj.weaver.patterns.OrPointcut;
-import org.aspectj.weaver.patterns.Pointcut;
-import org.aspectj.weaver.patterns.ReferencePointcut;
-
-/**
- * Provides utility methods for generating details for IProgramElements used when creating the model both from source (via
- * AsmElementFormatter.visit(..)) and when filling in the model for binary aspects (via AsmRelationshipProvider bug 145963)
- */
-public class AsmRelationshipUtils {
-
-       // public static final String UNDEFINED="<undefined>";
-       public static final String DECLARE_PRECEDENCE = "precedence";
-       public static final String DECLARE_SOFT = "soft";
-       public static final String DECLARE_PARENTS = "parents";
-       public static final String DECLARE_WARNING = "warning";
-       public static final String DECLARE_ERROR = "error";
-       public static final String DECLARE_UNKNONWN = "<unknown declare>";
-       public static final String POINTCUT_ABSTRACT = "<abstract pointcut>";
-       public static final String POINTCUT_ANONYMOUS = "<anonymous pointcut>";
-       public static final String DOUBLE_DOTS = "..";
-       public static final int MAX_MESSAGE_LENGTH = 18;
-       public static final String DEC_LABEL = "declare";
-
-       /**
-        * Generates the declare message used in the details, for example if the declare warning statement has message
-        * "There should be no printlns" will return 'declare warning: "There should be n.."'
-        */
-       public static String genDeclareMessage(String message) {
-               int length = message.length();
-               if (length < MAX_MESSAGE_LENGTH) {
-                       return message;
-               } else {
-                       return message.substring(0, MAX_MESSAGE_LENGTH - 1) + DOUBLE_DOTS;
-               }
-       }
-
-       /**
-        * Generates the pointcut details for the given pointcut, for example an anonymous pointcut will return '<anonymous pointcut>'
-        * and a named pointcut called p() will return 'p()..'
-        */
-       public static String genPointcutDetails(Pointcut pcd) {
-               StringBuffer details = new StringBuffer();
-               if (pcd instanceof ReferencePointcut) {
-                       ReferencePointcut rp = (ReferencePointcut) pcd;
-                       details.append(rp.name).append(DOUBLE_DOTS);
-               } else if (pcd instanceof AndPointcut) {
-                       AndPointcut ap = (AndPointcut) pcd;
-                       if (ap.getLeft() instanceof ReferencePointcut) {
-                               details.append(ap.getLeft().toString()).append(DOUBLE_DOTS);
-                       } else {
-                               details.append(POINTCUT_ANONYMOUS).append(DOUBLE_DOTS);
-                       }
-               } else if (pcd instanceof OrPointcut) {
-                       OrPointcut op = (OrPointcut) pcd;
-                       if (op.getLeft() instanceof ReferencePointcut) {
-                               details.append(op.getLeft().toString()).append(DOUBLE_DOTS);
-                       } else {
-                               details.append(POINTCUT_ANONYMOUS).append(DOUBLE_DOTS);
-                       }
-               } else {
-                       details.append(POINTCUT_ANONYMOUS);
-               }
-               return details.toString();
-       }
-
-}
index 6f521b233f38de26cf4ce01bb529be2631cb7b5c..c563792407b8420c227a3cd4f290d5798c0cac4b 100644 (file)
@@ -20,6 +20,7 @@ import org.aspectj.asm.IRelationship;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.bridge.Message;
+import org.aspectj.weaver.model.AsmRelationshipProvider;
 import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
 import org.aspectj.weaver.patterns.PerClause;
 import org.aspectj.weaver.patterns.Pointcut;
index 346d60ff3de7c00aac457fb74719ba258f59be69..ea3a891f27aecc25c203e6904f1a27d3c9df25d7 100644 (file)
@@ -32,6 +32,7 @@ import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.PartialOrder;
 import org.aspectj.util.TypeSafeEnum;
 import org.aspectj.weaver.ast.Var;
+import org.aspectj.weaver.model.AsmRelationshipProvider;
 
 /*
  * The superclass of anything representing a the shadow of a join point.  A shadow represents
index c99525459bafba6e829da394f62c230279d0fbaa..c69589b29e6d9c3d5b10f657f26b8203445c1174 100644 (file)
@@ -25,6 +25,7 @@ import org.aspectj.asm.internal.ProgramElement;
 import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.bridge.SourceLocation;
 import org.aspectj.util.PartialOrder;
+import org.aspectj.weaver.model.AsmRelationshipUtils;
 import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
 import org.aspectj.weaver.patterns.PerClause;
 import org.aspectj.weaver.patterns.Pointcut;
index 1b0b82a8aadc2bc843a0da5493a34901415b12b5..372dcb73522c08f4c61a5071c1ae6d2a91bf8557 100644 (file)
@@ -61,7 +61,6 @@ import org.aspectj.util.PartialOrder;
 import org.aspectj.weaver.AjAttribute;
 import org.aspectj.weaver.AjcMemberMaker;
 import org.aspectj.weaver.AnnotationAJ;
-import org.aspectj.weaver.AsmRelationshipProvider;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ConcreteTypeMunger;
 import org.aspectj.weaver.IClassWeaver;
@@ -82,6 +81,7 @@ import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.WeaverStateInfo;
 import org.aspectj.weaver.World;
+import org.aspectj.weaver.model.AsmRelationshipProvider;
 import org.aspectj.weaver.patterns.DeclareAnnotation;
 import org.aspectj.weaver.patterns.ExactTypePattern;
 import org.aspectj.weaver.tools.Trace;
index f0dee6d019e6eceaccb92582a5f638bb509cec6f..de8cf3a3c827007d5e8e01a3f164d80e2fc0ee0d 100644 (file)
@@ -41,7 +41,6 @@ import org.aspectj.bridge.context.ContextToken;
 import org.aspectj.weaver.AjcMemberMaker;
 import org.aspectj.weaver.AnnotationAJ;
 import org.aspectj.weaver.AnnotationOnTypeMunger;
-import org.aspectj.weaver.AsmRelationshipProvider;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ConcreteTypeMunger;
 import org.aspectj.weaver.Member;
@@ -63,6 +62,7 @@ import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.WeaverStateInfo;
 import org.aspectj.weaver.World;
+import org.aspectj.weaver.model.AsmRelationshipProvider;
 import org.aspectj.weaver.patterns.DeclareAnnotation;
 import org.aspectj.weaver.patterns.Pointcut;
 
index d08d8d55e868723f5b3403223e126b2df4307750..eec8b5eac2827f8eeac9770058aec40f00ee9a00 100644 (file)
@@ -56,7 +56,6 @@ import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.Advice;
 import org.aspectj.weaver.AnnotationAJ;
 import org.aspectj.weaver.AnnotationOnTypeMunger;
-import org.aspectj.weaver.AsmRelationshipProvider;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ConcreteTypeMunger;
 import org.aspectj.weaver.CrosscuttingMembersSet;
@@ -74,6 +73,7 @@ import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.WeaverStateInfo;
 import org.aspectj.weaver.World;
+import org.aspectj.weaver.model.AsmRelationshipProvider;
 import org.aspectj.weaver.patterns.AndPointcut;
 import org.aspectj.weaver.patterns.BindingPattern;
 import org.aspectj.weaver.patterns.BindingTypePattern;
diff --git a/weaver/src/org/aspectj/weaver/model/AsmRelationshipProvider.java b/weaver/src/org/aspectj/weaver/model/AsmRelationshipProvider.java
new file mode 100644 (file)
index 0000000..9d10f0a
--- /dev/null
@@ -0,0 +1,500 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.weaver.model;
+
+import java.util.Iterator;
+
+import org.aspectj.asm.AsmManager;
+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.ProgramElement;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.SourceLocation;
+import org.aspectj.weaver.Advice;
+import org.aspectj.weaver.AdviceKind;
+import org.aspectj.weaver.Checker;
+import org.aspectj.weaver.Lint;
+import org.aspectj.weaver.Member;
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.ResolvedTypeMunger;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.ShadowMunger;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.Lint.Kind;
+
+public class AsmRelationshipProvider {
+
+       protected static AsmRelationshipProvider INSTANCE = new AsmRelationshipProvider();
+
+       public static final String ADVISES = "advises";
+       public static final String ADVISED_BY = "advised by";
+       public static final String DECLARES_ON = "declares on";
+       public static final String DECLAREDY_BY = "declared by";
+       public static final String SOFTENS = "softens";
+       public static final String SOFTENED_BY = "softened by";
+       public static final String MATCHED_BY = "matched by";
+       public static final String MATCHES_DECLARE = "matches declare";
+       public static final String INTER_TYPE_DECLARES = "declared on";
+       public static final String INTER_TYPE_DECLARED_BY = "aspect declarations";
+
+       public static final String ANNOTATES = "annotates";
+       public static final String ANNOTATED_BY = "annotated by";
+
+       public void checkerMunger(AsmManager asm, Shadow shadow, Checker checker) {
+               if (asm == null) // !AsmManager.isCreatingModel())
+                       return;
+               if (shadow.getSourceLocation() == null || checker.getSourceLocation() == null)
+                       return;
+
+               if (World.createInjarHierarchy) {
+                       checker.createHierarchy(asm);
+               }
+
+               // Ensure a node for the target exists
+               IProgramElement targetNode = getNode(asm, shadow);
+               if (targetNode == null)
+                       return;
+               String targetHandle = asm.getHandleProvider().createHandleIdentifier(targetNode);
+               if (targetHandle == null)
+                       return;
+
+               IProgramElement sourceNode = asm.getHierarchy().findElementForSourceLine(checker.getSourceLocation());
+               String sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
+               if (sourceHandle == null)
+                       return;
+
+               IRelationshipMap mapper = asm.getRelationshipMap();
+               IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE, MATCHED_BY, false, true);
+               foreward.addTarget(targetHandle);
+
+               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE, MATCHES_DECLARE, false, true);
+               if (back != null && back.getTargets() != null) {
+                       back.addTarget(sourceHandle);
+               }
+               if (sourceNode.getSourceLocation() != null) {
+                       asm.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
+               }
+
+       }
+
+       // For ITDs
+       public void addRelationship(AsmManager asm, ResolvedType onType, ResolvedTypeMunger munger, ResolvedType originatingAspect) {
+
+               if (asm == null)// !AsmManager.isCreatingModel())
+                       return;
+               if (originatingAspect.getSourceLocation() != null) {
+                       String sourceHandle = "";
+                       IProgramElement sourceNode = null;
+                       if (munger.getSourceLocation() != null && munger.getSourceLocation().getOffset() != -1) {
+                               sourceNode = asm.getHierarchy().findElementForSourceLine(munger.getSourceLocation());
+                               sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
+                       } else {
+                               sourceNode = asm.getHierarchy().findElementForSourceLine(originatingAspect.getSourceLocation());
+                               sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
+                       }
+                       if (sourceHandle == null)
+                               return;
+                       IProgramElement targetNode = asm.getHierarchy().findElementForSourceLine(onType.getSourceLocation());
+                       String targetHandle = asm.getHandleProvider().createHandleIdentifier(targetNode);
+                       if (targetHandle == null)
+                               return;
+
+                       IRelationshipMap mapper = asm.getRelationshipMap();
+                       IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARES, false,
+                                       true);
+                       foreward.addTarget(targetHandle);
+
+                       IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARED_BY, false,
+                                       true);
+                       back.addTarget(sourceHandle);
+                       asm.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
+               }
+       }
+
+       // public void addDeclareParentsRelationship(ISourceLocation decp,
+       // ResolvedType targetType, List newParents) {
+       // if (!AsmManager.isCreatingModel())
+       // return;
+       //
+       // IProgramElement sourceNode =
+       // AsmManager.getDefault().getHierarchy().findElementForSourceLine(decp);
+       // String sourceHandle =
+       // AsmManager.getDefault().getHandleProvider().createHandleIdentifier
+       // (sourceNode);
+       // if (sourceHandle == null)
+       // return;
+       //
+       // IProgramElement targetNode = AsmManager.getDefault().getHierarchy()
+       // .findElementForSourceLine(targetType.getSourceLocation());
+       // String targetHandle =
+       // AsmManager.getDefault().getHandleProvider().createHandleIdentifier
+       // (targetNode);
+       // if (targetHandle == null)
+       // return;
+       //
+       // IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap();
+       // IRelationship foreward = mapper.get(sourceHandle,
+       // IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARES, false, true);
+       // foreward.addTarget(targetHandle);
+       //
+       // IRelationship back = mapper.get(targetHandle,
+       // IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARED_BY, false,
+       // true);
+       // back.addTarget(sourceHandle);
+       // }
+
+       /**
+        * Adds a declare annotation relationship, sometimes entities don't have source locs (methods/fields) so use other variants of
+        * this method if that is the case as they will look the entities up in the structure model.
+        */
+       public void addDeclareAnnotationRelationship(AsmManager asm, ISourceLocation declareAnnotationLocation,
+                       ISourceLocation annotatedLocation) {
+               if (asm == null) // !AsmManager.isCreatingModel())
+                       return;
+
+               IProgramElement sourceNode = asm.getHierarchy().findElementForSourceLine(declareAnnotationLocation);
+               String sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
+               if (sourceHandle == null)
+                       return;
+
+               IProgramElement targetNode = asm.getHierarchy().findElementForSourceLine(annotatedLocation);
+               String targetHandle = asm.getHandleProvider().createHandleIdentifier(targetNode);
+               if (targetHandle == null)
+                       return;
+
+               IRelationshipMap mapper = asm.getRelationshipMap();
+               IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
+               foreward.addTarget(targetHandle);
+
+               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true);
+               back.addTarget(sourceHandle);
+               if (sourceNode.getSourceLocation() != null) {
+                       asm.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
+               }
+       }
+
+       public void adviceMunger(AsmManager asm, Shadow shadow, ShadowMunger munger) {
+               if (asm == null) // !AsmManager.isCreatingModel())
+                       return;
+               if (munger instanceof Advice) {
+                       Advice advice = (Advice) munger;
+
+                       if (advice.getKind().isPerEntry() || advice.getKind().isCflow()) {
+                               // TODO: might want to show these in the future
+                               return;
+                       }
+
+                       if (World.createInjarHierarchy) {
+                               munger.createHierarchy(asm);
+                       }
+
+                       IRelationshipMap mapper = asm.getRelationshipMap();
+                       IProgramElement targetNode = getNode(asm, shadow);
+                       if (targetNode == null)
+                               return;
+                       boolean runtimeTest = advice.hasDynamicTests();
+
+                       // Work out extra info to inform interested UIs !
+                       IProgramElement.ExtraInformation ai = new IProgramElement.ExtraInformation();
+
+                       String adviceHandle = advice.getHandle(asm);
+                       if (adviceHandle == null)
+                               return;
+
+                       // What kind of advice is it?
+                       // TODO: Prob a better way to do this but I just want to
+                       // get it into CVS !!!
+                       AdviceKind ak = ((Advice) munger).getKind();
+                       ai.setExtraAdviceInformation(ak.getName());
+                       IProgramElement adviceElement = asm.getHierarchy().findElementForHandle(adviceHandle);
+                       if (adviceElement != null) {
+                               adviceElement.setExtraInfo(ai);
+                       }
+                       String targetHandle = targetNode.getHandleIdentifier();
+                       if (advice.getKind().equals(AdviceKind.Softener)) {
+                               IRelationship foreward = mapper.get(adviceHandle, IRelationship.Kind.DECLARE_SOFT, SOFTENS, runtimeTest, true);
+                               if (foreward != null)
+                                       foreward.addTarget(targetHandle);// foreward.getTargets().add
+                               // (targetHandle);
+
+                               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE, SOFTENED_BY, runtimeTest, true);
+                               if (back != null)
+                                       back.addTarget(adviceHandle);// back.getTargets().add(
+                               // adviceHandle);
+                       } else {
+                               IRelationship foreward = mapper.get(adviceHandle, IRelationship.Kind.ADVICE, ADVISES, runtimeTest, true);
+                               if (foreward != null)
+                                       foreward.addTarget(targetHandle);// foreward.getTargets().add
+                               // (targetHandle);
+
+                               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.ADVICE, ADVISED_BY, runtimeTest, true);
+                               if (back != null)
+                                       back.addTarget(adviceHandle);// back.getTargets().add(
+                               // adviceHandle);
+                       }
+                       if (adviceElement.getSourceLocation() != null) {
+                               asm.addAspectInEffectThisBuild(adviceElement.getSourceLocation().getSourceFile());
+                       }
+               }
+       }
+
+       protected IProgramElement getNode(AsmManager model, Shadow shadow) {
+               Member enclosingMember = shadow.getEnclosingCodeSignature();
+
+               IProgramElement enclosingNode = lookupMember(model.getHierarchy(), enclosingMember);
+               if (enclosingNode == null) {
+                       Lint.Kind err = shadow.getIWorld().getLint().shadowNotInStructure;
+                       if (err.isEnabled()) {
+                               err.signal(shadow.toString(), shadow.getSourceLocation());
+                       }
+                       return null;
+               }
+
+               Member shadowSig = shadow.getSignature();
+               // pr235204
+               if (shadow.getKind() == Shadow.MethodCall || !shadowSig.equals(enclosingMember)) {
+                       IProgramElement bodyNode = findOrCreateCodeNode(model, enclosingNode, shadowSig, shadow);
+                       return bodyNode;
+               } else {
+                       return enclosingNode;
+               }
+       }
+
+       private boolean sourceLinesMatch(ISourceLocation loc1, ISourceLocation loc2) {
+               if (loc1.getLine() != loc2.getLine())
+                       return false;
+               return true;
+       }
+
+       /**
+        * Finds or creates a code IProgramElement for the given shadow.
+        * 
+        * The byteCodeName of the created node is set to 'shadowSig.getName() + "!" + counter', eg "println!3". The counter is the
+        * occurence count of children within the enclosingNode which have the same name. So, for example, if a method contains two
+        * System.out.println statements, the first one will have byteCodeName 'println!1' and the second will have byteCodeName
+        * 'println!2'. This is to ensure the two nodes have unique handles when the handles do not depend on sourcelocations.
+        * 
+        * Currently the shadows are examined in the sequence they appear in the source file. This means that the counters are
+        * consistent over incremental builds. All aspects are compiled up front and any new aspect created will force a full build.
+        * Moreover, if the body of the enclosingShadow is changed, then the model for this is rebuilt from scratch.
+        */
+       private IProgramElement findOrCreateCodeNode(AsmManager asm, IProgramElement enclosingNode, Member shadowSig, Shadow shadow) {
+               for (Iterator it = enclosingNode.getChildren().iterator(); it.hasNext();) {
+                       IProgramElement node = (IProgramElement) it.next();
+                       int excl = node.getBytecodeName().lastIndexOf('!');
+                       if (((excl != -1 && shadowSig.getName().equals(node.getBytecodeName().substring(0, excl))) || shadowSig.getName()
+                                       .equals(node.getBytecodeName()))
+                                       && shadowSig.getSignature().equals(node.getBytecodeSignature())
+                                       && sourceLinesMatch(node.getSourceLocation(), shadow.getSourceLocation())) {
+                               return node;
+                       }
+               }
+
+               ISourceLocation sl = shadow.getSourceLocation();
+
+               // XXX why not use shadow file? new SourceLocation(sl.getSourceFile(),
+               // sl.getLine()),
+               SourceLocation peLoc = new SourceLocation(enclosingNode.getSourceLocation().getSourceFile(), sl.getLine());
+               peLoc.setOffset(sl.getOffset());
+               IProgramElement peNode = new ProgramElement(asm, shadow.toString(), IProgramElement.Kind.CODE, peLoc, 0, null, null);
+
+               // check to see if the enclosing shadow already has children with the
+               // same name. If so we want to add a counter to the byteCodeName
+               // otherwise
+               // we wont get unique handles
+               int numberOfChildrenWithThisName = 0;
+               for (Iterator it = enclosingNode.getChildren().iterator(); it.hasNext();) {
+                       IProgramElement child = (IProgramElement) it.next();
+                       if (child.getName().equals(shadow.toString())) {
+                               numberOfChildrenWithThisName++;
+                       }
+               }
+               peNode.setBytecodeName(shadowSig.getName() + "!" + String.valueOf(numberOfChildrenWithThisName + 1));
+               peNode.setBytecodeSignature(shadowSig.getSignature());
+               enclosingNode.addChild(peNode);
+               return peNode;
+       }
+
+       protected IProgramElement lookupMember(IHierarchy model, Member member) {
+               UnresolvedType declaringType = member.getDeclaringType();
+               IProgramElement classNode = model.findElementForType(declaringType.getPackageName(), declaringType.getClassName());
+               return findMemberInClass(classNode, member);
+       }
+
+       protected IProgramElement findMemberInClass(IProgramElement classNode, Member member) {
+               if (classNode == null)
+                       return null; // XXX remove this check
+               for (Iterator it = classNode.getChildren().iterator(); it.hasNext();) {
+                       IProgramElement node = (IProgramElement) it.next();
+                       if (member.getName().equals(node.getBytecodeName()) && member.getSignature().equals(node.getBytecodeSignature())) {
+                               return node;
+                       }
+               }
+               // if we can't find the member, we'll just put it in the class
+               return classNode;
+       }
+
+       // private static IProgramElement.Kind genShadowKind(Shadow shadow) {
+       // IProgramElement.Kind shadowKind;
+       // if (shadow.getKind() == Shadow.MethodCall
+       // || shadow.getKind() == Shadow.ConstructorCall
+       // || shadow.getKind() == Shadow.FieldGet
+       // || shadow.getKind() == Shadow.FieldSet
+       // || shadow.getKind() == Shadow.ExceptionHandler) {
+       // return IProgramElement.Kind.CODE;
+       //                      
+       // } else if (shadow.getKind() == Shadow.MethodExecution) {
+       // return IProgramElement.Kind.METHOD;
+       //                      
+       // } else if (shadow.getKind() == Shadow.ConstructorExecution) {
+       // return IProgramElement.Kind.CONSTRUCTOR;
+       //                      
+       // } else if (shadow.getKind() == Shadow.PreInitialization
+       // || shadow.getKind() == Shadow.Initialization) {
+       // return IProgramElement.Kind.CLASS;
+       //                      
+       // } else if (shadow.getKind() == Shadow.AdviceExecution) {
+       // return IProgramElement.Kind.ADVICE;
+       //                      
+       // } else {
+       // return IProgramElement.Kind.ERROR;
+       // }
+       // }
+
+       public static AsmRelationshipProvider getDefault() {
+               return INSTANCE;
+       }
+
+       /**
+        * Add a relationship to the known set for a declare @method/@constructor construct. Locating the method is a messy (for messy
+        * read 'fragile') bit of code that could break at any moment but it's working for my simple testcase. Currently just fails
+        * silently if any of the lookup code doesn't find anything...
+        * 
+        * @param hierarchy
+        */
+       public void addDeclareAnnotationMethodRelationship(ISourceLocation sourceLocation, String typename, ResolvedMember method,
+                       AsmManager structureModel) {
+               if (structureModel == null) // !AsmManager.isCreatingModel())
+                       return;
+
+               String pkg = null;
+               String type = typename;
+               int packageSeparator = typename.lastIndexOf(".");
+               if (packageSeparator != -1) {
+                       pkg = typename.substring(0, packageSeparator);
+                       type = typename.substring(packageSeparator + 1);
+               }
+
+               IHierarchy hierarchy = structureModel.getHierarchy();
+
+               IProgramElement typeElem = hierarchy.findElementForType(pkg, type);
+               if (typeElem == null)
+                       return;
+
+               StringBuffer parmString = new StringBuffer("(");
+               UnresolvedType[] args = method.getParameterTypes();
+               // Type[] args = method.getArgumentTypes();
+               for (int i = 0; i < args.length; i++) {
+                       String s = args[i].getName();// Utility.signatureToString(args[i].
+                       // getName()getSignature(), false);
+                       parmString.append(s);
+                       if ((i + 1) < args.length)
+                               parmString.append(",");
+               }
+               parmString.append(")");
+               IProgramElement methodElem = null;
+
+               if (method.getName().startsWith("<init>")) {
+                       // its a ctor
+                       methodElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.CONSTRUCTOR, type + parmString);
+                       if (methodElem == null && args.length == 0)
+                               methodElem = typeElem; // assume default ctor
+               } else {
+                       // its a method
+                       methodElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.METHOD, method.getName() + parmString);
+               }
+
+               if (methodElem == null)
+                       return;
+
+               try {
+                       String targetHandle = methodElem.getHandleIdentifier();
+                       if (targetHandle == null)
+                               return;
+
+                       IProgramElement sourceNode = hierarchy.findElementForSourceLine(sourceLocation);
+                       String sourceHandle = structureModel.getHandleProvider().createHandleIdentifier(sourceNode);
+                       if (sourceHandle == null)
+                               return;
+
+                       IRelationshipMap mapper = structureModel.getRelationshipMap();
+                       IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
+                       foreward.addTarget(targetHandle);
+
+                       IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true);
+                       back.addTarget(sourceHandle);
+               } catch (Throwable t) { // I'm worried about that code above, this will
+                       // make sure we don't explode if it plays up
+                       t.printStackTrace(); // I know I know .. but I don't want to lose
+                       // it!
+               }
+       }
+
+       /**
+        * Add a relationship to the known set for a declare @field construct. Locating the field is trickier than it might seem since
+        * we have no line number info for it, we have to dig through the structure model under the fields' type in order to locate it.
+        * Currently just fails silently if any of the lookup code doesn't find anything...
+        */
+       public void addDeclareAnnotationFieldRelationship(AsmManager asm, ISourceLocation sourceLocation, String typename,
+                       ResolvedMember field) {
+               if (asm == null) // !AsmManager.isCreatingModel())
+                       return;
+
+               String pkg = null;
+               String type = typename;
+               int packageSeparator = typename.lastIndexOf(".");
+               if (packageSeparator != -1) {
+                       pkg = typename.substring(0, packageSeparator);
+                       type = typename.substring(packageSeparator + 1);
+               }
+               IHierarchy hierarchy = asm.getHierarchy();
+               IProgramElement typeElem = hierarchy.findElementForType(pkg, type);
+               if (typeElem == null)
+                       return;
+
+               IProgramElement fieldElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.FIELD, field.getName());
+               if (fieldElem == null)
+                       return;
+
+               String targetHandle = fieldElem.getHandleIdentifier();
+               if (targetHandle == null)
+                       return;
+
+               IProgramElement sourceNode = hierarchy.findElementForSourceLine(sourceLocation);
+               String sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
+               if (sourceHandle == null)
+                       return;
+
+               IRelationshipMap mapper = asm.getRelationshipMap();
+               IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
+               foreward.addTarget(targetHandle);
+
+               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true);
+               back.addTarget(sourceHandle);
+       }
+
+}
diff --git a/weaver/src/org/aspectj/weaver/model/AsmRelationshipUtils.java b/weaver/src/org/aspectj/weaver/model/AsmRelationshipUtils.java
new file mode 100644 (file)
index 0000000..f9c9f6a
--- /dev/null
@@ -0,0 +1,79 @@
+/********************************************************************
+ * 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.weaver.model;
+
+import org.aspectj.weaver.patterns.AndPointcut;
+import org.aspectj.weaver.patterns.OrPointcut;
+import org.aspectj.weaver.patterns.Pointcut;
+import org.aspectj.weaver.patterns.ReferencePointcut;
+
+/**
+ * Provides utility methods for generating details for IProgramElements used when creating the model both from source (via
+ * AsmElementFormatter.visit(..)) and when filling in the model for binary aspects (via AsmRelationshipProvider bug 145963)
+ */
+public class AsmRelationshipUtils {
+
+       // public static final String UNDEFINED="<undefined>";
+       public static final String DECLARE_PRECEDENCE = "precedence";
+       public static final String DECLARE_SOFT = "soft";
+       public static final String DECLARE_PARENTS = "parents";
+       public static final String DECLARE_WARNING = "warning";
+       public static final String DECLARE_ERROR = "error";
+       public static final String DECLARE_UNKNONWN = "<unknown declare>";
+       public static final String POINTCUT_ABSTRACT = "<abstract pointcut>";
+       public static final String POINTCUT_ANONYMOUS = "<anonymous pointcut>";
+       public static final String DOUBLE_DOTS = "..";
+       public static final int MAX_MESSAGE_LENGTH = 18;
+       public static final String DEC_LABEL = "declare";
+
+       /**
+        * Generates the declare message used in the details, for example if the declare warning statement has message
+        * "There should be no printlns" will return 'declare warning: "There should be n.."'
+        */
+       public static String genDeclareMessage(String message) {
+               int length = message.length();
+               if (length < MAX_MESSAGE_LENGTH) {
+                       return message;
+               } else {
+                       return message.substring(0, MAX_MESSAGE_LENGTH - 1) + DOUBLE_DOTS;
+               }
+       }
+
+       /**
+        * Generates the pointcut details for the given pointcut, for example an anonymous pointcut will return '<anonymous pointcut>'
+        * and a named pointcut called p() will return 'p()..'
+        */
+       public static String genPointcutDetails(Pointcut pcd) {
+               StringBuffer details = new StringBuffer();
+               if (pcd instanceof ReferencePointcut) {
+                       ReferencePointcut rp = (ReferencePointcut) pcd;
+                       details.append(rp.name).append(DOUBLE_DOTS);
+               } else if (pcd instanceof AndPointcut) {
+                       AndPointcut ap = (AndPointcut) pcd;
+                       if (ap.getLeft() instanceof ReferencePointcut) {
+                               details.append(ap.getLeft().toString()).append(DOUBLE_DOTS);
+                       } else {
+                               details.append(POINTCUT_ANONYMOUS).append(DOUBLE_DOTS);
+                       }
+               } else if (pcd instanceof OrPointcut) {
+                       OrPointcut op = (OrPointcut) pcd;
+                       if (op.getLeft() instanceof ReferencePointcut) {
+                               details.append(op.getLeft().toString()).append(DOUBLE_DOTS);
+                       } else {
+                               details.append(POINTCUT_ANONYMOUS).append(DOUBLE_DOTS);
+                       }
+               } else {
+                       details.append(POINTCUT_ANONYMOUS);
+               }
+               return details.toString();
+       }
+
+}