From: aclement Date: Fri, 13 Jan 2006 17:07:57 +0000 (+0000) Subject: more ajdoc changes - see pr121711 - from Helen. X-Git-Tag: POST_MEMORY_CHANGES~189 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=dd1203a376d6b0dcc865735cf50288a83e710b05;p=aspectj.git more ajdoc changes - see pr121711 - from Helen. --- diff --git a/ajdoc/src/org/aspectj/tools/ajdoc/HtmlDecorator.java b/ajdoc/src/org/aspectj/tools/ajdoc/HtmlDecorator.java index db148e599..ba68dc299 100644 --- a/ajdoc/src/org/aspectj/tools/ajdoc/HtmlDecorator.java +++ b/ajdoc/src/org/aspectj/tools/ajdoc/HtmlDecorator.java @@ -15,6 +15,7 @@ package org.aspectj.tools.ajdoc; import java.io.BufferedReader; +import java.io.DataInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; @@ -29,6 +30,7 @@ import java.util.StringTokenizer; import org.aspectj.asm.AsmManager; import org.aspectj.asm.IProgramElement; import org.aspectj.asm.IRelationship; +import org.aspectj.util.TypeSafeEnum; /** * @author Mik Kersten @@ -226,7 +228,7 @@ class HtmlDecorator { int secondClassStartIndex = fileContents.toString().indexOf("class "); if (secondClassStartIndex != -1) { String name = decl.toSignatureString(); - int classEndIndex = fileContents.indexOf(name + "
"); + int classEndIndex = fileContents.indexOf(name + "
"); if (secondClassStartIndex != -1 && classEndIndex != -1) { StringBuffer sb = new StringBuffer(fileContents.toString(). substring(secondClassStartIndex,classEndIndex)); @@ -283,6 +285,21 @@ class HtmlDecorator { insertDeclarationsSummary(fileBuffer, advice, ADVICE_SUMMARY, index); insertDeclarationsDetails(fileBuffer, advice, ADVICE_DETAIL, index); } + // add the 'aspect declarations' information against the type + List parentsDeclaredOn = StructureUtil.getDeclareInterTypeTargets(node, IProgramElement.Kind.DECLARE_PARENTS); + if (parentsDeclaredOn != null && parentsDeclaredOn.size() > 0) { + decorateDocWithRel(node,fileBuffer,index,parentsDeclaredOn,HtmlRelationshipKind.ASPECT_DECLARATIONS); + } + // add the 'annotated by' information against the type + List annotatedBy = StructureUtil.getTargets(node,IRelationship.Kind.DECLARE_INTER_TYPE,"annotated by"); + if (annotatedBy != null && annotatedBy.size() > 0) { + decorateDocWithRel(node,fileBuffer,index,annotatedBy,HtmlRelationshipKind.ANNOTATED_BY); + } + // add the 'advised by' information against the type + List advisedBy = StructureUtil.getTargets(node, IRelationship.Kind.ADVICE); + if (advisedBy != null && advisedBy.size() > 0) { + decorateDocWithRel(node,fileBuffer,index,advisedBy,HtmlRelationshipKind.ADVISED_BY); + } } // static void addIntroductionDocumentation(IProgramElement decl, @@ -335,7 +352,7 @@ class HtmlDecorator { entry += comment + "

"; } entry += - generateAffects(decl, false) + "" + + generateAffects(decl) + "" + "\n"; } else if ( kind.equals( POINTCUT_SUMMARY ) ) { @@ -362,7 +379,7 @@ class HtmlDecorator { "" + "" + "" + decl.toLabelString() + "

" + - generateAffects(decl, true); + generateAffects(decl); } else if ( kind.equals( ITD_FIELD_SUMMARY ) || kind.equals( ITD_METHOD_SUMMARY)) { @@ -456,7 +473,7 @@ class HtmlDecorator { "" + generateSignatures(decl) + "\n" + "

" + generateDetailsComment(decl) + "

" + - generateAffects(decl, false); + generateAffects(decl); } else if (kind.equals(POINTCUT_DETAIL)) { entry += @@ -477,7 +494,7 @@ class HtmlDecorator { if (!decl.getKind().isDeclare()) { entry += generateSignatures(decl) + "

"; } - entry += generateAffects(decl, true) + + entry += generateAffects(decl) + generateDetailsComment(decl); } @@ -530,15 +547,18 @@ class HtmlDecorator { return index; } } - - static void decorateMemberDocumentation(IProgramElement node, - StringBuffer fileContentsBuffer, - int index ) { - List targets = StructureUtil.getTargets(node, IRelationship.Kind.ADVICE); + + static void decorateDocWithRel( + IProgramElement node, + StringBuffer fileContentsBuffer, + int index, + List targets, + HtmlRelationshipKind relKind) { if (targets != null && !targets.isEmpty()) { - String adviceDoc - = "" + - "
 Advised by:"; + String adviceDoc = "" + + "
" + + relKind.toString() + + ""; String relativePackagePath = getRelativePathFromHere( @@ -546,8 +566,16 @@ class HtmlDecorator { List addedNames = new ArrayList(); for (Iterator it = targets.iterator(); it.hasNext(); ) { - String currHandle = (String)it.next(); - IProgramElement currDecl = AsmManager.getDefault().getHierarchy().findElementForHandle(currHandle); + Object o = it.next(); + IProgramElement currDecl = null; + if (o instanceof String) { + String currHandle = (String)o; + currDecl = AsmManager.getDefault().getHierarchy().findElementForHandle(currHandle); + } else if (o instanceof IProgramElement){ + currDecl = (IProgramElement)o; + } else { + return; + } String packagePath = ""; if (currDecl.getPackageName() != null && !currDecl.getPackageName().equals("")) { @@ -565,12 +593,16 @@ class HtmlDecorator { hrefName = currDecl.getPackageName().replace('.', '/'); // hrefLink = "";//+ currDecl.getPackageName() + Config.DIR_SEP_CHAR; } + // use the currDecl.toLabelString rather than currDecl.getName() + // because two distinct advice blocks can have the same + // currDecl.getName() and wouldn't both appear in the ajdoc hrefName += Config.DIR_SEP_CHAR + - currDecl.getParent().toLinkLabelString() - + "." + currDecl.getName(); + currDecl.getParent().toLinkLabelString() + + "." + currDecl.toLabelString(); + // need to replace " with quot; otherwise the links wont work hrefLink += currDecl.getParent().toLinkLabelString() + ".html" - + "#" + currDecl.toLabelString(); + + "#" + currDecl.toLabelString().replaceAll("\"","quot;"); if (!addedNames.contains(hrefName)) { adviceDoc = adviceDoc + @@ -585,6 +617,22 @@ class HtmlDecorator { fileContentsBuffer.insert( index, adviceDoc ); } } + + static void decorateMemberDocumentation(IProgramElement node, + StringBuffer fileContentsBuffer, + int index ) { + List targets = StructureUtil.getTargets(node, IRelationship.Kind.ADVICE); + decorateDocWithRel(node,fileContentsBuffer,index,targets,HtmlRelationshipKind.ADVISED_BY); + + List warnings = StructureUtil.getTargets(node,IRelationship.Kind.DECLARE,"matches declare"); + decorateDocWithRel(node,fileContentsBuffer,index,warnings,HtmlRelationshipKind.MATCHES_DECLARE); + + List softenedBy = StructureUtil.getTargets(node,IRelationship.Kind.DECLARE,"softened by"); + decorateDocWithRel(node,fileContentsBuffer,index,softenedBy,HtmlRelationshipKind.SOFTENED_BY); + + List annotatedBy = StructureUtil.getTargets(node,IRelationship.Kind.DECLARE_INTER_TYPE,"annotated by"); + decorateDocWithRel(node,fileContentsBuffer,index,annotatedBy,HtmlRelationshipKind.ANNOTATED_BY); + } /** * pr119453 - adding "declared by" relationship @@ -626,20 +674,39 @@ class HtmlDecorator { /** * TODO: probably want to make this the same for intros and advice. */ - static String generateAffects(IProgramElement decl, boolean isIntroduction) { + static String generateAffects(IProgramElement decl) { List targets = null; - if (isIntroduction) { - targets = StructureUtil.getDeclareTargets(decl); - } else { - targets = StructureUtil.getTargets(decl, IRelationship.Kind.ADVICE); - } + if (decl.getKind().isDeclare() || decl.getKind().isInterTypeMember()) { + targets = StructureUtil.getDeclareTargets(decl); + } else { + targets = StructureUtil.getTargets(decl, IRelationship.Kind.ADVICE); + } if (targets == null) return ""; String entry = ""; - if (!isIntroduction) { - entry += "") == -1)) { + int relIndex = subLine.indexOf(relationship.toString()); + int targetIndex = subLine.indexOf(target); + if ((relIndex != -1) && (targetIndex != -1)) { + reader.close(); + if (relIndex < targetIndex) { + return true; + } + return false; + } + subLine = reader.readLine(); } + reader.close(); + return false; } nextLine = reader.readLine(); } @@ -205,4 +299,5 @@ public class AjdocOutputChecker { reader.close(); return false; } + } diff --git a/ajdoc/testsrc/org/aspectj/tools/ajdoc/CoverageTestCase.java b/ajdoc/testsrc/org/aspectj/tools/ajdoc/CoverageTestCase.java index 4b57d4978..33a97d486 100644 --- a/ajdoc/testsrc/org/aspectj/tools/ajdoc/CoverageTestCase.java +++ b/ajdoc/testsrc/org/aspectj/tools/ajdoc/CoverageTestCase.java @@ -81,6 +81,35 @@ public class CoverageTestCase extends AjdocTestCase { assertTrue(htmlFile.getName() + " should not contain the private Jazz class",missing.contains("Jazz")); } + /** + * Test that the ajdoc for an aspect has the title "Aspect" + */ + public void testAJdocHasAspectTitle() throws Exception { + File[] files = {new File(getAbsoluteProjectDir() + "/pkg/A.aj")}; + runAjdoc("private","1.4",files); + File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/A.html"); + if (htmlFile == null || !htmlFile.exists()) { + fail("couldn't find " + htmlFile.getAbsolutePath()+ " - were there compilation errors?"); + } + assertTrue(htmlFile.getAbsolutePath() + " should have Aspect A as it's title", + AjdocOutputChecker.containsString(htmlFile,"Aspect A")); + } + + /** + * Test that the ajdoc for a class has the title "Class" + */ + public void testAJdocHasClassTitle() throws Exception { + File[] files = {new File(getAbsoluteProjectDir() + "/pkg/C.java")}; + runAjdoc("private","1.4",files); + File htmlFile = new File(getAbsolutePathOutdir() + "/pkg/C.html"); + if (htmlFile == null || !htmlFile.exists()) { + fail("couldn't find " + htmlFile.getAbsolutePath()+ " - were there compilation errors?"); + } + assertTrue(htmlFile.getAbsolutePath() + " should have Class C as it's title", + AjdocOutputChecker.containsString(htmlFile,"Class C")); + + } + /** * Test that the ajdoc for an inner aspect is entitled "Aspect" rather * than "Class", but that the enclosing class is still "Class" @@ -171,44 +200,50 @@ public class CoverageTestCase extends AjdocTestCase { } String[] strings = { - "before(): methodExecutionP..", - "Advises:
 Advises:"; - } else { - entry += " Declared on:"; - } + + IProgramElement.Kind kind = decl.getKind(); + if (kind.equals(IProgramElement.Kind.ADVICE)) { + entry += "" + + HtmlRelationshipKind.ADVISES.toString() + + ""; + } else if (kind.equals(IProgramElement.Kind.DECLARE_WARNING) + || kind.equals(IProgramElement.Kind.DECLARE_ERROR)) { + entry += "" + + HtmlRelationshipKind.MATCHED_BY.toString() + + ""; + } else if (kind.isDeclareAnnotation()) { + entry += "" + + HtmlRelationshipKind.ANNOTATES.toString() + + ""; + } else if (kind.equals(IProgramElement.Kind.DECLARE_SOFT)) { + entry += "" + + HtmlRelationshipKind.SOFTENS.toString() + + ""; + } else { + entry += "" + + HtmlRelationshipKind.DECLARED_ON.toString() + + ""; + } String relativePackagePath = getRelativePathFromHere( @@ -867,4 +934,48 @@ class HtmlDecorator { } return formattedComment; } + + /** + * TypeSafeEnum for the entries which need to be put in the html doc + */ + public static class HtmlRelationshipKind extends TypeSafeEnum { + + public HtmlRelationshipKind(String name, int key) { + super(name, key); + + } + + public static HtmlRelationshipKind read(DataInputStream s) throws IOException { + int key = s.readByte(); + switch(key) { + case 1: return ADVISES; + case 2: return ADVISED_BY; + case 3: return MATCHED_BY; + case 4: return MATCHES_DECLARE; + case 5: return DECLARED_ON; + case 6: return ASPECT_DECLARATIONS; + case 7: return SOFTENS; + case 8: return SOFTENED_BY; + case 9: return ANNOTATES; + case 10: return ANNOTATED_BY; + case 11: return USES_POINTCUT; + case 12: return POINTCUT_USED_BY; + } + throw new Error("weird relationship kind " + key); + } + + public static final HtmlRelationshipKind ADVISES = new HtmlRelationshipKind(" Advises:", 1); + public static final HtmlRelationshipKind ADVISED_BY = new HtmlRelationshipKind(" Advised by:", 2); + public static final HtmlRelationshipKind MATCHED_BY = new HtmlRelationshipKind(" Matched by:", 3); + public static final HtmlRelationshipKind MATCHES_DECLARE = new HtmlRelationshipKind(" Matches declare:", 4); + public static final HtmlRelationshipKind DECLARED_ON = new HtmlRelationshipKind(" Declared on:", 5); + public static final HtmlRelationshipKind ASPECT_DECLARATIONS = new HtmlRelationshipKind(" Aspect declarations:", 6); + public static final HtmlRelationshipKind SOFTENS = new HtmlRelationshipKind(" Softens:", 7); + public static final HtmlRelationshipKind SOFTENED_BY = new HtmlRelationshipKind(" Softened by:", 8); + public static final HtmlRelationshipKind ANNOTATES = new HtmlRelationshipKind(" Annotates:", 9); + public static final HtmlRelationshipKind ANNOTATED_BY = new HtmlRelationshipKind(" Annotated by:", 10); + public static final HtmlRelationshipKind USES_POINTCUT = new HtmlRelationshipKind(" Uses pointcut:", 11); + public static final HtmlRelationshipKind POINTCUT_USED_BY = new HtmlRelationshipKind(" Pointcut used by:", 12); + + } } diff --git a/ajdoc/src/org/aspectj/tools/ajdoc/StructureUtil.java b/ajdoc/src/org/aspectj/tools/ajdoc/StructureUtil.java index 42568837b..df063f2bd 100644 --- a/ajdoc/src/org/aspectj/tools/ajdoc/StructureUtil.java +++ b/ajdoc/src/org/aspectj/tools/ajdoc/StructureUtil.java @@ -25,21 +25,58 @@ import org.aspectj.asm.IRelationship; */ public class StructureUtil { - /** + * Calculate the targets for a given IProgramElement (and it's + * immediate children if its not a type or if the child is + * CODE) and relationship kind + * * @return null if a relationship of that kind is not found */ public static List /*String*/ getTargets(IProgramElement node, IRelationship.Kind kind) { - List relations = AsmManager.getDefault().getRelationshipMap().get(node); + return getTargets(node,kind,null); + } + + /** + * Calculate the targets for a given IProgramElement (and it's immediate + * children if its not a type or if the child is CODE) and relationship + * kind with the specified relationship name. + * + * @return null if a relationship of that kind is not found + */ + public static List /*String*/ getTargets(IProgramElement node, IRelationship.Kind kind, String relName) { + List relations = AsmManager.getDefault().getRelationshipMap().get(node); + for (Iterator iter = node.getChildren().iterator(); iter.hasNext();) { + IProgramElement child = (IProgramElement) iter.next(); + // if we're not a type, or if we are and the child is code, then + // we want to get the relationships for this child - this means that the + // correct relationships appear against the type in the ajdoc + if (!node.getKind().isType() + || child.getKind().equals(IProgramElement.Kind.CODE) ) { + List childRelations = AsmManager.getDefault().getRelationshipMap().get(child); + if (childRelations != null) { + if (relations == null) { + relations = childRelations; + } else { + relations.addAll(childRelations); + } + } + } + } List targets = null; - if (relations == null) return null; + if (relations == null || relations.isEmpty()) return null; for (Iterator it = relations.iterator(); it.hasNext(); ) { IRelationship rtn = (IRelationship)it.next(); - if (rtn.getKind().equals(kind)) { - targets = rtn.getTargets(); + if (rtn.getKind().equals(kind) + && ((relName != null && relName.equals(rtn.getName())) + || relName == null)){ + if (targets == null) { + targets = rtn.getTargets(); + } else { + targets.addAll(rtn.getTargets()); + } } } - return targets; + return targets; } static List /*IProgramElement */ getDeclareInterTypeTargets(IProgramElement node, IProgramElement.Kind kind) { diff --git a/ajdoc/testdata/coverage/foo/ModelCoverage.java b/ajdoc/testdata/coverage/foo/ModelCoverage.java index b05d7bc72..695026642 100644 --- a/ajdoc/testdata/coverage/foo/ModelCoverage.java +++ b/ajdoc/testdata/coverage/foo/ModelCoverage.java @@ -6,6 +6,10 @@ import java.util.List; interface I { } +/** + * doc about the Point class........ + * + */ class Point { int x; static int sx; @@ -28,7 +32,8 @@ class Point { } public int changeX(int x) { - this.x = x; + //this.x = x; + setX(x); return x; } diff --git a/ajdoc/testdata/coverage/pkg/A.aj b/ajdoc/testdata/coverage/pkg/A.aj new file mode 100644 index 000000000..7c720c670 --- /dev/null +++ b/ajdoc/testdata/coverage/pkg/A.aj @@ -0,0 +1,5 @@ +package pkg; + +public aspect A { + +} diff --git a/ajdoc/testdata/coverage/pkg/A2.aj b/ajdoc/testdata/coverage/pkg/A2.aj new file mode 100644 index 000000000..4f876dc65 --- /dev/null +++ b/ajdoc/testdata/coverage/pkg/A2.aj @@ -0,0 +1,20 @@ +package pkg; + +public aspect A2 { + + pointcut p() : execution(* C2.amethod(..)); + pointcut p2() : execution(* C2.amethod(..)); + + before() : p() { + } + + before() : p2() { + } + +} + +class C2 { + + public void amethod() { + } +} diff --git a/ajdoc/testdata/coverage/pkg/C.java b/ajdoc/testdata/coverage/pkg/C.java new file mode 100644 index 000000000..e817b5163 --- /dev/null +++ b/ajdoc/testdata/coverage/pkg/C.java @@ -0,0 +1,5 @@ +package pkg; + +public class C { + +} diff --git a/ajdoc/testdata/declareForms/A.aj b/ajdoc/testdata/declareForms/A.aj new file mode 100644 index 000000000..947d9d2cb --- /dev/null +++ b/ajdoc/testdata/declareForms/A.aj @@ -0,0 +1,19 @@ +package foo; + +public aspect A { + + pointcut p() : execution(* C.amethod(..)); + + declare warning : p() : "warning"; + + before() : p() { + } + +} + +class C { + + public void amethod() { + } + +} diff --git a/ajdoc/testdata/declareForms/AnnotationTest.aj b/ajdoc/testdata/declareForms/AnnotationTest.aj deleted file mode 100644 index 28a72736a..000000000 --- a/ajdoc/testdata/declareForms/AnnotationTest.aj +++ /dev/null @@ -1,14 +0,0 @@ -package foo; - -@interface MyAnnotation { -} - -public aspect AnnotationTest { - - declare @type : C : @MyAnnotation; - -} - -class C { - -} diff --git a/ajdoc/testdata/declareForms/DeclareAtConstructor.aj b/ajdoc/testdata/declareForms/DeclareAtConstructor.aj new file mode 100644 index 000000000..1d43cac39 --- /dev/null +++ b/ajdoc/testdata/declareForms/DeclareAtConstructor.aj @@ -0,0 +1,17 @@ +package foo; + +@interface MyAnnotation { +} + +public aspect DeclareAtConstructor { + + declare @constructor : C.new(..) : @MyAnnotation; + +} + +class C { + + public C(String s) { + } + +} diff --git a/ajdoc/testdata/declareForms/DeclareAtField.aj b/ajdoc/testdata/declareForms/DeclareAtField.aj new file mode 100644 index 000000000..ea5230a86 --- /dev/null +++ b/ajdoc/testdata/declareForms/DeclareAtField.aj @@ -0,0 +1,16 @@ +package foo; + +@interface MyAnnotation { +} + +public aspect DeclareAtField { + + declare @field : int C.* : @MyAnnotation; + +} + +class C { + + int x = 1; + +} diff --git a/ajdoc/testdata/declareForms/DeclareAtMethod.aj b/ajdoc/testdata/declareForms/DeclareAtMethod.aj new file mode 100644 index 000000000..2dc6ca739 --- /dev/null +++ b/ajdoc/testdata/declareForms/DeclareAtMethod.aj @@ -0,0 +1,17 @@ +package foo; + +@interface MyAnnotation { +} + +public aspect DeclareAtMethod { + + declare @method : public * C.*(..) : @MyAnnotation; + +} + +class C { + + public void amethod() { + } + +} diff --git a/ajdoc/testdata/declareForms/DeclareAtType.aj b/ajdoc/testdata/declareForms/DeclareAtType.aj new file mode 100644 index 000000000..44f60b633 --- /dev/null +++ b/ajdoc/testdata/declareForms/DeclareAtType.aj @@ -0,0 +1,14 @@ +package foo; + +@interface MyAnnotation { +} + +public aspect DeclareAtType { + + declare @type : C : @MyAnnotation; + +} + +class C { + +} diff --git a/ajdoc/testdata/declareForms/DeclareCoverage2.aj b/ajdoc/testdata/declareForms/DeclareCoverage2.aj index 6300298e9..1ea6b6322 100644 --- a/ajdoc/testdata/declareForms/DeclareCoverage2.aj +++ b/ajdoc/testdata/declareForms/DeclareCoverage2.aj @@ -2,20 +2,23 @@ package foo; public aspect DeclareCoverage2 { - pointcut illegalNewFigElt(): call(Point.new(..)) && !withincode(* *.doIt(..)); + pointcut illegalNewFigElt(): call(Point2.new(..)) && !withincode(* *.doIt(..)); declare error: illegalNewFigElt(): "Illegal constructor call."; - declare warning: call(* Point.setX(..)): "Illegal call."; + declare warning: call(* Point2.setX(..)): "Illegal call."; + declare warning : execution(* Point2.setX(..)) : "blah"; - declare parents: Point extends java.io.Serializable; - declare parents: Line implements java.util.Observable; - declare soft: SizeException : call(* Point.getX()); - declare precedence: DeclareCoverage2, InterTypeDecCoverage, *; + declare parents: Point2 implements java.io.Serializable; + declare soft: SizeException2 : call(* Point2.getX()); + declare precedence: DeclareCoverage2, InterTypeDecCoverage2, *; } -aspect InterTypeDecCoverage {} +aspect InterTypeDecCoverage2 {} -class Point { +/** + * comment about class Point2 + */ +class Point2 { int x = 2; public void setX(int x) { @@ -27,18 +30,18 @@ class Point { } } -class Line { +class Line2 { } -class SizeException extends Throwable { } +class SizeException2 extends Throwable { } -class Main { +class Main2 { public static void main(String[] args) { } public void doIt() { - Point p = new Point(); + Point2 p = new Point2(); p.setX(3); p.getX(); } diff --git a/ajdoc/testdata/declareForms/DeclareParents.aj b/ajdoc/testdata/declareForms/DeclareParents.aj new file mode 100644 index 000000000..c86784690 --- /dev/null +++ b/ajdoc/testdata/declareForms/DeclareParents.aj @@ -0,0 +1,12 @@ +package foo; + +public aspect DeclareParents { + declare parents: Class1 implements java.io.Serializable; + declare parents: Class2 extends java.util.Observable; +} + +class Class1 { +} + +class Class2 { +} diff --git a/ajdoc/testdata/pr119453/src/pack/A.aj b/ajdoc/testdata/pr119453/src/pack/A.aj index 21517b07f..1741b6165 100644 --- a/ajdoc/testdata/pr119453/src/pack/A.aj +++ b/ajdoc/testdata/pr119453/src/pack/A.aj @@ -18,4 +18,7 @@ public aspect A { before() : p() { } + pointcut p1() : execution(public String C.method1(..)); + after() returning : p1() { + } } diff --git a/ajdoc/testsrc/org/aspectj/tools/ajdoc/AjdocOutputChecker.java b/ajdoc/testsrc/org/aspectj/tools/ajdoc/AjdocOutputChecker.java index 0022265e1..d46b2a4af 100644 --- a/ajdoc/testsrc/org/aspectj/tools/ajdoc/AjdocOutputChecker.java +++ b/ajdoc/testsrc/org/aspectj/tools/ajdoc/AjdocOutputChecker.java @@ -130,31 +130,104 @@ public class AjdocOutputChecker { } return missingStrings; } + + /** + * Returns whether the class data section has the expected + * relationship and target i.e. have the relationships been + * applied to the type. + * + * @param the ajdoc html file + * @param the detail sectionHeader, for example "DECLARE DETAIL SUMMARY" + * @param the source of the relationship, for example "Point()" + * @param the relationship, for example HtmlDecorator.HtmlRelationshipKind.MATCHED_BY + * @param the expected target, for example "HREF=\"../foo/Main.html#doIt()\"" + * @return true if the section contains the expected source/relationship/target, + * false otherwise + */ + public static boolean classDataSectionContainsRel(File htmlFile, + HtmlDecorator.HtmlRelationshipKind relationship, + String target) throws Exception { + if (((htmlFile == null) || !htmlFile.getAbsolutePath().endsWith("html"))) { + return false; + } + BufferedReader reader = new BufferedReader(new FileReader(htmlFile)); + String line = reader.readLine(); + while (line != null) { + if (line.indexOf("START OF CLASS DATA") != -1) { + // found the required class data section + String subLine = reader.readLine(); + while(subLine != null + && (subLine.indexOf("========") == -1)){ + int relIndex = subLine.indexOf(relationship.toString()); + int targetIndex = subLine.indexOf(target); + if ((relIndex != -1) && (targetIndex != -1)) { + reader.close(); + if (relIndex < targetIndex) { + return true; + } + return false; + } + subLine = reader.readLine(); + } + reader.close(); + return false; + } + line = reader.readLine(); + } + reader.close(); + return false; + } /** - * Checks whether the given strings appear one after the other in the - * ajdoc html file + * Returns whether the supplied source has the expected + * relationship and target within the given detail section * - * @param htmlFile - * @param firstString - * @param secondString expected to follow the firstString - * @return true if secondString appears after firstString, false otherwise - * @throws Exception + * @param the ajdoc html file + * @param the detail sectionHeader, for example "DECLARE DETAIL SUMMARY" + * @param the source of the relationship, for example "Point()" + * @param the relationship, for example HtmlDecorator.HtmlRelationshipKind.MATCHED_BY + * @param the expected target, for example "HREF=\"../foo/Main.html#doIt()\"" + * @return true if the section contains the expected source/relationship/target, + * false otherwise */ - public static boolean fileContainsConsecutiveStrings(File htmlFile, - String firstString, String secondString ) throws Exception { - if ((htmlFile == null) || !htmlFile.getAbsolutePath().endsWith("html")) { + public static boolean detailSectionContainsRel(File htmlFile, + String sectionHeader, String source, + HtmlDecorator.HtmlRelationshipKind relationship, + String target) throws Exception { + if (((htmlFile == null) || !htmlFile.getAbsolutePath().endsWith("html"))) { + return false; + } + if (sectionHeader.indexOf("DETAIL") == -1) { return false; } BufferedReader reader = new BufferedReader(new FileReader(htmlFile)); String line = reader.readLine(); while (line != null) { - if (line.indexOf(firstString) != -1) { - if ( (line.indexOf(secondString) != -1 - && line.indexOf(secondString) > line.indexOf(firstString)) - || reader.readLine().indexOf(secondString) != -1) { - reader.close(); - return true; + if (line.indexOf(sectionHeader) != -1) { + // found the required main section + String nextLine = reader.readLine(); + while (nextLine != null && (nextLine.indexOf("========") == -1)) { + if (nextLine.indexOf("NAME=\""+source+"\"") != -1) { + // found the required subsection + String subLine = reader.readLine(); + while(subLine != null + && (subLine.indexOf("========") == -1) + && (subLine.indexOf("NAME") == -1)) { + int relIndex = subLine.indexOf(relationship.toString()); + int targetIndex = subLine.indexOf(target); + if ((relIndex != -1) && (targetIndex != -1)) { + reader.close(); + if (relIndex < targetIndex) { + return true; + } + return false; + } + subLine = reader.readLine(); + } + reader.close(); + return false; + } + nextLine = reader.readLine(); } reader.close(); return false; @@ -164,36 +237,57 @@ public class AjdocOutputChecker { reader.close(); return false; } - + /** - * Checks whether the given strings appear one after the other in the - * given section of the ajdoc html file + * Returns whether the supplied source has the expected + * relationship and target within the given summary section * - * @param htmlFile - * @param firstString - * @param secondString expected to follow the firstString - * @param sectionHeader - * @return true if secondString appears after firstString, false otherwise - * @throws Exception + * @param the ajdoc html file + * @param the detail sectionHeader, for example "DECLARE SUMMARY" + * @param the source of the relationship, for example "Point()" + * @param the relationship, for example HtmlDecorator.HtmlRelationshipKind.MATCHED_BY + * @param the expected target, for example "HREF=\"../foo/Main.html#doIt()\"" + * @return true if the section contains the expected source/relationship/target, + * false otherwise */ - public static boolean sectionContainsConsecutiveStrings(File htmlFile, - String firstString, String secondString, String sectionHeader) throws Exception { + public static boolean summarySectionContainsRel( + File htmlFile, + String sectionHeader, + String source, + HtmlDecorator.HtmlRelationshipKind relationship, + String target) throws Exception { if (((htmlFile == null) || !htmlFile.getAbsolutePath().endsWith("html"))) { return false; } + if (sectionHeader.indexOf("SUMMARY") == -1) { + return false; + } BufferedReader reader = new BufferedReader(new FileReader(htmlFile)); String line = reader.readLine(); while (line != null) { if (line.indexOf(sectionHeader) != -1) { + // found the required main section String nextLine = reader.readLine(); while (nextLine != null && (nextLine.indexOf("========") == -1)) { - if (nextLine.indexOf(firstString) != -1) { - if ( (nextLine.indexOf(secondString) != -1 - && nextLine.indexOf(secondString) > nextLine.indexOf(firstString)) - || reader.readLine().indexOf(secondString) != -1) { - reader.close(); - return true; + if (nextLine.indexOf(source) != -1) { + // found the required subsection + String subLine = nextLine; + while(subLine != null + && (subLine.indexOf("========") == -1) + && (subLine.indexOf("
before(): constructorExecutionP..", - "Advises:before(): callConstructorP..", - "Advises:before(): getP..", - "Advises:before(): setP..", - "Advises:foo.Point, foo.Point.Point(), foo.Point.setX, before(): initializationP..", - "Advises:before(): staticinitializationP..", - "Advises:before(): handlerP..", - "Advises:foo.Point, foo.Point.Point(), C.y", + "public C.C", + "package void"}; + List missing = AjdocOutputChecker.getMissingStringsInSection(htmlA,stringsA,"DECLARE DETAIL SUMMARY"); + assertEquals("There should be one missing string ",1,missing.size()); + assertEquals("the 'package' and 'void' modifiers shouldn't appear in the 'Declare Detail' section of the ajdoc", + "package void", missing.get(0)); + + // check the modifiers are correct in the declare summary + String[] stringsA2 = {"private", "int", "public", "String", "package void"}; + missing = AjdocOutputChecker.getMissingStringsInSection(htmlA,stringsA2,"DECLARE SUMMARY"); + assertEquals("There should be two missing strings ",2,missing.size()); + assertTrue("the public modifier shouldn't appear in the 'Declare Summary' section of the ajdoc", missing.contains("public")); + assertTrue("the 'package' and 'void' modifiers shouldn't appear in the 'Declare Summary' section of the ajdoc", missing.contains("package void")); + + } /** * Test for pr119453 */ - public void testITDShownInDoc() throws Exception { + public void testITDMatchesDeclare() throws Exception { initialiseProject("pr119453"); File[] files = { new File(getAbsoluteProjectDir() + "/src/pack/C.java"), @@ -32,9 +83,7 @@ public class ITDTest extends AjdocTestCase { fail("couldn't find " + getAbsolutePathOutdir() + "/pack/C.html - were there compilation errors?"); } - // check that C is a class - assertTrue(htmlC.getAbsolutePath() + " should have Class C as it's title", - AjdocOutputChecker.containsString(htmlC,"Class C")); + // check that the required sections exist assertTrue(htmlC.getAbsolutePath() + " should contain an " + "'INTER-TYPE METHOD SUMMARY' section", @@ -46,7 +95,7 @@ public class ITDTest extends AjdocTestCase { + "'INTER-TYPE CONSTRUCTOR SUMMARY' section", AjdocOutputChecker.containsString(htmlC,"INTER-TYPE CONSTRUCTOR SUMMARY")); - // check the contents of the sections is correct + // check the modifier information in the sections is correct String[] stringsC = { "public", "String", "pack.A" }; List missing = AjdocOutputChecker.getMissingStringsInSection(htmlC,stringsC,"INTER-TYPE METHOD SUMMARY"); assertEquals("There should be one missing string",1,missing.size()); @@ -56,33 +105,33 @@ public class ITDTest extends AjdocTestCase { String[] stringsC2 = { "private" }; missing = AjdocOutputChecker.getMissingStringsInSection(htmlC,stringsC2,"INTER-TYPE FIELD SUMMARY"); assertTrue("the private modifier for itd methods should appear in the ajdoc ",missing.size() == 0); - - // check the contents of A.html - File htmlA = new File(getAbsolutePathOutdir() + "/pack/A.html"); - if (htmlA == null || !htmlA.exists()) { - fail("couldn't find " + getAbsolutePathOutdir() + "/pack/A.html - were there compilation errors?"); + + } + + /** + * Test that the ITD's do not appear in as 'aspect declarations' in the + * class data information. + */ + public void testNoAspectDeclarations() throws Exception { + initialiseProject("pr119453"); + File[] files = { + new File(getAbsoluteProjectDir() + "/src/pack/C.java"), + new File(getAbsoluteProjectDir() + "/src/pack/A.aj") + }; + runAjdoc("private",files); + + File htmlC = new File(getAbsolutePathOutdir() + "/pack/C.html"); + if (htmlC == null || !htmlC.exists()) { + fail("couldn't find " + getAbsolutePathOutdir() + + "/pack/C.html - were there compilation errors?"); } - // check that A is an Aspect - assertTrue(htmlA.getAbsolutePath() + " should have Aspect A as it's title", - AjdocOutputChecker.containsString(htmlA,"Aspect A")); - // check the contents of the declare detail summary - String[] stringsA = { "private int", - "public java.lang.String", - "

C.y

", - "public C.C", - "package void"}; - missing = AjdocOutputChecker.getMissingStringsInSection(htmlA,stringsA,"DECLARE DETAIL SUMMARY"); - assertEquals("There should be one missing string ",1,missing.size()); - assertEquals("the 'package' and 'void' modifiers shouldn't appear in the 'Declare Detail' section of the ajdoc", - "package void", missing.get(0)); - - // check the contents of the declare summary - String[] stringsA2 = {"private", "int", "public", "String", "package void"}; - missing = AjdocOutputChecker.getMissingStringsInSection(htmlA,stringsA2,"DECLARE SUMMARY"); - assertEquals("There should be two missing strings ",2,missing.size()); - assertTrue("the public modifier shouldn't appear in the 'Declare Summary' section of the ajdoc", missing.contains("public")); - assertTrue("the 'package' and 'void' modifiers shouldn't appear in the 'Declare Summary' section of the ajdoc", missing.contains("package void")); + boolean b = AjdocOutputChecker.classDataSectionContainsRel( + htmlC, + HtmlDecorator.HtmlRelationshipKind.ASPECT_DECLARATIONS, + "pack.A.C.y"); + assertFalse("The class data section should not have 'aspect declarations" + + " pack.A.C.y' since this is an ITD",b); } } diff --git a/asm/src/org/aspectj/asm/IProgramElement.java b/asm/src/org/aspectj/asm/IProgramElement.java index d1175df74..8223c176b 100644 --- a/asm/src/org/aspectj/asm/IProgramElement.java +++ b/asm/src/org/aspectj/asm/IProgramElement.java @@ -351,6 +351,10 @@ public interface IProgramElement extends Serializable { return name.startsWith("declare"); } + public boolean isDeclareAnnotation() { + return name.startsWith("declare @"); + } + // The 4 declarations below are necessary for serialization private static int nextOrdinal = 0; private final int ordinal = nextOrdinal++;