+++ /dev/null
-/* *******************************************************************
- * 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);
- }
-
-}
+++ /dev/null
-/********************************************************************
- * 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();
- }
-
-}
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;
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
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;
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;
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;
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;
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;
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;
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;
--- /dev/null
+/* *******************************************************************
+ * 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);
+ }
+
+}
--- /dev/null
+/********************************************************************
+ * 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();
+ }
+
+}