lastSlash = sourceFilePath.lastIndexOf('/');
}
String fileName = sourceFilePath.substring(lastSlash+1);
- IProgramElement fileNode = new ProgramElement(fileName, IProgramElement.Kind.FILE_JAVA, null);
- fileNode.setSourceLocation(new SourceLocation(new File(sourceFilePath), 1, 1));
+ IProgramElement fileNode = new ProgramElement(fileName, IProgramElement.Kind.FILE_JAVA, new SourceLocation(new File(sourceFilePath), 1, 1),0,null,null);
+ //fileNode.setSourceLocation();
fileNode.addChild(NO_STRUCTURE);
return fileNode;
}
return sourceLocation;
}
+ // not really sure why we have this setter ... how can we be in the situation where we didn't
+ // know the location when we built the node but we learned it later on?
public void setSourceLocation(ISourceLocation sourceLocation) {
- //this.sourceLocation = sourceLocation;
+// this.sourceLocation = sourceLocation;
}
public IMessage getMessage() {
--- /dev/null
+package pkg;
+
+public aspect A {
+
+ pointcut p() : execution(* *.*(..)) && !within(pkg.*);
+
+ before() : p() {
+ }
+
+}
--- /dev/null
+public class ClassForAspectPath {
+
+ public static void main(String[] args) {
+ new ClassForAspectPath().method();
+
+ }
+
+ public void method() {
+ System.out.println("blah");
+ }
+
+}
--- /dev/null
+package pkg;
+
+public aspect Deow {
+
+ declare warning : (get(* System.out) || get(* System.err)) : "There should be no printlns";
+
+}
--- /dev/null
+package pkg;
+
+public aspect Itd {
+
+ declare parents : Point extends NewClass;
+
+}
--- /dev/null
+package pkg;
+
+public class NewClass {
+
+}
TestSuite suite = new TestSuite("AspectJ 1.5.2 tests");
//$JUnit-BEGIN$
suite.addTest(Ajc152Tests.suite());
+ suite.addTest(CreatingModelForInjarTests.suite());
suite.addTest(SynchronizationTests.suite());
suite.addTest(SynchronizationTransformTests.suite());
//$JUnit-END$
--- /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.systemtest.ajc152;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.Test;
+
+import org.aspectj.asm.AsmManager;
+import org.aspectj.asm.IHierarchy;
+import org.aspectj.asm.IProgramElement;
+import org.aspectj.testing.XMLBasedAjcTestCase;
+import org.aspectj.weaver.World;
+
+public class CreatingModelForInjarTests extends org.aspectj.testing.XMLBasedAjcTestCase {
+
+ public void testAdviceAndNamedPCD() {
+ runTest("advice and deow");
+
+ // expect:
+ // - pkg {package}
+ // - A.aj (binary) {java source file}
+ // - import declarations {import reference}
+ // - A {aspect}
+ // - p {pointcut}
+ // - before {advice}
+
+ IProgramElement pkgNode = getPkgNode();
+ IProgramElement srcFile = checkChild(pkgNode,IProgramElement.Kind.FILE_JAVA,"A.aj (binary)",1);
+ checkChild(srcFile,IProgramElement.Kind.IMPORT_REFERENCE,"import declarations",-1);
+ IProgramElement aspectNode = checkChild(srcFile,IProgramElement.Kind.ASPECT,"A",-1);
+ checkChild(aspectNode,IProgramElement.Kind.POINTCUT,"p",5);
+ checkChild(aspectNode,IProgramElement.Kind.ADVICE,"before",7);
+ }
+
+ public void testDeclareWarning() {
+ runTest("advice and deow");
+
+ // expect:
+ // - pkg {package}
+ // - Deow.aj (binary) {java source file}
+ // - import declarations {import reference}
+ // - Deow {aspect}
+ // - declare warning {declare warning}
+
+ IHierarchy top = AsmManager.getDefault().getHierarchy();
+ IProgramElement dwNode = top.findElementForLabel(top.getRoot(),
+ IProgramElement.Kind.DECLARE_WARNING,
+ "declare warning: \"There should be n..\"");
+ assertNotNull("Couldn't find 'declare warning: \"There should be n..\"' " +
+ "element in the tree",dwNode);
+ assertEquals("expected 'declare warning: \"There should be n..\"'" +
+ " to be on line 5 but was on " + dwNode.getSourceLocation().getLine(),
+ 5, dwNode.getSourceLocation().getLine());
+ }
+
+ public void testNumberOfPackageNodes() {
+ runTest("advice and deow");
+ // check that the 'pkg' package node has not been added twice
+ IProgramElement root = AsmManager.getDefault().getHierarchy().getRoot();
+ List l = root.getChildren();
+ int numberOfPkgs = 0;
+ for (Iterator iter = l.iterator(); iter.hasNext();) {
+ IProgramElement element = (IProgramElement) iter.next();
+ if (element.getKind().equals(IProgramElement.Kind.PACKAGE)
+ && element.getName().equals("pkg")) {
+ numberOfPkgs++;
+ }
+ }
+ assertEquals("expected one package called 'pkg' but found " + numberOfPkgs,1,numberOfPkgs);
+ }
+
+ private IProgramElement getPkgNode() {
+ IHierarchy top = AsmManager.getDefault().getHierarchy();
+ IProgramElement pkgNode = top.findElementForLabel(top.getRoot(),
+ IProgramElement.Kind.PACKAGE,"pkg");
+ assertNotNull("Couldn't find 'pkg' element in the tree",pkgNode);
+ return pkgNode;
+ }
+
+ private IProgramElement checkChild(IProgramElement parent,
+ IProgramElement.Kind childKind,
+ String childName,
+ int childLineNumbr) {
+ List children = parent.getChildren();
+ boolean foundChild = false;
+ for (Iterator iter = children.iterator(); iter.hasNext();) {
+ IProgramElement element = (IProgramElement) iter.next();
+ if (element.getKind().equals(childKind)
+ && element.getName().equals(childName) ) {
+ foundChild = true;
+ if (childLineNumbr != -1) {
+ assertEquals("expected " + childKind.toString() + childName +
+ " to be on line " + childLineNumbr + " but was on " +
+ element.getSourceLocation().getLine(),
+ childLineNumbr, element.getSourceLocation().getLine());
+ }
+ return element;
+ }
+ }
+ assertTrue("expected " + parent.getName() + " to have child " + childName
+ + " but it did not", foundChild);
+ return null;
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ World.createInjarHierarchy = true;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ World.createInjarHierarchy = false;
+ }
+
+ // ///////////////////////////////////////
+ public static Test suite() {
+ return XMLBasedAjcTestCase.loadSuite(CreatingModelForInjarTests.class);
+ }
+
+ protected File getSpecFile() {
+ return new File("../tests/src/org/aspectj/systemtest/ajc152/injar.xml");
+ }
+}
--- /dev/null
+<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]>
+
+<!-- AspectJ v1.5.2 Tests -->
+<suite>
+
+ <ajc-test dir="bugs152/pr145963" title="advice and deow">
+ <compile files="ClassForAspectPath.java" aspectpath="adviceAndDeow.jar" options="-emacssym">
+ <message kind="warning" line="9" text="There should be no printlns"/>
+ </compile>
+ </ajc-test>
+
+
+</suite>
public ResolvedType getConcreteAspect() {
return concreteAspect;
}
+
+ public ResolvedType getResolvedDeclaringAspect() {
+ // The aspect which declares this piece of advice
+ // is 'concreteAspect' since 'declaringType' is null
+ return concreteAspect;
+ }
}
checker.getSourceLocation().getLine(),
checker.getSourceLocation().getColumn(),
checker.getSourceLocation().getOffset());
-
+
+ if (World.createInjarHierarchy) {
+ checker.createHierarchy();
+ }
+
String targetHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(
shadow.getSourceLocation().getSourceFile(),
shadow.getSourceLocation().getLine(),
package org.aspectj.weaver;
-import java.util.*;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
import org.aspectj.asm.IRelationship;
-import org.aspectj.bridge.*;
-import org.aspectj.weaver.patterns.*;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
+import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
+import org.aspectj.weaver.patterns.PerClause;
+import org.aspectj.weaver.patterns.Pointcut;
public class Checker extends ShadowMunger {
return isError;
}
+ public ResolvedType getResolvedDeclaringAspect() {
+ // The aspect which declares this deow is the declaring type
+ return getDeclaringType();
+ }
}
package org.aspectj.weaver;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
import java.util.Map;
import org.aspectj.asm.AsmManager;
+import org.aspectj.asm.IProgramElement;
+import org.aspectj.asm.internal.ProgramElement;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.util.PartialOrder;
+import org.aspectj.weaver.bcel.BcelAdvice;
+import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
import org.aspectj.weaver.patterns.PerClause;
import org.aspectj.weaver.patterns.Pointcut;
if (null == handle) {
ISourceLocation sl = getSourceLocation();
if (sl != null) {
+ if (World.createInjarHierarchy) {
+ createHierarchy();
+ }
handle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(
sl.getSourceFile(),
sl.getLine(),
sl.getColumn(),
- sl.getOffset());
+ sl.getOffset());
}
}
return handle;
* @return true if munger has to check that its exceptions can be throwned based on the shadow
*/
public abstract boolean mustCheckExceptions();
+
+ /**
+ * Returns the ResolvedType corresponding to the aspect in which this
+ * shadowMunger is declared. This is different for deow's and advice.
+ */
+ public abstract ResolvedType getResolvedDeclaringAspect();
+
+ public void createHierarchy() {
+ IProgramElement sourceFileNode = AsmManager.getDefault().getHierarchy().findElementForSourceLine(getSourceLocation());
+ if (!sourceFileNode.getKind().equals(IProgramElement.Kind.FILE_JAVA)) {
+ return;
+ }
+ String name = sourceFileNode.getName();
+ sourceFileNode.setName(name + " (binary)");
+
+ ResolvedType aspect = getResolvedDeclaringAspect();
+
+ // create package ipe if one exists....
+ IProgramElement root = AsmManager.getDefault().getHierarchy().getRoot();
+ if (aspect.getPackageName() != null) {
+ // check that there doesn't already exist a node with this name
+ IProgramElement pkgNode = AsmManager.getDefault().getHierarchy().findElementForLabel(
+ root,IProgramElement.Kind.PACKAGE,aspect.getPackageName());
+ // note packages themselves have no source location
+ if (pkgNode == null) {
+ pkgNode = new ProgramElement(
+ aspect.getPackageName(),
+ IProgramElement.Kind.PACKAGE,
+ new ArrayList());
+ root.addChild(pkgNode);
+ }
+ pkgNode.addChild(sourceFileNode);
+ } else {
+ root.addChild(sourceFileNode);
+ }
+
+ // remove the error child from the 'A.aj' node
+ if (sourceFileNode instanceof ProgramElement) {
+ IProgramElement errorNode = (IProgramElement) sourceFileNode.getChildren().get(0);
+ if (errorNode.getKind().equals(IProgramElement.Kind.ERROR)) {
+ ((ProgramElement)sourceFileNode).removeChild(errorNode);
+ }
+ }
+
+ // add and create empty import declaration ipe
+ sourceFileNode.addChild(new ProgramElement(
+ "import declarations",
+ IProgramElement.Kind.IMPORT_REFERENCE,
+ null,0,null,null));
+
+ // add and create aspect ipe
+ IProgramElement aspectNode = new ProgramElement(
+ aspect.getSimpleName(),
+ IProgramElement.Kind.ASPECT,
+ aspect.getSourceLocation(),
+ aspect.getModifiers(),
+ null,null);
+ sourceFileNode.addChild(aspectNode);
+
+ addChildNodes(aspectNode,aspect.getDeclaredPointcuts());
+
+ addChildNodes(aspectNode,aspect.getDeclaredAdvice());
+ addChildNodes(aspectNode,aspect.getDeclares());
+ }
+
+ private void addChildNodes(IProgramElement parent,ResolvedMember[] children) {
+ for (int i = 0; i < children.length; i++) {
+ ResolvedMember pcd = children[i];
+ if (pcd instanceof ResolvedPointcutDefinition) {
+ ResolvedPointcutDefinition rpcd = (ResolvedPointcutDefinition)pcd;
+ parent.addChild(new ProgramElement(
+ pcd.getName(),
+ IProgramElement.Kind.POINTCUT,
+ rpcd.getPointcut().getSourceLocation(),
+ pcd.getModifiers(),
+ null,
+ Collections.EMPTY_LIST));
+ }
+ }
+ }
+
+ private void addChildNodes(IProgramElement parent, Collection children) {
+ for (Iterator iter = children.iterator(); iter.hasNext();) {
+ Object element = (Object) iter.next();
+ if (element instanceof DeclareErrorOrWarning) {
+ DeclareErrorOrWarning decl = (DeclareErrorOrWarning)element;
+ IProgramElement deowNode = new ProgramElement(
+ decl.isError() ? "declare error" : "declare warning",
+ decl.isError() ? IProgramElement.Kind.DECLARE_ERROR : IProgramElement.Kind.DECLARE_WARNING,
+ getSourceLocation(),
+ this.getDeclaringType().getModifiers(),
+ null,null);
+ deowNode.setDetails("\"" + genDeclareMessage(decl.getMessage()) + "\"");
+ parent.addChild(deowNode);
+ } else if (element instanceof BcelAdvice) {
+ BcelAdvice advice = (BcelAdvice)element;
+ parent.addChild(new ProgramElement(
+ advice.kind.getName(),
+ IProgramElement.Kind.ADVICE,
+ getSourceLocation(),
+ advice.signature.getModifiers(),null,Collections.EMPTY_LIST));
+ }
+ }
+ }
+
+ // taken from AsmElementFormatter
+ private String genDeclareMessage(String message) {
+ int length = message.length();
+ if (length < 18) {
+ return message;
+ } else {
+ return message.substring(0, 17) + "..";
+ }
+ }
}
// to be independent of location before we can do that.
/** Should we take into account source location when comparing mungers - which may trigger full builds */
public final static boolean compareLocations = true;
-
+
+ // see pr145963
+ /** Should we create the hierarchy for binary classes and aspects*/
+ public static boolean createInjarHierarchy = true;
/** Calculator for working out aspect precedence */
private AspectPrecedenceCalculator precedenceCalculator;