]> source.dussan.org Git - aspectj.git/commitdiff
initial version of unused/attic code for later reference
authorwisberg <wisberg>
Tue, 31 Dec 2002 18:25:37 +0000 (18:25 +0000)
committerwisberg <wisberg>
Tue, 31 Dec 2002 18:25:37 +0000 (18:25 +0000)
131 files changed:
aspectj-attic/.classpath [new file with mode: 0644]
aspectj-attic/.project [new file with mode: 0644]
aspectj-attic/ajdoc-src/devnotes.txt [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/AdviceDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/AspectDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ClassDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ConstructorDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Doc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ExecutableMemberDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/FieldDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/IntroducedDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/IntroducedSuperDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/IntroductionDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/MemberDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/MethodDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/OfClauseDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/OfEachObjectDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/PackageDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ParamTag.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Parameter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/PointcutDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ProgramElementDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/RootDoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/SeeTag.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/SerialFieldTag.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Tag.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ThrowsTag.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Type.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Access.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AccessChecker.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AdviceDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Ajdoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AjdocCompiler.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AspectDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/CannotMakeRootDocException.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ClassDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/CodeDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Comment.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ConstructorDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/DocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/DocletProxy.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ErrPrinter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ExecutableMemberDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/FieldDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/FilteredDecList.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/IntroducedDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/IntroducedSuperDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/IntroductionDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Main.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/MemberDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/MethodDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/OfClauseDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/PackageDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ParamTagImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ParameterImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/PointcutDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ProgramElementDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Quietable.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/RootDocImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/RootDocMaker.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/SeeTagImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/SerialFieldTagImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/TagImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ThrowsTagImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/TypeImpl.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Util.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/resources/ajdoc.properties [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/rootmakers/Javadoc.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/rootmakers/Javadoc13.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/rootmakers/Javadoc14.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractIndexWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractStandard.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractSubWriterAJ.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractTreeWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AdviceSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassUseMapper.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassUseWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ConfigurationStandard.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ConstructorIntroductionSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ConstructorSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/DeprecatedAPIListBuilder.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/DeprecatedListWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ExecutableMemberSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/FieldIntroductionSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/FieldSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/MethodIntroductionSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/MethodSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PackageFrameWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PackageTreeWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PackageWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PointcutSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SingleIndexWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SplitIndexWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/Standard.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/Statics.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SubWriterHolderWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SuperIntroductionSubWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/TreeWriter.java [new file with mode: 0644]
aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/resources/standard.properties [new file with mode: 0644]
aspectj-attic/ajdoc-testsrc/AjdocModuleTests.java [new file with mode: 0644]
aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/AjdocTests.java [new file with mode: 0644]
aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/JUnitDriver.java [new file with mode: 0644]
aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/SeeTagImplTest.java [new file with mode: 0644]
aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/genSeeTestCases.sh [new file with mode: 0644]
aspectj-attic/readme-aspectj-attic-module.html [new file with mode: 0644]
aspectj-attic/testing-src/AjcTaskTester.java [new file with mode: 0644]
aspectj-attic/testing-src/AjcTaskTester2.java [new file with mode: 0644]
aspectj-attic/testing-src/AjdocTaskTester.java [new file with mode: 0644]
aspectj-attic/testing-src/AntTaskTester.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/CompareFiles.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/CompareUtil.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNode.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNodeListOrdererFactoryI.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNodeListOrdererI.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNodesVisitorI.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/Regexp.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/RegexpFactory.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/RegexpFilter.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/RegexpFilterReader.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/TreeCompare.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/GenericTreeNodeFactoryI.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/JTreeNodeGenericTreeNodeFactory.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/Structure.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/StructureGenericTreeNodeFactory.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/SubTypeComparator.java [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/package.html [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/compare/package.html [new file with mode: 0644]
aspectj-attic/testing-src/org/aspectj/testing/taskdefs/CompareFiles.java [new file with mode: 0644]

diff --git a/aspectj-attic/.classpath b/aspectj-attic/.classpath
new file mode 100644 (file)
index 0000000..e451f51
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" path="ajdoc-src"/>
+    <classpathentry kind="src" path="ajdoc-testsrc"/>
+    <classpathentry kind="src" path="testing-src"/>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+    <classpathentry kind="lib" path="/lib/junit/junit.jar" sourcepath="/lib/junit/junit-src.jar"/>
+    <classpathentry kind="lib" path="/lib/ant/lib/ant.jar" sourcepath="/lib/ant/ant-src.zip"/>
+    <classpathentry kind="lib" path="/lib/regexp/jakarta-regexp-1.2.jar"/>
+    <classpathentry kind="src" path="/testing"/>
+    <classpathentry kind="src" path="/util"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/aspectj-attic/.project b/aspectj-attic/.project
new file mode 100644 (file)
index 0000000..844fe4c
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>aspectj-attic</name>
+       <comment></comment>
+       <projects>
+               <project>testing</project>
+               <project>util</project>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/aspectj-attic/ajdoc-src/devnotes.txt b/aspectj-attic/ajdoc-src/devnotes.txt
new file mode 100644 (file)
index 0000000..5958dfb
--- /dev/null
@@ -0,0 +1,98 @@
+
+-------------- Problems:
+
+---- todo FIX output HTML is using "introduction" as labels.
+- use "[Summary|Details] of [fields|methods|constructors] declared for target types"
+  ("target" rather than "other" since they may be defined on self?)
+- see also top index links:
+  - super introductions...
+
+solution: change doclet resources
+
+---- FIXED comments not displayed for inter-type declarations in the aspects
+solution:  IntroducedDocImpl.java sets source location for the dec from the introduced dec
+
+>         dec.setSourceLocation(introducedDec.getSourceLocation()); // PR790, 712
+
+
+---- PARTIAL FIX: synthetic constructors are shown in the javadoc
+solution: post-process to remove unadvised constructors with same source location as parent class
+
+See ClassDocImpl.java
+
+problem with the solution: does not remove synthetic constructors on aspects??
+ (only if they advise themselves?)
+
+
+---- FIXED class cast exception trying to print introduced Constructor parameters
+solution:
+diff -r1.5 IntroducedDocImpl.java
+105c107
+<                             makeParameters(((MethodDocImpl)cs[i]).
+---
+>                             makeParameters(((ConstructorDocImpl)cs[i]).
+
+---- introduced constructor names use the name of the declaring aspect, not the target 
+solution:
+diff -r1.4 ConstructorDocImpl.java
+53c56,58
+<         return containingClass().name();
+---
+>         String qname = getQualifiedName();
+>         return (null != qname ? qname : containingClass().name());
+
+---- ok: in aspect docs, inter-type declarations targeting the aspect work as expected,
+     with both the inter-type declaration and the aspect-declared member documented.
+     
+---- ajc prints out declare-warnings when compiling for ajdoc
+
+---- in aspect docs, links out to affected classes not printed for introduced constructors
+essentially, the name of the constructor (should) differ for each target.  sigh.
+- identifier should be the FQN of the aspect plus the type pattern and signature of the constructor.
+  (parm signature - result, throws not required)
+- display label in the aspect should be the identifier
+  -> currently is the name of the aspect plus ()
+- display label in affected classes should be the name of the affected class and the parm signature
+  -> c
+
+---- in target docs, links back to declaring aspects for introduced constructors fail
+(iff parms?)
+
+---- in target docs, summaries of members declared by aspects do not list initial comment line.
+
+---- is aspect docs, members declared on target types are displayed only with the member name,
+     not the typepattern.
+see IntroducedDocImpl.java name()
+
+    public String name() {
+        // when using qualified name, unable to find links aout to targets
+        // return (null != qualifiedName ? qualifiedName : dec().getId()); // XXX
+        // when using id, only get simple name
+        return dec().getId();
+    }  
+    ==> get caller to use printedName as label
+
+UNFIXABLE - caller is sun doclet, and we only give it the member as parameter.
+We do control the names of the links out, but not the name of the member in the class,
+except to override qualifiedName, which causes the links out to fail (because
+IntroducedDocImpl.createTargets() uses MemberDocImpl.weakEquals() to discover 
+all introduced members in other types to find out if they were introduced by this
+declaration (awful!), and [Method|Field|Member]DocImpl.weakEquals() implementations
+use name() - using qualifiedName() would result in false positives for any field
+in a target class). Overriding name() also causes other things to fail because it is 
+used as an id.   Even changing the name during the lifecycle seems risky.  There's
+not a clean separation between the type name and the name as displayed. 
+
+---- in target class docs, introduced member links back to declaring aspect 
+     have the member name as their label; should have the aspect type.
+     
+---- bad fix: references to declaration targets lost and incomplete html thereafter
+     is a result of modifying name() or qualifiedName() of memberDoc
+
+-------------- Background:
+??
+declaration target - Introduced
+declaration source - Introduction
+
+
+
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/AdviceDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/AdviceDoc.java
new file mode 100644 (file)
index 0000000..1abf7df
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+import com.sun.javadoc.Type;
+
+/**
+ * Documentation for a piece of advice.
+ *
+ * @author Jeff Palm
+ */
+public interface AdviceDoc extends ExecutableMemberDoc,
+                                   com.sun.javadoc.ExecutableMemberDoc {
+    /**
+     * Returns <code>true</code> if the advice is <code>abstract</code>.
+     *
+     * @return <code>true</code> if the advice is <code>abstract</code>.
+     */
+    public boolean isAbstract();
+
+    /**
+     * Returns a {@link #AspectDoc} representing the aspect
+     * that is overriden by this advice.
+     *
+     * @return a AspectDoc representing the aspect
+     *         that is overriden by this advice.
+     */
+    public AspectDoc overriddenAspect();
+
+    /**
+     * Returns the return type of this advice -- it may be null.
+     *
+     * @return the return type of this advice -- it may be null.
+     */
+    public Type returnType();
+
+    /**
+     * Returns the array of docs this advice crosscuts.
+     *
+     * @return an array of docs this advice crosscuts.
+     */
+    public com.sun.javadoc.ExecutableMemberDoc[] crosscuts();
+
+    /**
+     * Returns <code>true</code> if this is <code>throwing</code> advice.
+     *
+     * @return <code>true</code> if this is <code>throwing</code> advice.
+     */
+    public boolean isThrowing();
+    
+    /**
+     * Returns <code>true</code> if this is <code>returning</code> advice.
+     *
+     * @return <code>true</code> if this is <code>returning</code> advice.
+     */
+    public boolean isReturning();
+
+    /**
+     * Returns the extra formal type that's the optional type
+     * to <code>after returning</code> or <code>after throwing</code>
+     * advice.
+     *
+     * @return an instance of Type that represents the the extra formal type
+     *         that's the optional type to <code>after returning</code> or
+     *         <code>after throwing</code> advice.
+     */
+    public Type extraType();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/AspectDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/AspectDoc.java
new file mode 100644 (file)
index 0000000..0ead3a1
--- /dev/null
@@ -0,0 +1,83 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * Represents an aspectj aspect and extends
+ * <code>ClassDoc</code> to provide the extra aspectj-only
+ * information not present in that interface.
+ *
+ * @author Jeff Palm
+ */
+public interface AspectDoc extends ClassDoc { //, com.sun.javadoc.ClassDoc {
+
+    /**
+     * Return advice in aspect.
+     *
+     * @return an array of AdviceDoc for representing the
+     *         visible advice in this aspect.
+     */
+    public AdviceDoc[] advice();
+
+    /**
+     * Return aspects that are dominated by this aspect.
+     *
+     * @return an array of AspectDoc for representing the
+     *         aspects that are dominated by this aspect.
+     */
+    public AspectDoc[] dominatees();
+
+    /**
+     * Return aspects that dominate this aspect.
+     *
+     * @return an array of AspectDoc for representing the
+     *         aspects that dominate this aspect.
+     */
+    public AspectDoc[] dominators();
+
+    /**
+     * Return the introductions made by this aspect on other types.
+     *
+     * @return an array of IntroductionDoc for representing the
+     *         introductions made on other types.
+     */
+    public IntroductionDoc[] introductions();
+
+    /**
+     * Return the of clauses that describe this aspect.
+     *
+     * @return an array of OfClauseDoc for representing the
+     *         of clauses that describe this aspect.
+     */
+    public OfClauseDoc ofClause();
+
+    /**
+     * Returns <code>true</code> if this aspects dominates
+     * the passed in aspect.
+     *
+     * @param other an AspectDoc that represents another
+     *              aspect in this world.
+     * @return      <code>true</code> if this aspects dominates
+     *              the passed in aspect.
+     */
+    public boolean dominates(AspectDoc other);
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ClassDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ClassDoc.java
new file mode 100644 (file)
index 0000000..eff5fa1
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * Represents a class in the aspectj-world.  The difference
+ * between this and one in the javac-world, is that a class
+ * may have pointcuts and introductions.
+ *
+ * @author Jeff Palm
+ */
+public interface ClassDoc extends com.sun.javadoc.ClassDoc,
+                                  ProgramElementDoc, Type {
+
+    /**
+     * Returns the pointcuts this class declares.
+     *
+     * @return an array of PointcutDoc representing the
+     *         pointcuts declared by this class.
+     */
+    public PointcutDoc[] pointcuts();
+
+    /**
+     * Returns the introductions made by other aspects that
+     * affect the type hierarchy of this class.
+     *
+     * @return an array of IntroducedSuperDoc representing the
+     *         introductions affecting the type hierarchy of
+     *         this class.
+     */
+    public IntroducedSuperDoc[] introducers();
+
+    /**
+     * Return <code>true</code> if this is an aspect.
+     *
+     * @return <code>true</code> is this is an aspect.
+     */
+    public boolean isAspect();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ConstructorDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ConstructorDoc.java
new file mode 100644 (file)
index 0000000..3557fe0
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * An empty extension of com.sun.javadoc.ConstructorDoc.
+ *
+ * @author Jeff Palm
+ */
+public interface ConstructorDoc extends com.sun.javadoc.ConstructorDoc,
+                                        ExecutableMemberDoc {
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Doc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Doc.java
new file mode 100644 (file)
index 0000000..95fc251
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * The abstract base class of all Doc classes in the
+ * aspectj-world.
+ *
+ * @author Jeff Palm
+ */
+public interface Doc extends com.sun.javadoc.Doc {
+
+    /**
+     * Returns <code>true</code> if this Doc is advice.
+     *
+     * @return <code>true</code> is this Doc is advice.
+     */
+    public boolean isAdvice();
+
+    /**
+     * Returns <code>true</code> if this Doc is a pointcut.
+     *
+     * @return <code>true</code> is this Doc is a pointcut.
+     */
+    public boolean isPointcut();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ExecutableMemberDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ExecutableMemberDoc.java
new file mode 100644 (file)
index 0000000..7af271f
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * Represents and executable member in the aspectj-world.
+ * The only difference between this and one in the javac-world
+ * is that these members can have advice on them
+ *
+ * @author Jeff Palm
+ */
+public interface ExecutableMemberDoc extends com.sun.javadoc.ExecutableMemberDoc,
+                                             MemberDoc {
+
+    /**
+     * Returns the advice placed on this member.
+     *
+     * @return an array of AdviceDoc representing the
+     *         advice placed on this member.
+     */
+    public AdviceDoc[] advice();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/FieldDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/FieldDoc.java
new file mode 100644 (file)
index 0000000..5997df3
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * An empty extension of com.sun.javadoc.FieldDoc.
+ *
+ * @author Jeff Palm
+ */
+public interface FieldDoc extends com.sun.javadoc.FieldDoc, MemberDoc {
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/IntroducedDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/IntroducedDoc.java
new file mode 100644 (file)
index 0000000..3f3f6ac
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * Represents the introduction of a member onto a ClassDoc.
+ *
+ * @author Jeff Palm
+ */
+public interface IntroducedDoc extends IntroductionDoc {
+
+    /**
+     * Returns the member introduced on {@link #targets()}.
+     *
+     * @return the MemberDoc that was introduced.
+     */
+    public MemberDoc member();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/IntroducedSuperDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/IntroducedSuperDoc.java
new file mode 100644 (file)
index 0000000..855b137
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * Represents the introduction of a class-extension or
+ * interface-implementation (e.g. +extends or +implements)
+ * onto a ClassDoc.
+ *
+ * @author Jeff Palm
+ */
+public interface IntroducedSuperDoc extends IntroductionDoc {
+
+    /**
+     * Returns the types that are introduced.
+     *
+     * @return an array of Type representing the classes or
+     *         aspects that the target ClassDocs now implement
+     *         or extend.
+     */
+    public Type[] types();
+
+    /**
+     * Returns <code>true</code> is this is a '+implements'
+     * introduction.
+     *
+     * @return  <code>true</code> is this is a '+implements'
+     *          introduction.
+     */
+    public boolean isImplements();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/IntroductionDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/IntroductionDoc.java
new file mode 100644 (file)
index 0000000..a2e4efe
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * Represents an introduction with >= 0 target ClassDocs.
+ *
+ * @author Jeff Palm
+ */
+public interface IntroductionDoc extends MemberDoc {
+
+    /**
+     * Returns the targets that this introduction affects.
+     *
+     * @return an array of ClassDoc representing the
+     *         classes/aspects this introduction affects.
+     */
+    public ClassDoc[] targets();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/MemberDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/MemberDoc.java
new file mode 100644 (file)
index 0000000..e793d92
--- /dev/null
@@ -0,0 +1,43 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * A class or aspect member in the aspectj-world, the difference
+ * between this and a javac-world member is that if this member
+ * was introduced by an aspect, it has a reference to that
+ * introduction.
+ *
+ * @author Jeff Palm
+ */
+public interface MemberDoc extends com.sun.javadoc.MemberDoc,
+                                   ProgramElementDoc {
+
+    /**
+     * Returns the introduction that placed this member on this class
+     * if is exists -- this <b>can</b> be <code>null</code>.
+     *
+     * @return the introduction that placed this member on this class
+     *         if is exists -- this <b>can</b> be <code>null</code>.
+     */
+    public IntroducedDoc introduced();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/MethodDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/MethodDoc.java
new file mode 100644 (file)
index 0000000..0d05b0d
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * An empty exntension to com.sun.javadoc.MethodDoc.
+ *
+ * @author Jeff Palm
+ */
+public interface MethodDoc extends com.sun.javadoc.MethodDoc,
+                                   ExecutableMemberDoc {
+    
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/OfClauseDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/OfClauseDoc.java
new file mode 100644 (file)
index 0000000..776d1bc
--- /dev/null
@@ -0,0 +1,79 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * Represents an of clause describing an aspect.
+ * This declaration also contains constants to be used to
+ * identify different OfClauseDocs.
+ *
+ * @author Jeff Palm
+ */
+public interface OfClauseDoc {
+
+    /**
+     * A typesafe-enum describing the possible kinds
+     * of OfClauseDocs.
+     */
+    public final static class Kind {
+
+        /** Internal representation. */
+        private final String kind;
+
+        /**
+         * Don't allow any other's to call this.
+         *
+         * @param kind The internal String representation.
+         */
+        private Kind(String kind) { this.kind = kind; }
+
+        /**
+         * Represents an 'of eachcflow(..)' clause.
+         */
+        public final static Kind EACH_CFLOW = new Kind("echocflow(..)");
+
+        /**
+         * Represents an 'of eachJVM()' clause.
+         */
+        public final static Kind EACH_JVM = new Kind("eachJVM()");
+        
+        /**
+         * Represents an 'of eachobject(..)' clause.
+         */
+        public final static Kind EACH_OBJECT = new Kind("eachObject()");
+
+        /**
+         * Returns a short representation of the kind.
+         *
+         * @return a short representation of the kind.
+         */
+        public String toString() { return kind; }
+    }
+
+    /**
+     * Returns the appropriate constant defined in Kind.
+     *
+     * @return the appropriate constant defined in Kind.
+     * @see    Kind
+     */
+    public Kind kind();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/OfEachObjectDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/OfEachObjectDoc.java
new file mode 100644 (file)
index 0000000..bc05a77
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * Representat an 'of eachobject(..)' clause, thought currently
+ * out of the language, it could make a comeback.
+ *
+ * @author Jeff Palm
+ */
+public interface OfEachObjectDoc extends OfClauseDoc {
+
+    /**
+     * Returns the classes for which an instance of
+     * this aspect will be made for each.
+     *
+     * @return an array of com.sun.javadoc.ClassDoc representing
+     *         the classes for which an instance of
+     *         this aspect will be made for each.
+     */
+    //public com.sun.javadoc.ClassDoc[] instances();
+    public ClassDoc[] instances();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/PackageDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/PackageDoc.java
new file mode 100644 (file)
index 0000000..a34cc50
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * An extension of com.sun.javadoc.PackageDoc to add aspects.
+ *
+ * @author Jeff Palm
+ */
+public interface PackageDoc extends com.sun.javadoc.PackageDoc,
+                                    Doc
+{
+
+    /**
+     * Returns the aspects in this package.
+     *
+     * @return an array of AspectDoc representing the
+     *         aspects in this package.
+     */
+    public AspectDoc[] aspects();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ParamTag.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ParamTag.java
new file mode 100644 (file)
index 0000000..9b9bc15
--- /dev/null
@@ -0,0 +1,24 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+public interface ParamTag extends com.sun.javadoc.ParamTag {}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Parameter.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Parameter.java
new file mode 100644 (file)
index 0000000..140b5dd
--- /dev/null
@@ -0,0 +1,24 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+public interface Parameter extends com.sun.javadoc.Parameter {}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/PointcutDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/PointcutDoc.java
new file mode 100644 (file)
index 0000000..0883271
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+import com.sun.javadoc.ClassDoc;
+
+import com.sun.javadoc.Type;
+
+/**
+ * Represents a pointcut in the aspectj-world.
+ *
+ * @author Jeff Palm
+ */
+public interface PointcutDoc extends ExecutableMemberDoc,
+                                     com.sun.javadoc.ExecutableMemberDoc
+{
+    /**
+     * Returns the resulting type of this pointcut.
+     *
+     * @return an instance of Type representing the type
+     *         this pointcut returns.
+     */
+    public Type resultType();
+
+    /**
+     * The nearest class in which this pointcut was defined.
+     *
+     * @return an instanceof ClassDoc representing the
+     *         nearst class in which this pointcut was
+     *         defined.
+     */
+    public ClassDoc overriddenClass();
+
+    /**
+     * Returns <code>true</code> if this pointcut
+     * is <code>abstract</code>.
+     *
+     * @return <code>true</code> if this pointcut
+     *         is <code>abstract</code>.
+     */
+    public boolean isAbstract();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ProgramElementDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ProgramElementDoc.java
new file mode 100644 (file)
index 0000000..5ef9f84
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * An empty extension of com.sun.javadoc.ProgramElementDoc.
+ *
+ * @author Jeff Palm
+ */
+public interface ProgramElementDoc extends com.sun.javadoc.ProgramElementDoc,
+                                           Doc {
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/RootDoc.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/RootDoc.java
new file mode 100644 (file)
index 0000000..6a80ee4
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * An empty extension of com.sun.javadoc.RootDoc.
+ *
+ * @author Jeff Palm
+ */
+public interface RootDoc extends com.sun.javadoc.RootDoc,
+                                 Doc {
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/SeeTag.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/SeeTag.java
new file mode 100644 (file)
index 0000000..69add72
--- /dev/null
@@ -0,0 +1,24 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+public interface SeeTag extends com.sun.javadoc.SeeTag {}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/SerialFieldTag.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/SerialFieldTag.java
new file mode 100644 (file)
index 0000000..078cbb8
--- /dev/null
@@ -0,0 +1,24 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+public interface SerialFieldTag extends com.sun.javadoc.SerialFieldTag {}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Tag.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Tag.java
new file mode 100644 (file)
index 0000000..bacd8b8
--- /dev/null
@@ -0,0 +1,24 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+public interface Tag extends com.sun.javadoc.Tag {}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ThrowsTag.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/ThrowsTag.java
new file mode 100644 (file)
index 0000000..419e779
--- /dev/null
@@ -0,0 +1,24 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+public interface ThrowsTag extends com.sun.javadoc.ThrowsTag {}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Type.java b/aspectj-attic/ajdoc-src/org/aspectj/ajdoc/Type.java
new file mode 100644 (file)
index 0000000..4ffdccb
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.ajdoc;
+
+/**
+ * An empty extension of com.sun.javadoc.RootDoc.
+ *
+ * @author Jeff Palm
+ */
+public interface Type extends com.sun.javadoc.Type {
+
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Access.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Access.java
new file mode 100644 (file)
index 0000000..e337918
--- /dev/null
@@ -0,0 +1,197 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+//package com.sun.tools.doclets.standard;
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.tools.doclets.standard.AbstractSubWriter;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.Doc;
+import com.sun.javadoc.ExecutableMemberDoc;
+import com.sun.javadoc.ProgramElementDoc;
+import com.sun.tools.doclets.standard.ClassUseWriter;
+import com.sun.tools.doclets.standard.ExecutableMemberSubWriter;
+import com.sun.tools.doclets.standard.SubWriterHolderWriter;
+
+import java.util.List;
+import java.util.SortedSet;
+
+/**
+ * Allows for access to protected and package-protected (OK
+ * sometimes private) members in classes in the package
+ * com.sun.tools.doclets...
+ *
+ * @author Jeff Palm
+ */
+public class Access {
+
+    public static void printSummaryType(AbstractSubWriter mw,
+                                        ProgramElementDoc member) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw.del(),
+                    "printSummaryType",
+                    new Class[]{ProgramElementDoc.class},
+                    new Object[]{member});
+    }
+    public static void printSummaryLink(AbstractSubWriter mw,
+                                        ClassDoc cd,
+                                        ProgramElementDoc member) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw.del(),
+                    "printSummaryLink",
+                    new Class[]{ClassDoc.class,
+                                ProgramElementDoc.class},
+                    new Object[]{cd, member});
+    }
+    public static void printInheritedSummaryLink(AbstractSubWriter mw,
+                                                 ClassDoc cd,
+                                                 ProgramElementDoc member) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw.del(),
+                    "printInheritedSummaryLink",
+                    new Class[]{ClassDoc.class,
+                                ProgramElementDoc.class},
+                    new Object[]{cd, member});
+    }
+    public static void printHeader(AbstractSubWriter mw,
+                                   ClassDoc cd) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw.del(),
+                    "printHeader",
+                    new Class[]{ClassDoc.class},
+                    new Object[]{cd});
+    }
+    public static void printBodyHtmlEnd(AbstractSubWriter mw,
+                                        ClassDoc cd) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw.del(),
+                    "printBodyHtmlEnd",
+                    new Class[]{ClassDoc.class},
+                    new Object[]{cd});
+    }
+    public static void printMember(AbstractSubWriter mw,
+                                   ProgramElementDoc elem) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw.del(),
+                    "printMember",
+                    new Class[]{ProgramElementDoc.class},
+                    new Object[]{elem});
+    }
+    public static void printDeprecatedLink(AbstractSubWriter mw,
+                                           ProgramElementDoc member) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw.del(),
+                    "printDeprecatedLink",
+                    new Class[]{ProgramElementDoc.class},
+                    new Object[]{member});
+    }
+    public static void printNavSummaryLink(AbstractSubWriter mw,
+                                           ClassDoc cd,
+                                           boolean link) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw.del(),
+                    "printNavSummaryLink",
+                    new Class[]{ClassDoc.class,
+                                boolean.class},
+                    new Object[]{cd, new Boolean(link)});
+    }
+    public static void printNavDetailLink(AbstractSubWriter mw,
+                                          boolean link) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw.del(),
+                    "printNavDetailLink",
+                    new Class[]{boolean.class},
+                    new Object[]{new Boolean(link)});
+    }
+    public static void printTags(AbstractSubWriter mw,
+                                 ProgramElementDoc member) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw.del(),
+                    "printTags",
+                    new Class[]{ProgramElementDoc.class},
+                    new Object[]{member});
+    }
+    public static void printDeprecatedAPI(AbstractSubWriter mw,
+                                   List deprmembers,
+                                   String headingKey) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw.del(),
+                    "printDeprecatedAPI",
+                    new Class[]{List.class, String.class},
+                    new Object[]{deprmembers, headingKey});
+    }
+    public static void printParameters(ExecutableMemberSubWriter mw,
+                                       ExecutableMemberDoc member) {
+        Util.invoke(com.sun.tools.doclets.standard.ExecutableMemberSubWriter.class,
+                    mw,
+                    "printParameters",
+                    new Class[]{ExecutableMemberDoc.class},
+                    new Object[]{member});
+    }
+    public static void printUseInfo(AbstractSubWriter mw,
+                                    Object mems,
+                                    String heading) {
+        printUseInfo(mw.del(), mems, heading);
+    }
+    public static void printUseInfo
+        (com.sun.tools.doclets.standard.AbstractSubWriter mw,
+         Object mems,
+         String heading) {
+        if (mw != null) {
+            Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                        mw,
+                        "printUseInfo",
+                        new Class[]{Object.class, String.class},
+                        new Object[]{mems, heading});
+        }
+    }
+    public static void printCommentDef(AbstractSubWriter mw, Doc doc) {
+        Util.invoke(SubWriterHolderWriter.class,
+                    writer(mw),
+                    "printCommentDef",
+                    new Class[]{Doc.class},
+                    new Object[]{doc});
+    }
+    public static SubWriterHolderWriter writer(AbstractSubWriter mw) {
+        return (SubWriterHolderWriter)
+            Util.access(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                        mw, "writer");
+    }
+    public static SortedSet pkgSet(ClassUseWriter writer) {
+        return (SortedSet)Util.access(ClassUseWriter.class,
+                                      writer,
+                                      "pkgSet");
+    }
+    public static ClassDoc classdoc(ClassUseWriter writer) {
+        return (ClassDoc)Util.access(ClassUseWriter.class,
+                                     writer,
+                                     "classdoc");
+    }
+    public static void print(com.sun.tools.doclets.standard.AbstractSubWriter mw,
+                             String str) {
+        Util.invoke(com.sun.tools.doclets.standard.AbstractSubWriter.class,
+                    mw,
+                    "print",
+                    new Class[]{String.class},
+                    new Object[]{str});
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AccessChecker.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AccessChecker.java
new file mode 100644 (file)
index 0000000..fff6318
--- /dev/null
@@ -0,0 +1,178 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ast.Modifiers;
+import org.aspectj.compiler.base.ast.FieldDec;
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.base.ast.NameType;
+import org.aspectj.compiler.base.ast.CodeDec;
+import org.aspectj.compiler.crosscuts.ast.PointcutDec;
+
+/**
+ * This utility tells whether a declaration is accessible
+ * based on its access modifiers (and that of its declaring
+ * class, if it is a member (i.e., including inner classes).
+ * <p><u>Instantiation and subclassing</u>: 
+ * The constants should suffice for most uses, but subclassing
+ * is permitted if you need to implement new functionality or
+ * make new instances. 
+ */
+public abstract class AccessChecker {
+    // constants open doCanAccess to public to permit direct use
+
+    /** return true only for public elements */
+    public static final AccessChecker PUBLIC = new AccessChecker("public") {
+            public boolean doCanAccess(Modifiers mods, Object object) {
+                return mods.isPublic();
+            }
+        };
+
+    /** return true for public and protected elements */
+    public static final AccessChecker PROTECTED = new AccessChecker("protected") {
+            public boolean doCanAccess(Modifiers mods, Object object) {
+                return mods.isPublic() || mods.isProtected();
+            }
+        };
+
+    /** return true unless private elements */
+    public static final AccessChecker PACKAGE = new AccessChecker("package") {
+            public boolean doCanAccess(Modifiers mods, Object object) {
+                return !mods.isPrivate();
+            }
+        };
+
+    /** return true for all elements */
+    public static final AccessChecker PRIVATE = new AccessChecker("private") {
+            public boolean doCanAccess(Modifiers mods, Object object) {
+                return true;
+            }
+        };
+
+    /** lowercase option without - */
+    protected final String optionName;
+
+    /** 
+     * Encourage use of static constants by prohibiting construction 
+     * but permit new subclasses.
+     * Subclasses should ensure optionName is lowercase and
+     * doCanAccess is public if need be.
+     */
+    protected AccessChecker(String optionName){
+        this.optionName = optionName;
+    }
+
+    /** @return true if modifiers permitted for self and declaring type */
+    public boolean canAccess(FieldDec dec) {
+        if (null == dec) return false;
+        if (!canAccess(dec.getModifiers(), dec)) {
+            return false;
+        } else {
+            return canAccess(dec.getBytecodeTypeDec());
+        }
+    }
+
+    /** @return true if modifiers permitted for self and declaring type */
+    public boolean canAccess(CodeDec dec) {
+        if (null == dec) return false;
+        if (!canAccess(dec.getModifiers(), dec)) {
+            return false;
+        } else {
+            return canAccess(dec.getBytecodeTypeDec());
+        }
+    }
+
+    /** @return true if modifiers permitted for self and declaring type */
+    public boolean canAccess(PointcutDec dec) {
+        if (null == dec) return false;
+        if (!canAccess(dec.getModifiers(), dec)) {
+            return false;
+        } else {
+            return canAccess(dec.getBytecodeTypeDec());
+        }
+    }
+
+    /** decode dec modifiers and return whether access is permitted 
+     *  Access is permitted if it is permitted to the dec.
+     * The caller must prohibit access when displaying in the aspect
+     * (i.e., <code>canAccess(dec.getLexicalType())</code> or in
+     * the target class
+     * (i.e., <code>canAccess(dec.getDeclaringType())</code>)
+     * and to the enclosing lexical type (i.e,. the enclosing aspect).
+     */
+    /*
+    public boolean canAccess(IntroducedDec dec) { // todo: users
+        if (null == dec) return false;
+        if (!canAccess(dec.getModifiers(), dec)) {
+            return false;
+        } else {
+            return canAccess(dec.getLexicalType());
+        }
+    }
+    */
+
+    /** @return true if modifiers permitted for self and any enclosing type */
+    public boolean canAccess(TypeDec dec) {
+        if (null == dec) return false; 
+        boolean result = canAccess(dec.getModifiers(), dec);
+        if (result) {
+            // avoiding NPE in getEnclosingInstanceTypeDec
+            NameType outerType = dec.getEnclosingInstanceType();
+            TypeDec outer = (null == outerType? null 
+                             : outerType.getTypeDec()); // todo: typeDec?
+            result = ((null == outer) || canAccess(outer));
+        }
+        return result;
+    }
+
+    /** 
+     * This is called from <code>canAccess</code> to log any results 
+     * of <code>doCanAccess</code>
+     * and should return the result or a principled variant thereof.
+     */
+    protected boolean canAccessLog(Modifiers mods, Object object,
+                                    boolean result) {
+        return result;
+    }
+
+    /**
+     * Check whether client has access to the object
+     * based on the modifiers.
+     * @param object the Object with the modifier flags - may be null
+     * @param modifiers the Modifiers to check
+     * @return false if modifiers are null or true if access is permitted
+     */
+    // todo: object unused but useful for logging
+    public final boolean canAccess(Modifiers mods, Object object) {
+        boolean result = (null == mods? false : doCanAccess(mods, object));
+        return canAccessLog(mods, object, result);
+    }
+
+    /** @return lowercase variant of option name (e.g., "private" for -private) */
+    public final String getOption() { return optionName; }
+
+    /** @return UPPERCASE variant of option name (e.g., "PRIVATE" for -private) */
+    public final String toString() { return optionName.toUpperCase(); }
+
+    /** subclasses implement semantics here. */
+    abstract protected boolean doCanAccess(Modifiers mods, Object object);
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AdviceDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AdviceDocImpl.java
new file mode 100644 (file)
index 0000000..7b10288
--- /dev/null
@@ -0,0 +1,199 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+
+import org.aspectj.ajdoc.AdviceDoc;
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.ClassDoc;
+import org.aspectj.ajdoc.ExecutableMemberDoc;
+import org.aspectj.compiler.base.ast.CodeDec;
+import org.aspectj.compiler.base.ast.FormalDec;
+import org.aspectj.compiler.base.ast.NameType;
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.crosscuts.ast.AdviceDec;
+import org.aspectj.compiler.crosscuts.ast.AfterReturningAdviceDec;
+import org.aspectj.compiler.crosscuts.ast.AfterThrowingAdviceDec;
+import org.aspectj.compiler.crosscuts.ast.AroundAdviceDec;
+
+import com.sun.javadoc.Type;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+public class AdviceDocImpl extends CodeDocImpl implements AdviceDoc {
+
+    /** Crosscuts this advice affects. */
+    private final Collection crosscuts;
+
+    /**
+     * Constructrs an AdviceDoc with the containing ClassDoc
+     * and underlying AdviceDec.
+     *
+     * @param containingClass containing ClassDoc.
+     * @param adviceDec       underlying AdviceDec.
+     */
+     public AdviceDocImpl(ClassDoc containingClass, AdviceDec adviceDec) {
+        super(containingClass, adviceDec);
+        crosscuts = createCrosscuts();
+    }
+
+    /**
+     * Returns the underlying Dec -- an AdviceDec.
+     *
+     * @return the underlying Dec -- an AdviceDec.
+     */
+    protected AdviceDec adviceDec() {
+        return (AdviceDec)codeDec();
+    }
+
+    /**
+     * Return the ExecutableMemberDocs this advice crosscuts.
+     *
+     * @return an array of ExecutableMemberDocs representing
+     *         the members this advice crosscuts.
+     */
+    public com.sun.javadoc.ExecutableMemberDoc[] crosscuts() {
+        return (ExecutableMemberDoc[])crosscuts.toArray
+            (new ExecutableMemberDoc[crosscuts.size()]);
+    }
+
+    /**
+     * Returns <code>null</code>, because advice can't override
+     * other advice.
+     *
+     * @return <code>null</code>, because advice can't override
+     *         other advice.
+     */
+    public AspectDoc overriddenAspect() {
+        return null;
+    }
+
+    /**
+     * Returns the return type of the advice -- it may be null.
+     *
+     * @return the return type of the advice -- it may be null.
+     */
+    public com.sun.javadoc.Type returnType() {
+        if (adviceDec() instanceof AroundAdviceDec) {
+            return TypeImpl.getInstance(adviceDec().getReturnType());
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns <code>true</code>.
+     *
+     * @return <code>true</code>.
+     */
+    public boolean isAdvice() {
+        return true;
+    }
+
+    /**
+     * Returns <code>true</code> if this advice is <code>abstract</code>.
+     *
+     * @return <code>true</code> if this advice is <code>abstract</code>.
+     */
+    public boolean isAbstract() {
+        return adviceDec().isAbstract();
+    }
+
+    
+    /**
+     * Returns <code>true</code> if this is <code>throwing</code> advice.
+     *
+     * @return <code>true</code> if this is <code>throwing</code> advice.
+     */
+    public boolean isThrowing() {
+        return adviceDec() instanceof AfterThrowingAdviceDec;
+    }
+
+    /**
+     * Returns <code>true</code> if this is <code>returning</code> advice.
+     *
+     * @return <code>true</code> if this is <code>returning</code> advice.
+     */
+    public boolean isReturning() {
+        return adviceDec() instanceof AfterReturningAdviceDec;
+    }
+
+    /**
+     * Returns the extra formal type that's the optional type
+     * to <code>after returning</code> or <code>after throwing</code>
+     * advice.
+     *
+     * @return an instance of Type that represents the the extra formal type
+     *         that's the optional type to <code>after returning</code> or
+     *         <code>after throwing</code> advice.
+     */
+    public Type extraType() {
+        FormalDec fd = adviceDec().getExtraFormal();
+        if (fd != null) {
+            return TypeImpl.getInstance(fd.getType());
+        }
+        return null;
+    }
+
+
+    /**
+     * Returns a Collection of CodeDocImpl representing the
+     * crosscuts the underlying TypeDec declares.
+     *
+     * @return a Collection of CodeDocImpl representing the
+     *         crosscuts the underlying TypeDec declares.
+     */
+    private Collection createCrosscuts() {
+        Set affects = ajc().getCorrespondences().getAffects(adviceDec());
+        if (affects.size() < 1) return Collections.EMPTY_LIST;
+        List list = new ArrayList();
+        for (Iterator i = affects.iterator(); i.hasNext();) {
+            Object o = i.next();
+            if (o instanceof CodeDec) {
+                CodeDec cdec = (CodeDec)o;
+                TypeDec owner = ((NameType)cdec.getDeclaringType()).getTypeDec();
+                ClassDocImpl cd = ClassDocImpl.getInstance(owner);
+                CodeDocImpl cdoc = cd.docForDec(cdec);
+                if (cdoc != null) { // todo: silent introduced members
+                    list.add(cdoc);
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Returns the simple name of this advice.  Need to override
+     * this so we don't print afterThrowing or afterReturning.
+     *
+     * @return one of after, before, around.
+     */
+    public String name() {
+        if (isThrowing() || isReturning())  return "after";
+        return super.name();
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Ajdoc.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Ajdoc.java
new file mode 100644 (file)
index 0000000..59dec52
--- /dev/null
@@ -0,0 +1,384 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.CompilerErrors;
+import org.aspectj.compiler.base.ExitRequestException;
+import org.aspectj.compiler.base.InternalCompilerError;
+
+import com.sun.javadoc.RootDoc;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Front-end for ajdoc.
+ *
+ */ 
+public class Ajdoc extends AjdocCompiler {
+
+    private final static int VERBOSE  = 1;
+    private final static int WARNINGS = 4;
+   
+    private DocletProxy docletProxy;
+    private RootDocMaker rootDocMaker;          
+    private String source = null;
+    private String extdirs = null;
+    private String locale = null;
+    private String encoding = null;
+    private String sourcepath = null;
+    private String classpath = null;
+    private String bootclasspath = null;
+    private int verbosity = WARNINGS;
+    private List filenamesAndPackages = new ArrayList();
+    private List options = new ArrayList();
+
+    public Ajdoc(String programName) {
+        super(programName);
+    }
+
+    public Ajdoc() {
+        this("ajdoc");
+    }
+
+    /**
+     * Programmatic entry into this compiler that
+     * uses the error printer to catch internal errors.
+     *
+     * @param args Command line arguments.
+     * @return     <code>0</code> for a successful document.
+     */
+    public int execute(String[] args) {
+        try {
+            return doc(args) && err.getNumErrors() == 0 ? 0 : 1;
+        } catch (ExitRequestException exit) {
+            return exit.getValue();
+        } catch (CompilerErrors err) { 
+            return err.errors;   // report error already printed by ajc
+        } catch (InternalCompilerError error) { // cf ajc.Main
+            handleInternalError(error.uncaughtThrowable);
+            error.showWhere(new PrintWriter(System.err));
+            return -2;
+        } catch (Exception e) {
+            e.printStackTrace(System.err);
+            err.internalError("internal_msg", e);
+            return 1;
+        }
+    }
+
+    /** copied from ajc.Main */
+    public void handleInternalError(Throwable uncaughtThrowable) {
+        System.err.println("An internal error occured in Ajdoc invocation of AspectJ-"
+                           +getCompiler().getVersion());
+        System.err.println(uncaughtThrowable.toString());
+        uncaughtThrowable.printStackTrace(System.err);
+        System.err.println();
+    }
+
+    /**
+     * Programmatic entry into this compiler that
+     * doesn't use the error printer to catch internal errors.
+     *
+     * @param args Command line arguments.
+     * @return     <code>true</code> for a succesful run.
+     */
+    public boolean doc(String[] args) {
+
+        long start = System.currentTimeMillis();
+
+        if (args == null) {
+            err.error("internal_error", "Arguments cannot be null");
+            return false;
+        }
+
+        try {
+            args = expandAndCreateDoclet(args);
+        } catch (FileNotFoundException e) {
+            err.error("file_not_found_exception", e.getMessage());
+            return false;
+        } catch (IOException e) {
+            err.error("io_exception", e.getMessage());
+            return false;
+        }
+        
+        for (int i = 0; i < args.length;) {
+            String arg = args[i++];
+            if (arg.equals("-overview")) {
+                set(args, i++);
+            } else if (arg.equals("-public")) {
+                set(arg);
+                if (filter != null) {
+                    err.error("argument_already_seen", arg);
+                } else {
+                    setFilter(AccessChecker.PUBLIC, arg);
+                }
+            } else if (arg.equals("-protected")) {
+                set(arg);
+                if (filter != null) {
+                    err.error("argument_already_seen", arg);
+                } else {
+                    setFilter(AccessChecker.PROTECTED, arg);
+                }
+            } else if (arg.equals("-package")) {
+                set(arg);
+                if (filter != null) {
+                    err.error("argument_already_seen", arg);
+                } else {
+                    setFilter(AccessChecker.PACKAGE, arg);
+                }
+            } else if (arg.equals("-private")) {
+                set(arg);
+                if (filter != null) {
+                    err.error("argument_already_seen", arg);
+                } else {
+                    setFilter(AccessChecker.PRIVATE, arg); 
+                }
+            } else if (arg.equals("-help")) {
+                usage(0);
+            } else if (arg.equals("-sourcepath")) {
+                if (sourcepath != null) {
+                    usage("argument_already_seen", arg);
+                }
+                sourcepath = set(args, i++);
+            }else if (arg.equals("-classpath")) {
+                if (classpath != null) {
+                    usage("argument_already_seen", arg);
+                }
+                classpath = set(args, i++);
+            }else if (arg.equals("-bootclasspath")) {
+                if (bootclasspath != null) {
+                    usage("argument_already_seen", arg);
+                }
+                bootclasspath = set(args, i++); 
+            }else if (arg.equals("-source")) {
+                if (source != null) {
+                    usage("argument_already_seen", arg);
+                }
+                source = set(args, i++);
+            } else if (arg.equals("-extdirs")) {
+                if (extdirs != null) {
+                    usage("argument_already_seen", arg);
+                }
+                extdirs = set(args, i++);
+            } else if (arg.equals("-verbose")) {
+                set(arg);
+                verbosity |= VERBOSE;
+            } else if (arg.equals("-locale")) {
+                if (locale != null) {
+                    usage("argument_already_seen", arg);
+                }
+                set(args, i++);
+            } else if (arg.equals("-encoding")) {
+                if (encoding != null) {
+                    usage("argument_already_seen", arg);
+                }
+                encoding = set(args, i++);
+            } else if (arg.equals("-compiler")) { 
+                err.warning("usage_help", "-compiler option ignored");
+            } else if (arg.equals("-debug")) { 
+                err.warning("usage_help", "-debug option disabled");
+            } else if (arg.startsWith("-J")) { // todo unsupported?
+                if (arg.length() == 2) continue;
+                String rest = arg.substring(2);
+                int ieq = rest.indexOf('=');
+                String key, val;
+                if (ieq != -1) {
+                    key = rest.substring(0, ieq);
+                    val = rest.substring(ieq+1);
+                } else {
+                    key = rest;
+                    val = "";
+                }
+                System.setProperty(key, val);
+            } else if (arg.startsWith("-")) {
+                int optionLength = docletProxy.optionLength(arg);
+                if (optionLength < 0) {
+                    exit();
+                } else if (optionLength == 0) {
+                    usage("invalid_flag", arg);
+                } else if (optionLength > args.length) {
+                    usage("requires_argument", arg, optionLength+"");
+                } else {
+                    List iargs = new ArrayList();
+                    iargs.add(arg);
+                    for (int j = 0; j < optionLength-1; j++) {
+                        iargs.add(args[i++]);
+                    }
+                    set((String[])iargs.toArray(new String[iargs.size()]));
+                }
+            } else {
+                filenamesAndPackages.add(arg);
+            }
+        }
+        if (locale == null) {
+            locale = "";
+        }
+        if (sourcepath == null) {
+            sourcepath = ".";
+        }
+        try {
+            if (!docletProxy.validOptions(options, err)) {
+                exit(1);
+            }
+        } catch (IOException e) {
+            e.printStackTrace(System.err);
+            err.internalError("internal_msg", e);
+            return false;
+        }
+        if (filenamesAndPackages.size() < 1) {
+            usage("No_packages_or_classes_specified");
+            return false;
+        }
+        RootDoc rootDoc = null;
+        boolean good = true;
+        try {
+            rootDoc = makeRootDoc(sourcepath,
+                                  classpath,
+                                  bootclasspath,
+                                  extdirs,
+                                  verbosity,
+                                  encoding,
+                                  locale,
+                                  source,
+                                  filenamesAndPackages,
+                                  options,
+                                  err,
+                                  programName,
+                                  getFilter());
+        } catch (CannotMakeRootDocException e) {
+            err.error("cant_create_root_doc_ex", "AjdocCompiler", e.getMessage());
+            exit(1);
+            good = false;
+        }
+        good &= rootDoc != null;
+        if (good) {
+            err.notice("generating_docs");
+            try {
+                good &= docletProxy.start(rootDoc);
+            } catch (IOException e) {
+                e.printStackTrace(System.err);
+                err.internalError("internal_msg", e);
+                return false;
+            }
+        }
+        if ((verbosity & VERBOSE) != 0) {
+            err.notice("done_in", Long.toString(System.currentTimeMillis()-start));
+        }
+        return good;
+    }
+    
+
+    private void usage(String key, String s0, String s1) {
+        err.error(key, s0, s1);
+        usage(1);
+    }
+
+    private void usage(String key, String s0) {
+        usage(key,s0,"");
+    }
+
+    private void usage(String key) {
+        usage(key,"");
+    }
+
+    private void usage() {
+        err.notice("usage_help", programName);
+        if (docletProxy != null) { docletProxy.optionLength("-help"); }
+    }
+    
+    private void usage(int exit) {
+        usage();
+        exit(exit);
+    }
+
+    protected String[] expandAndCreateDoclet(String[] args) throws IOException {
+        List list = new ArrayList();
+        docletProxy = DocletProxy.DEFAULT;
+        for (int i = 0; i < args.length;) {
+            String arg = args[i++];
+            if (arg == null || arg.length() < 1) continue;
+            if (arg.charAt(0) == '@') {
+                expandAtFile(arg.substring(1), list);
+            } else if (arg.equals("-argfile")) {
+                if (check(args, i)) {
+                    expandAtFile(args[i++], list);
+                }
+            } else if (arg.equals("-doclet")) {
+                err.warning("usage_help", "-doclet option ignored");
+            } else if (arg.equals("-docletpath")) {
+                err.warning("usage_help", "-docletpath option ignored");
+            } else if (arg.equals("-standard")) { 
+                docletProxy = DocletProxy.STANDARD;
+            } else {
+                list.add(arg);
+            }
+        }
+        return (String[])list.toArray(new String[list.size()]);
+    }
+
+    private static boolean check(String[] args, int i) {
+        return i >= 0 && i < args.length;
+    }
+
+    private String set(String[] args, int i) {
+        String arg = null;
+        if (check(args, i)) {
+            arg = args[i];
+            set(args[i-1], arg);
+        } else {
+            err.internalError("internal_error",
+                              new ArrayIndexOutOfBoundsException(i));
+        }
+        return arg;
+    }
+
+    private void set(String opt) {
+        set(new String[]{opt});
+    }
+
+    private void set(String opt, String arg) {
+        set(new String[]{opt, arg});
+    }
+
+    private void set(String[] opts) {
+        options.add(opts);
+    }
+
+    protected void internalCompile(List filenames) {
+        super.internalCompile(filenames);
+    }
+
+    private final void exit() {
+        exit(0);
+    }
+    
+    private void exit(int exit) {
+        throw new ExitRequestException(exit);
+    }
+
+    private static String classname(Object o) {
+        return o != null ? o.getClass().getName() : "null";
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AjdocCompiler.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AjdocCompiler.java
new file mode 100644 (file)
index 0000000..b374587
--- /dev/null
@@ -0,0 +1,605 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.AbstractCompilerPass;
+import org.aspectj.compiler.base.ErrorHandler;
+import org.aspectj.compiler.base.ast.CompilationUnit;
+import org.aspectj.compiler.base.ast.Dec;
+import org.aspectj.compiler.base.ast.Decs;
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.base.ast.World;
+import org.aspectj.compiler.crosscuts.AspectJCompiler;
+
+import com.sun.javadoc.DocErrorReporter;
+import com.sun.javadoc.RootDoc;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * Extension of the AspectJCompiler to provide
+ * functionality for creating documentation.
+ *
+ * @author Jeff Palm
+ */
+public class AjdocCompiler extends AspectJCompiler implements RootDocMaker {
+
+    /** The name of the program. */
+    protected final String programName;
+
+    /** The error printer we use. */
+    protected final ErrPrinter err;
+
+    /**
+     * Construct a new ajdoc compile with the
+     * error handler <code>errorHandler</code> and
+     * name <code>programName</code>
+     *
+     * @param errorHandler the error handler.
+     * @param programName  the name of the program.
+     */
+    public AjdocCompiler(ErrorHandler errorHandler, String programName) {
+        super(errorHandler);
+        getOptions().preprocess = true;
+        getOptions().nocomments = true;
+        (errorHandler = err =
+         new ErrPrinter(this.programName = programName)).
+            setCompiler(this);
+    }
+
+    /**
+     * Construct a new ajdoc compile with the
+     * name <code>programName</code>.
+     *
+     * @param programName the name of the program.
+     */
+    public AjdocCompiler(String programName) {
+        this(null, programName);
+    }
+
+    /**
+     * Returns the ErrPrinter currently used.
+     *
+     * @return the ErrPrinter currently used.
+     */
+    public ErrPrinter err() {
+        return err;
+    }
+
+    /** The packages found on the command line. */
+    private Set pkgnames = new HashSet();
+
+    /** The classes found on the command line and from files. */
+    private Set classnames = new HashSet();
+
+    /** The source files on the command line. */
+    private Set files = new HashSet();
+
+    /** The list of source files to compile. */
+    protected final List srcfiles = new ArrayList();
+
+    /** The list of filenames that came from user-specified source files. */
+    protected List srcSrcfilenames = new ArrayList();
+
+    /** The list of filenames that came from user-specified packages. */
+    protected List pkgSrcfilenames = new ArrayList();
+
+    /** The list of filenames that came from user-specified classes. */
+    protected List clsSrcfilenames = new ArrayList();
+
+    /** The source path with which to search. */
+    protected final List sourcepaths = new ArrayList();
+    {
+        sourcepaths.add(new File("."));
+    }
+    /** The list of filenames that came from user-specified classes. */
+    protected AccessChecker filter;
+
+    /**
+     * Create the RootDoc.
+     */
+    public RootDoc makeRootDoc(String sourcepath,
+                               String classpath,
+                               String bootclasspath,
+                               String extdirs,
+                               long flags,
+                               String encoding,
+                               String locale,
+                               String source,
+                               List filenamesAndPackages,
+                               List options,
+                               DocErrorReporter err,
+                               String programName,
+                               AccessChecker filter)
+        throws CannotMakeRootDocException {
+        if ((null != filter) && (this.filter != filter)) {
+            this.filter = filter;
+        }
+        if (null == this.filter) {
+            this.filter = AccessChecker.PROTECTED;
+        }
+        if (classpath != null) {
+            getOptions().classpath = classpath;
+        }
+        if (bootclasspath != null) {
+            getOptions().bootclasspath = bootclasspath;
+        }
+        if (extdirs != null) {
+            getOptions().extdirs = extdirs;
+        }
+        if (source != null) {
+            getOptions().source = source;
+        }
+        resolveSourcePath(sourcepath);
+        resolveFilesAndPackages(filenamesAndPackages);
+
+        Collections.sort(pkgSrcfilenames);
+        Collections.sort(clsSrcfilenames);
+        Collections.sort(srcSrcfilenames);
+
+        srcfiles.addAll(pkgSrcfilenames);
+        srcfiles.addAll(clsSrcfilenames);
+        srcfiles.addAll(srcSrcfilenames);
+
+        err().notice("starting_internal_compile");
+
+        for (Iterator i = options.iterator(); i.hasNext();) {
+            String[] opts = (String[])i.next();
+            if (opts.length == 1) {
+                if (opts[0].equals("-verbose")) {
+                    getOptions().verbose = true;
+                }
+            } else if (opts.length == 2) {
+                if (opts[0].equals("-classpath")) {
+                    getOptions().classpath = opts[1];
+                } else if (opts[1].equals("-bootclasspath")) {
+                    getOptions().bootclasspath = opts[1];
+                } else if (opts[1].equals("-extdirs")) {
+                    getOptions().extdirs = opts[1];
+                }
+            }
+        }
+
+        // Compile the srcfiles - have to add passes first
+        addPasses();
+        internalCompile(srcfiles);      
+
+        // This is the world with which we create the root
+        World world = getWorld();
+
+        // Add all the classes found in the source files
+        // to the list of specified classnames
+        for (Iterator i = world.getCompilationUnits().iterator();
+             i.hasNext();) {
+            Decs decs = ((CompilationUnit)i.next()).getDecs();
+            for (int j = 0, N = decs.size(); j < N; j++) {
+                Dec dec = decs.get(j);
+                if (dec instanceof TypeDec) {
+                    classnames.add(((TypeDec)dec).getFullName());
+                }
+            }
+        }
+
+        // Initialize and return the root created
+        // from the our world
+        err().notice("creating_root");
+        RootDoc result = init(this, (String[][])options.toArray
+                    (new String[options.size()][]));
+                    
+        // do another pass at RootDoc after constructed 
+        com.sun.javadoc.ClassDoc[] cds = result.classes();
+        for (int i = 0; i < cds.length; i++) {
+            if (cds[i] instanceof ClassDocImpl) {
+                ClassDocImpl cd = (ClassDocImpl) cds[i];
+                cd.postProcess();
+            }
+        }
+        return result;
+    }
+    
+
+    private static AjdocCompiler instance;
+    { instance = this; }
+
+    public static AjdocCompiler instance() {
+        return instance;
+    }
+
+    /**
+     * The entry point to initialize a world created
+     * from an AspectJCompiler.
+     *
+     * @param ajc     the compiler.
+     * @param options the ajdoc options.
+     * @return        a RootDocImpl representing the
+     *                documentation tree.
+     */
+    public static RootDocImpl init(AspectJCompiler ajc, String[][] options) {
+
+        if (ajc == null) return null; //TODO: make empty
+
+        World world = ajc.getWorld();
+
+        Collection classnames = null;
+        Collection pkgnames = null;
+        if (ajc instanceof AjdocCompiler) {
+            AjdocCompiler ajdoc = (AjdocCompiler)ajc;
+            pkgnames = ajdoc.pkgnames;
+            classnames = ajdoc.classnames;
+        }
+
+        PackageDocImpl.init(ajc);
+
+        AccessChecker filter = AccessChecker.PUBLIC;
+        if (ajc instanceof AjdocCompiler) {
+            filter = ((AjdocCompiler) ajc).getFilter();
+        }
+        RootDocImpl root = new RootDocImpl(world,
+                                           options,
+                                           pkgnames,
+                                           classnames,
+                                           filter);
+        return root;
+    }
+
+    /** set filter associated with this compiler */
+    protected void setFilter(AccessChecker filter, String arg) {
+        this.filter = filter;
+    }
+
+    /** get filter associated with this compiler */
+    public final AccessChecker getFilter() {
+        return filter;
+    }
+
+    protected final void expandAtFile(String filename, 
+                                      List args) throws IOException {
+        BufferedReader in  = new BufferedReader(new FileReader(filename));
+        String dirfile = new File(filename).getParent();
+        File basedir = new File(null == dirfile ? "." : dirfile ) ;
+        String line;
+        while ((line = in.readLine()) != null) {
+            if (line == null || line.length() < 1) continue;
+            line = line.trim();
+            if (line.startsWith("//")) continue;
+            if (line.startsWith("#")) continue;
+            if (line.startsWith("@")) {
+                line = line.substring(1);
+                File newfile = new File(line);
+                newfile = newfile.isAbsolute() ?
+                    newfile : new File(basedir, line);
+                expandAtFile(newfile.getPath(), args);
+            } else {
+                File newfile = new File(line);
+                newfile = newfile.isAbsolute() ?
+                    newfile : new File(basedir, line);
+                if (newfile.exists()) {
+                    boolean result = maybeAdd(newfile, args);
+                    if (!result) {
+                        // we only support valid filenames, not options
+                        cantResolve(newfile); 
+                    }
+                } else {
+                    boolean addedFile = false;
+                    FileFilter filter = null;
+                    String name = newfile.getName().trim();
+                    if (name.equals("*.java")) {
+                        filter = new FileFilter() {
+                                    public boolean accept(File f) {
+                                        return f != null &&
+                                            f.getName().endsWith(".java");
+                                    }
+                                };
+                    } else if (name.equals("*.aj")) {
+                        filter = new FileFilter() {
+                                    public boolean accept(File f) {
+                                        return f != null &&
+                                            f.getName().endsWith(".java");
+                                    }
+                                };
+                    } else if (name.equals("*")) {
+                        filter = new FileFilter() {
+                                    public boolean accept(File f) {
+                                        return f != null &&
+                                            (f.getName().endsWith(".java")
+                                            || f.getName().endsWith(".aj"));
+                                    }
+                                };
+                    } 
+                    if (null != filter) {
+                        File parentDir = newfile.getParentFile();
+                        File[] javafiles = parentDir.listFiles(filter);
+                        if (javafiles != null) {
+                            for (int i = 0; i < javafiles.length; i++) {
+                                if (maybeAdd(javafiles[i], args)) {
+                                    if (!addedFile) addedFile = true;
+                                } else {
+                                    cantResolve(javafiles[i]);
+                                }
+                            }
+                        }
+                    }
+                    if (!addedFile) {
+                        if (isValidPkg(line)) {
+                            args.add(line);
+                        } else {
+                            cantResolve(newfile);
+                        }
+                    }
+                }
+            }
+        }
+        in.close();
+    }
+
+    protected final void cantResolve(File f) {
+        err().error("cant_resolve_file", f.getAbsolutePath());
+    }
+
+    private void resolveSourcePath(String sourcepath) {
+        if (sourcepath != null) {
+            sourcepaths.remove(0);
+            for (StringTokenizer t = new StringTokenizer(sourcepath,
+                                                         File.pathSeparator);
+                 t.hasMoreTokens();) {
+                File path = new File(t.nextToken().trim());
+                if (path.exists() && path.isDirectory()) {
+                    sourcepaths.add(path);
+                }
+            }
+            // TODO: don't want this, I think ????
+            //sourcepaths.add(new File("."));
+        }
+    }
+
+    private void resolveFilesAndPackages(List filenamesAndPackages) {
+        Collection pkgnamesFromCmd = new HashSet();
+        for (Iterator i = filenamesAndPackages.iterator(); i.hasNext();) {
+            String str = (String)i.next();
+            File file = new File(str);
+            if (/*file.isAbsolute() &&*/ maybeAdd(file, srcSrcfilenames)) {
+                addFile(file);
+                continue;
+            } else {
+                for (Iterator j = sourcepaths.iterator(); j.hasNext();) {
+                    File sourcepath = (File)j.next();
+                    file = new File(sourcepath, str);
+                    if (maybeAdd(file, srcSrcfilenames)) {
+                        addFile(file);
+                        continue;
+                    }
+                }
+            }
+            pkgnamesFromCmd.add(str);
+        }
+        for (Iterator i = pkgnamesFromCmd.iterator(); i.hasNext();) {
+            resolvePackageOrClass((String)i.next());
+        }
+    }
+
+    private void resolvePackageOrClass(String pkgOrClassName) {
+        boolean recurse;
+        String pkgOrClass =
+            (recurse = (pkgOrClassName.endsWith(".*"))) ?
+            pkgOrClassName.substring(0, pkgOrClassName.length()-2) :
+            pkgOrClassName;
+        for (Iterator i = sourcepaths.iterator(); i.hasNext();) {
+            File sourcepath = (File)i.next();
+            File possiblePkg = new File(sourcepath,
+                                        pkgOrClass.replace
+                                        ('.', File.separatorChar));
+            if (possiblePkg.exists() && possiblePkg.isDirectory()) {
+                if (recurse) {
+                    File[] dirs = possiblePkg.listFiles
+                        (new FileFilter() {
+                                public boolean accept(File f) {
+                                    return f != null && f.isDirectory();
+                                }
+                            });
+                    for (int j = 0; j < dirs.length; j++) {
+                        String pkgname = pkgOrClass + '.' + dirs[j].getName();
+                        resolvePackageOrClass(pkgname + ".*");
+                    }
+                }
+                File[] javafiles = possiblePkg.listFiles
+                    (new FileFilter() {
+                            public boolean accept(File f) {
+                                return f != null && !f.isDirectory();
+                            }
+                        });
+                if (javafiles.length > 0) {
+                    pkgnames.add(pkgOrClass);
+                }
+                boolean addedPkg = false;
+                for (int j = 0; j < javafiles.length; j++) {
+                    if (maybeAdd(javafiles[j], pkgSrcfilenames) && !addedPkg) {
+                        addPkg(pkgOrClass, javafiles[j]);
+                        addedPkg = true;
+                    }
+                }
+                break;
+            } else {
+                String pkgname = "";
+                String classname = pkgOrClass;
+                int ilastdot = pkgOrClass.lastIndexOf('.');
+                if (ilastdot != -1) {
+                    pkgname =  pkgOrClass.substring(0, ilastdot).
+                        replace('.', File.separatorChar) + File.separatorChar;
+                    classname = pkgOrClass.substring(ilastdot+1);
+                }
+                File file = new File(sourcepath,
+                                     pkgname + classname + ".java");
+                if (maybeAdd(file, clsSrcfilenames)) {
+                    addClass(pkgOrClass, file);
+                    break;
+                }
+            }
+        }
+    }
+
+    protected final File findFile(String filename, boolean isDir) {
+        for (Iterator i = sourcepaths.iterator(); i.hasNext();) {
+            File sourcepath = (File)i.next();
+            File file = new File(sourcepath, filename);
+            if (file.exists() && !(isDir ^ file.isDirectory())) {
+                return file;
+            }
+        }
+        return null;
+    }
+
+    protected static boolean maybeAddPkg(String pkgname,
+                                         Collection pkgnames) {
+        if (isValidPkg(pkgname)) {
+            pkgnames.add(pkgname);
+            return true;
+        }
+        return false;
+    }
+
+    protected final Map filesToClassnames = new HashMap();
+    protected final void addClass(String classname, File file) {
+        if (!(maybeAddClass(classname))) {
+            err().error("invalid_class_name", classname);
+        } else {
+            filesToClassnames.put(file.getAbsoluteFile(), classname);
+        }
+    }
+
+    protected final boolean maybeAddClass(String classname) {
+        return maybeAddClass(classname, classnames);
+    }
+
+    protected static boolean maybeAddClass(String classname,
+                                           Collection classnames) {
+        if (isValidClass(classname)) {
+            classnames.add(classname);
+            return true;
+        }
+        return false;
+    }
+
+    protected final static boolean isValidClass(String classname) {
+        return isValidPkg(classname);
+    }
+
+    protected final Map filesToPkgnames = new HashMap();
+    protected final void addPkg(String pkgname, File file) {
+        if (!maybeAddPkg(pkgname)) {
+            err().error("invalid_package_name", pkgname);
+        } else {
+            filesToPkgnames.put(file.getAbsoluteFile(), pkgname);
+       }
+    }
+
+    protected final boolean maybeAddPkg(String pkgname) {
+        return maybeAddPkg(pkgname, pkgnames);
+    }
+
+    protected final Map filesToFilenames = new HashMap();
+    protected final void addFile(File file) {
+        files.add(file);
+        filesToFilenames.put(file.getAbsoluteFile(), file.getAbsolutePath());
+    }
+
+    protected static boolean maybeAdd(File file, Collection files) {
+        if (isValidJavaFile(file)) {
+            files.add(file.getAbsolutePath());
+            return true;
+        }
+        return false;
+    }
+
+    protected final static boolean isValidJavaFile(File file) {
+        return file != null && file.exists() && !file.isDirectory()
+            && (file.getName().endsWith(".java")
+                || file.getName().endsWith(".aj")) ;
+    }
+
+    protected final static boolean isValidPkg(String pkgname) {
+        if (pkgname == null) {
+            return false;
+        }
+        if (pkgname.length() < 1) {
+            return true;
+        }
+        if (!Character.isJavaIdentifierStart(pkgname.charAt(0))) {
+            return false;
+        }
+        for (int i = 1; i < pkgname.length(); i++) {
+            char c = pkgname.charAt(i);
+            if (c == '.' && i == pkgname.length()-1) {
+                return false;
+            }
+            if (!(c == '.' || Character.isJavaIdentifierPart(c))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    protected void loading(CompilationUnit cu) {
+        File srcfile = cu.getSourceFile().getAbsoluteFile();
+        String pkgname, classname, filename;
+        if ((pkgname = (String)filesToPkgnames.get(srcfile))!= null) {
+            AjdocCompiler.this.err().notice
+                ("Loading_source_files_for_package", pkgname);
+        } else if ((classname = (String)filesToClassnames.get(srcfile)) != null) {
+            AjdocCompiler.this.err().notice
+                ("Loading_source_file_for_class", classname);
+        } else if ((filename = (String)filesToFilenames.get(srcfile)) != null) {
+            AjdocCompiler.this.err().notice
+                ("Loading_source_file", filename);
+        }
+    }
+
+    protected AbstractCompilerPass createParserPass() {
+        return new PrintingParserPass(this);
+    }
+    
+    protected static class PrintingParserPass extends AspectJCompiler.ParserPass {
+        public PrintingParserPass(AjdocCompiler jc) { super(jc); }
+        public void transform(CompilationUnit cu) {
+            ((AjdocCompiler)getCompiler()).loading(cu);
+            super.transform(cu);
+        }
+    }
+
+    protected void addPasses() {
+        passes = new ArrayList();
+        addPreSymbolPasses();
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AspectDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/AspectDocImpl.java
new file mode 100644 (file)
index 0000000..f603476
--- /dev/null
@@ -0,0 +1,300 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.AdviceDoc;
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.IntroductionDoc;
+import org.aspectj.ajdoc.OfClauseDoc;
+import org.aspectj.compiler.base.ast.Decs;
+import org.aspectj.compiler.crosscuts.ast.AdviceDec;
+import org.aspectj.compiler.crosscuts.ast.AspectDec;
+import org.aspectj.compiler.crosscuts.ast.IntroducedSuperDec;
+
+import com.sun.javadoc.ClassDoc;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+public class AspectDocImpl extends ClassDocImpl implements AspectDoc {
+
+    /** Array of AdviceDoc created from this AspectDecs AdviceDecs. */
+    private final Collection advice;
+
+    /** Array of IntroductionDec created from this AspectDecs introductions. */
+    private final Collection introductions;
+
+    /** The of clause this aspect has -- may be null. */
+    private final OfClauseDoc ofClause;
+
+    /** The aspects that dominate this aspect. */
+    private final Collection dominators = new ArrayList();
+
+    /** The aspects that are dominated by this aspect. */
+    private final Collection dominatees = new ArrayList();
+
+    /**
+     * Constructs an AspectDoc with the containing ClassDoc
+     * and underlying AspectDec.
+     *
+     * @param containingClass contained ClassDoc.
+     * @param aspectDec       underlying AspectDec.
+     */
+    public AspectDocImpl(ClassDoc containingClass, AspectDec aspectDec) {
+        super(containingClass, aspectDec);
+        introductions = createIntroductions();
+        advice = createAdvice();
+        ofClause = createOfClause();
+    }
+
+    /**
+     * Returns an instance of AdviceDocImpl corresponding to
+     * the AdviceDec passed in.
+     *
+     * @param dec the AdviceDec mapping to the desired
+     *            AdviceDocImpl.
+     * @return    an instance of AdviceDocImpl corresponding to
+     *            the AdviceDec passed in.
+     */
+    public AdviceDocImpl docForDec(AdviceDec dec) {
+        for (Iterator i = advice.iterator(); i.hasNext();) {
+            AdviceDocImpl ad = (AdviceDocImpl)i.next();
+            if (ad.dec() == dec) return ad;
+        }
+        return null;
+    }
+
+    /**
+     * Returns an instance of IntroducedSuperDocImpl corresponding to
+     * the IntroducedSuperDec passed in.
+     *
+     * @param  dec the IntroducedSuperDec mapping to the
+     *             desired IntroducedSuperDocImpl
+     * @return     an instance of IntroducedSuperDocImpl
+     *             corresponding to the IntroducedSuperDec
+     *             passed in.
+     */
+    public IntroducedSuperDocImpl introDocForDec(IntroducedSuperDec dec) {
+        for (Iterator i = introductions.iterator(); i.hasNext();) {
+            ProgramElementDocImpl id = (ProgramElementDocImpl)i.next();
+            if (id.dec() == dec) return (IntroducedSuperDocImpl)id;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the underlying AspectDec.
+     *
+     * @return the underlying AspectDec.
+     */
+    protected AspectDec aspectDec() {
+        return (AspectDec)typeDec();
+    }
+
+    /**
+     * Returns the visible advice in this aspect.
+     *
+     * @return an array of AdviceDoc representing the
+     *         visible advice in this aspect.
+     */
+    public AdviceDoc[] advice() {
+        return (AdviceDocImpl[])advice.toArray
+            (new AdviceDocImpl[advice.size()]);
+    }
+
+    /**
+     * Returns the aspects that are dominated by this aspect.
+     *
+     * @return an array of AspectDec representing the aspects
+     *         that are dominated by this aspect.
+     */
+    public AspectDoc[] dominatees() {
+        return (AspectDoc[])dominatees.toArray
+            (new AspectDoc[dominatees.size()]);
+    }
+   
+    /**
+     * Return the aspects that dominate this aspect.
+     *
+     * @return an array of AspectDoc representing the aspects
+     *         that dominate this aspect.
+     */
+    public AspectDoc[] dominators() {
+        return (AspectDoc[])dominators.toArray
+            (new AspectDoc[dominators.size()]);
+    }
+
+    /**
+     * TODO
+     * Returns the visible introductions of this aspect.
+     *
+     * @return an array of IntroductionDoc representing the
+     *         visible introductions in this aspect.
+     */
+    public IntroductionDoc[] introductions() {
+        return (IntroductionDocImpl[])introductions.toArray
+            (new IntroductionDocImpl[introductions.size()]);
+    }
+
+    /**
+     * Returns the <i>of clause</i> of this aspect.
+     *
+     * @return the <i>of clause</i> of this aspect.
+     */
+    public OfClauseDoc ofClause() {
+        return ofClause;
+    }
+
+    /**
+     * Returns <code>true</code>.
+     *
+     * @return <code>true</code>.
+     */
+    public boolean isAspect() {
+        return true;
+    }
+
+    /**
+     * Returns <code>true</code> if this aspects dominates
+     * the passed in aspect.
+     *
+     * @param other an AspectDoc that represents another
+     *              aspect in this world.
+     * @return      <code>true</code> if this aspects dominates
+     *              the passed in aspect.
+     */
+    public boolean dominates(AspectDoc other) {
+        if (!(other instanceof AspectDocImpl)) {
+            return false;
+        }
+        return aspectDec().dominates(((AspectDocImpl)other).aspectDec());
+    }
+
+    /**
+     * Adds a dominates relation from <code>dominator</code> to
+     * <code>this</code>.  For example, somewhere in the code
+     * the line
+     * <code>
+     *       aspect dominator dominates this { ... }
+     * </code>
+     * exists.
+     *
+     * @param dominator an instance of AspectDocImpl that
+     *                  dominates this.
+     */
+    public void addDominator(AspectDoc dominator) {
+        dominators.add(dominator);
+    }
+
+    /**
+     * Adds a dominates relation from <code>dominator</code> to
+     * <code>this</code>.  For example, somewhere in the code
+     * the line
+     * <code>
+     *       aspect this dominates dominatee { ... }
+     * </code>
+     * exists.
+     *
+     * @param dominatee an instance of AspectDocImpl that
+     *                  is dominated by this.
+     */
+    public void addDominatee(AspectDoc dominatee) {
+        dominatees.add(dominatee);
+    }
+
+    /**
+     * Returns a Collection of IntroductionDocImpl representing
+     * the introductions declared in this aspect.
+     *
+     * @return a Collection of IntroductionDocImpl representing
+     *         the introductions declared in this aspect.
+     */
+    private Collection createIntroductions() {
+        Decs decs = aspectDec().getBody();
+        if (decs.size() < 1) return Collections.EMPTY_LIST;
+        Collection list = new HashSet();
+        for (Iterator i = decs.getList().iterator(); i.hasNext();) {
+            Object o = IntroductionDocImpl.getInstance(this, i.next());
+            if (o != null) list.add(o);
+        }
+        return list;
+    }
+
+    /**
+     * Returns a Collection of AdviceDocImpl representing
+     * the advice declared in this aspect.
+     *
+     * @return a Collection of AdviceDocImpl representing
+     *         the advice declared in this aspect.
+     */
+    private Collection createAdvice() {
+        // pluck the AdviceDec from the list of JpPlannerMakers
+        List decs = aspectDec().getJpPlannerMakers();
+        if (null != decs) {
+            final int QUIT = 2;
+            for (int tries = 0; tries < QUIT; tries++) {
+                try {
+                    for (Iterator i = decs.iterator(); i.hasNext();) {
+                        Object o = i.next();
+                        if (!(o instanceof AdviceDec)) {
+                            i.remove(); 
+                        }
+                    }
+                    tries = QUIT;
+                } catch (UnsupportedOperationException o) {
+                    if (0 != tries) {
+                        tries = QUIT;
+                    } else {
+                        ArrayList list = new ArrayList();
+                        list.addAll(decs);
+                        decs = list;
+                    }
+                }
+            }
+        }
+        
+        if ((null == decs) || (decs.size() < 1)) {
+            return Collections.EMPTY_LIST;
+        }
+
+        List list = new ArrayList();
+        for (Iterator i = decs.iterator(); i.hasNext();) {
+            list.add(new AdviceDocImpl(this, (AdviceDec)i.next()));
+        }
+        return list;
+    }
+
+    /**
+     * Returns an instance of OfClauseDoc representing
+     * the of clause declared by this aspect.
+     *
+     * @return an instance of OfClauseDoc representing
+     *         the of clause declared by this aspect.
+     */
+    private OfClauseDoc createOfClause() {
+        return OfClauseDocImpl.getInstance(aspectDec().getPerClause());
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/CannotMakeRootDocException.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/CannotMakeRootDocException.java
new file mode 100644 (file)
index 0000000..646f5d3
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+/**
+ * A simple wrapper exception to be thrown when we
+ * can't make a RootDoc.
+ *
+ * @see    RootDocMaker#makeRootDoc
+ * @author Jeff Palm
+ */
+public class CannotMakeRootDocException  extends RuntimeException {
+
+    /**
+     * Constructs an empty exception.
+     */
+    public CannotMakeRootDocException() {
+        super();
+    }
+
+    /**
+     * Constructs an exception with message <code>message</code>
+     * and a <code>null</code> contained Throwable
+     *
+     * @param message Message to use.
+     */
+    public CannotMakeRootDocException(String message) {
+        this(message, null);
+    }
+
+    /**
+     * Constructs an exception with message <code>message</code>
+     * an contained Throwable <code>throwable</code>.
+     *
+     * @param message   Message to use.
+     * @param throwable Throwable to use.
+     */
+    public CannotMakeRootDocException(String message, Throwable throwable) {
+        super((message != null ? message : "") +
+              (throwable != null ? ":" + throwable : ""));
+    }
+
+    /**
+     * Constructs an exception with <code>null</code> message
+     * an contained Throwable <code>throwable</code>.
+     *
+     * @param throwable Throwable to use.
+     */
+    public CannotMakeRootDocException(Throwable t) {
+        this(null, t);
+    }
+
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ClassDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ClassDocImpl.java
new file mode 100644 (file)
index 0000000..7e8c213
--- /dev/null
@@ -0,0 +1,1107 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.IntroducedSuperDoc;
+import org.aspectj.ajdoc.PointcutDoc;
+import org.aspectj.compiler.base.ast.ClassDec;
+import org.aspectj.compiler.base.ast.CodeDec;
+import org.aspectj.compiler.base.ast.CompilationUnit;
+import org.aspectj.compiler.base.ast.Constructor;
+import org.aspectj.compiler.base.ast.ConstructorDec;
+import org.aspectj.compiler.base.ast.Dec;
+import org.aspectj.compiler.base.ast.Field;
+import org.aspectj.compiler.base.ast.FieldDec;
+import org.aspectj.compiler.base.ast.Import;
+import org.aspectj.compiler.base.ast.Imports;
+import org.aspectj.compiler.base.ast.InterfaceDec;
+import org.aspectj.compiler.base.ast.Method;
+import org.aspectj.compiler.base.ast.NameType;
+import org.aspectj.compiler.base.ast.SourceLocation;
+import org.aspectj.compiler.base.ast.TextSourceLocation;
+import org.aspectj.compiler.base.ast.Type;
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.crosscuts.AspectJCompiler;
+import org.aspectj.compiler.crosscuts.ast.AspectDec;
+import org.aspectj.compiler.crosscuts.ast.IntroducedSuperDec;
+import org.aspectj.compiler.crosscuts.ast.PointcutSO;
+
+import org.aspectj.ajdoc.ClassDoc;
+import com.sun.javadoc.ConstructorDoc;
+import com.sun.javadoc.FieldDoc;
+import com.sun.javadoc.MethodDoc;
+import com.sun.javadoc.PackageDoc;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This implements ClassDoc and acts as a factory for ClassDocImpl
+ * and associated DocImpl.
+ * The factory will excluded new superclasses and introduction classes
+ * so the caller should take care to include those classes explicitly
+ * by adding them directly before they are sought indirectly or
+ * by post-processing them to enable inclusion as appropriate.
+ */
+public class ClassDocImpl
+    extends ProgramElementDocImpl
+    implements org.aspectj.ajdoc.ClassDoc {
+
+    /**
+     * Returns an instance of ClassDoc represented by
+     * the passed in TypeDec.
+     *
+     * @param typeDec instance of TypeDec representing
+     *                the ClassDoc that will be returned.
+     * @return        an instance of ClassDoc mirroring
+     *                the passed in TypeDec.
+     */    
+    public final static ClassDocImpl getInstance(TypeDec typeDec) {
+        return factory.getInstance(typeDec);
+    }
+
+    /**
+     * Returns an instance of ClassDoc represented by
+     * the passed in TypeDec and containing ClassDoc (may be null).
+     *
+     * @param outerDoc the containing ClassDoc -- may be null.
+     * @param typeDec  instance of TypeDec representing
+     *                 the ClassDoc that will be returned.
+     * @return         an instance of ClassDoc mirroring
+     *                 the passed in TypeDec.
+     */  
+    public final static ClassDocImpl getInstance(ClassDoc outerDoc, TypeDec typeDec) {
+        return factory.getInstance(outerDoc, typeDec);
+    }
+
+    /**
+     * Returns the known ClassDocImpl for a given String --
+     * the returned value may be null.
+     *
+     * @return the known ClassDocImpl for a given String --
+     *         the returned value may be null.
+     */
+    public final static ClassDocImpl find(String qualifiedName) {
+        return factory.find(qualifiedName);
+    }
+
+    /**The factory used to create instances of this class. */
+    private final static Factory factory = new Factory();
+
+    /** The ClassDec to which is delegated. */
+    private final TypeDec typeDec;
+
+    // todo: we know these Collections are FilteredDecList, so declare that?
+    /** The introductions that affect a ClassDoc. */
+    private Collection introducers;
+
+    /** The array of fields visible in this type. */
+    private Collection fieldDocs;
+
+    /** The array of methods visible in this type. */
+    private Collection methodDocs;
+
+    /** The array of constructors visible in this type. 
+      * The implementation must support iterator().remove().
+      */
+    private Collection constructorDocs;
+
+    /** The array of inner classes visible in thie type. */
+    private Collection innerclassDocs;
+
+    /** The array of interfaces this type implements. */
+    private Collection interfaceDocs;
+
+    /** The array of classes this type imports on demand. */
+    private Collection importedClasses;
+
+    /** The array of package this type imports on demand. */
+    private Collection importedPackages;
+
+    /** The array of pointcuts visible in this type. */
+    private Collection pointcutDocs;
+
+    /** cached variant of <code>((AjdocCompiler)ajc()).getFilter()</code> */
+    private AccessChecker filter;
+    
+    /**
+     * Constructs a representation of an AspectJ-compiled class
+     * using the underlying TypeDec and containning ClassDoc.
+     * NOTE: This is protected (and maybe should be private)
+     * because the static method {@link #getInstance(TypeDec)}
+     * should always be used to get instances of this type.  It
+     * ensures that enclosing types are created before their
+     * enclosed types.
+     *
+     * @param containingClass ClassDoc that encloses this.
+     * @param typeDec         The underlying TypeDec.
+     */
+    protected ClassDocImpl(com.sun.javadoc.ClassDoc containingClass,
+                           TypeDec typeDec) {
+        super(containingClass);
+        this.typeDec = typeDec;
+        //AccessChecker check = getFilter();
+        // RootDocImpl sets inclusion of world classes
+        setIncluded(false); 
+        // have to install before creating imports to avoid cycles
+        factory.put(this, typeDec);
+        createImports(importedClasses  = new ArrayList(),
+                      importedPackages = new ArrayList());
+    }
+
+    /**
+     * Maps Decs to their counterpart by testing with
+     * <code>instanceof</code>
+     *
+     * @return a MemberDocImpl that has an underlying Dec dec.
+     */
+    public MemberDocImpl docForDec(Dec dec) {
+        if (dec instanceof FieldDec) {
+            return docForDec((FieldDec)dec);
+        }
+        if (dec instanceof CodeDec) {
+            return docForDec((CodeDec)dec);
+        }
+        // todo: map for inner classes, Type, etc?
+        return null; //TODO error ???
+    }
+
+    /**
+     * Returns a FieldDocImpl that has an underlying FieldDec dec.
+     *
+     * @return a FieldDocImpl that has an underlying FieldDec dec.
+     */
+    public FieldDocImpl docForDec(FieldDec dec) {
+        FieldDoc[] fs = fields();
+        for (int i = 0; i < fs.length; i++) {
+            FieldDocImpl fd = (FieldDocImpl)fs[i];
+            if (fd.dec() == dec) return fd;
+        }
+        return null;
+    }
+
+    /**
+     * Returns a CodeDocImpl that has an underlying CodeDec dec.
+     *
+     * @return a CodeDocImpl that has an underlying CodeDec dec.
+     */
+    public CodeDocImpl docForDec(CodeDec dec) {
+        MethodDoc[] ms = methods();
+        for (int i = 0; i < ms.length; i++) {
+            CodeDocImpl cd = (CodeDocImpl)ms[i];
+            if (cd.dec() == dec) return cd;
+        }
+        ConstructorDoc[] cs = constructors();
+        for (int i = 0; i < cs.length; i++) {
+            CodeDocImpl cd = (CodeDocImpl)cs[i];
+            if (cd.dec() == dec) return cd;
+        }
+        return null;
+    }
+
+    /**
+     * @todo ??????
+     */
+    public TypeDec nonNullTypeDec() {
+        if (typeDec().getLexicalType() == null) return typeDec();
+        return super.nonNullTypeDec();
+    }
+
+    /**
+     * Returns a Collection of ClassDocImpls that have corresponding
+     * ClassDecs declared within classDec().
+     *
+     * @return a Collection of ClassDocImpls that have corresponding
+     *         ClassDecs declared within classDec().
+     */
+    private Collection createInnerTypes() {
+        Collection items = ((NameType)typeDec.getType()).getInnerTypes();
+        FilteredDecList result = 
+            new FilteredDecList(getFilter(), this);
+        if (items != null) {
+            for (Iterator i = items.iterator(); i.hasNext();) {
+                result.add(((NameType)i.next()).getTypeDec());
+            }
+        }
+        Collections.sort(result);
+        return result;
+    }
+
+    /**
+     * Creates the two collection of imports -- class and packages --
+     * used by the file in which classDec() was declared.
+     *
+     * @param importClasses the classes to fill.
+     * @param importPkgs    the packages to fill.
+     */
+    private void createImports(final Collection importClasses,
+                               final Collection importPkgs) {
+        CompilationUnit cu = typeDec.getCompilationUnit();
+        if (cu != null) {
+            Imports imports = cu.getImports();
+            if (imports != null) {
+                for (int i = 0; i < imports.size(); i++) {
+                    Import imprt = imports.get(i);
+                    if (imprt != null) {
+                        if (imprt.getStar()) {
+                            PackageDoc importedPkg =
+                                PackageDocImpl.getPackageDoc
+                                (imprt.getName());
+                            if (importedPkg != null) {
+                                importPkgs.add(importedPkg);
+                            }
+                        } else {
+                            com.sun.javadoc.ClassDoc importedClass =
+                                findClass(imprt.getName());
+                            if (importedClass != null) {
+                                importClasses.add(importedClass);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns a Collection of ClassDocImpl representing the
+     * interfaces the underlying TypeDec implements.
+     *
+     * @return a Collection of ClassDocImpl representing the
+     *         interfaces the underlying TypeDec implements.
+     */
+    private Collection createInterfaces() {
+        //NameType type = (NameType)typeDec.getType();
+        Collection items = typeDec.getSuperInterfaceTypes();
+        FilteredDecList result = 
+            new FilteredDecList(getFilter(), this);
+        if (items != null) {
+            for (Iterator i = items.iterator(); i.hasNext();) {
+                result.add(((NameType)i.next()).getTypeDec());
+            }
+        }
+        Collections.sort(result);
+        return result;
+    }
+
+    /** 
+     * Called by AjdocCompiler to do pruning once the whole world is created.
+     * This avoids using aspect before initialized when 
+     * this classdoc constructed as a result of aspect
+     * initialization.
+     */
+    void postProcess() {
+        // prune compiler-generated default constructor if unadvised.
+        // can't do this on construction since advising aspect may exist but be uninitialized
+        final SourceLocation parentLoc = dec().getSourceLocation();
+        final int parentLine = (null == parentLoc ? -1 : parentLoc.getBeginLine());
+        final int parentColumn = (null == parentLoc ? -1 : parentLoc.getBeginColumn());
+        if (null == constructorDocs) {
+            if (null == constructors()) {
+                // XXX harmless error System.err.println("Unable to post-process");
+                return; 
+            }
+        }
+        try {
+            //ArrayList removed = new ArrayList();
+            for (Iterator i = constructorDocs.iterator(); i.hasNext(); ) {
+                ConstructorDocImpl cdi = (ConstructorDocImpl) i.next();
+                CodeDec cd = cdi.codeDec();
+                SourceLocation sl = (null == cd ? null : cd.getSourceLocation());
+                // if ajc changes so typedec start/end not equal to constructor, then can't recognize
+                if ((null != sl) 
+                    && (parentColumn == sl.getBeginColumn())
+                    && (parentLine == sl.getBeginLine())) {
+                    Object[] advice = cdi.advice();
+                    if ((null != advice) && (1 > advice.length)) {
+                        i.remove();                    
+                        //removed.add(cdi);
+                        //System.err.println("removing unadvised generated constructor: " + cdi);
+                    } else {
+                        //System.err.println("keeping advised generated constructor: " + cdi);
+                    }
+                } else {
+                     //System.err.println("keeping ungenerated constructor: " + cdi);
+                }
+            }
+//            for (Iterator i = removed.iterator(); i.hasNext();) {
+//                Object dec = i.next();
+//                             if (constructorDocs.contains(dec)) {
+//                    throw new Error("remove failed for " + dec);
+//                }                            
+//                     }
+        } catch (UnsupportedOperationException e) {
+            System.err.println("Warning: ClassDocImpl.constructorDocs not removable");
+        }
+    }
+    
+    /**
+     * Returns a Collection of ConstructorDocImpl representing the
+     * constructors the underlying TypeDec declares.
+     *
+     * @return a Collection of ConstructorDocImpl representing the
+     *         constructors the underlying TypeDec declares.
+     */
+    private Collection createConstructors() {
+        NameType type = (NameType)typeDec.getType();
+        Collection items = type.getConstructors();
+        final SourceLocation parentLoc = dec().getSourceLocation();
+        final int parentLine = (null == parentLoc ? -1 : parentLoc.getBeginLine());
+        final int parentColumn = (null == parentLoc ? -1 : parentLoc.getBeginColumn());
+        FilteredDecList result = 
+            new FilteredDecList(getFilter(), this);
+        if (items != null) {
+            for (Iterator i = items.iterator(); i.hasNext();) {
+                Constructor c = (Constructor) i.next();
+                ConstructorDec cd = c.getConstructorDec();
+                ConstructorDocImpl impl = new ConstructorDocImpl(this, cd);
+                // XXX workaround for ajc bug of default constructor source location
+                SourceLocation sl = (null == cd ? null : cd.getSourceLocation());
+                // if line/column starts the same, then a generated constructor
+                if ((null != sl) 
+                    && (parentColumn == sl.getBeginColumn())
+                    && (parentLine == sl.getBeginLine())) {
+                        // use source location clone without comment from class                        
+                        TextSourceLocation tsl = new TextSourceLocation(sl.getCompilationUnit(),
+                            sl.getStartPosition(), sl.getEndPosition());
+                        tsl.clearComment();
+                        cd.setSourceLocation(tsl);
+                } 
+                result.add(impl);
+            }
+        }
+        Collections.sort(result);
+        return result;
+    }
+    
+    /**
+     * Returns a Collection of PointcutDocImpl representing the
+     * pointcuts the underlying TypeDec declares.
+     *
+     * @return a Collection of PointcutDocImpl representing the
+     *         pointcuts the underlying TypeDec declares.
+     */
+    private Collection createPointcuts() {
+        NameType type = (NameType)typeDec.getType();
+        Collection items = type.getPointcuts();
+        FilteredDecList result = 
+            new FilteredDecList(getFilter(), this);
+        if (items != null) {
+            for (Iterator i = items.iterator(); i.hasNext();) {
+                result.add(((PointcutSO)i.next()).getPointcutDec());
+            }
+        }
+        Collections.sort(result);
+        return result;
+    }
+
+    /**
+     * Returns a Collection of MethodDocImpl representing the
+     * methods the underlying TypeDec declares.
+     *
+     * @return a Collection of MethodDocImpl representing the
+     *         methods the underlying TypeDec declares.
+     */
+    private Collection createMethods() {
+        NameType type = (NameType)typeDec.getType();
+        Collection methods = type.getMethods();
+        FilteredDecList result = 
+            new FilteredDecList(getFilter(), this);
+        if (methods != null) {
+            for (Iterator i = methods.iterator(); i.hasNext();) {
+                result.add(((Method)i.next()).getMethodDec());
+            }
+        }
+        Collections.sort(result);
+        return result;
+    }
+
+    /**
+     * Returns a Collection of FieldDocImpl representing the
+     * fields the underlying TypeDec declares.
+     *
+     * @return a Collection of FieldDocImpl representing the
+     *         fields the underlying TypeDec declares.
+     */
+    private Collection createFields() {
+        NameType type = (NameType)typeDec.getType();
+        Collection fields = type.getFields();
+        FilteredDecList result = 
+            new FilteredDecList(getFilter(), this);
+        if (fields != null) {
+            for (Iterator i = fields.iterator(); i.hasNext();) {
+                result.add(((Field)i.next()).getFieldDec());
+            }
+        }
+        Collections.sort(result);
+        return result;
+    }
+
+    /** return (and cache) filter from ajc() */
+    protected AccessChecker getFilter() {
+        // nb: called during construction
+        if (null == filter) {
+            AspectJCompiler ajc = ajc();
+            if (ajc instanceof AjdocCompiler) {
+                filter = ((AjdocCompiler) ajc).getFilter();
+            }
+        }
+        return filter; // still may be null
+    }
+
+    /**
+     * Returns the underlying Dec -- a TypeDec.
+     *
+     * @return the underlying Dec -- a TypeDec.
+     */
+    protected final Dec dec() {
+        return typeDec();
+    }
+    
+    /**
+     * Returns the underlying TypeDec.
+     *
+     * @return the underlying TypeDec.
+     */
+    public final TypeDec typeDec() {
+        return typeDec;
+    }
+
+    /**
+     * Returns the fully-qualified name of this TypeDec including
+     * the package and any enclosing classes.
+     *
+     * @return the fully-qualified name of this TypeDec including
+     *         the package and any inclosing classes.
+     */
+    public String qualifiedName() {
+        return qualifiedTypeName().replace('$','.');
+    }
+
+    /**
+     * Returns the fully-qualfied name of this class.
+     *
+     * @return the fully-qualfied name of this class.
+     */
+    public String toString() {
+        return qualifiedName();
+    }
+
+    /**
+     * Returns the single name of this TypeDec excluding the package
+     * but including enclosing classes.  NOTE:  All dollar signs
+     * are replaced by periods.
+     *
+     * @return the single name of this TypeDec excluding the package
+     *         but including enclosing classes.
+     */
+    public String name() {
+        return ((NameType)typeDec().getType()).
+            getExtendedId().replace('$','.');
+    }
+
+    /**
+     * Returns the class specified by <code>classname</code>
+     * from the context of <code>this</code>. This method may return
+     * <code>null</code> denoting the class wasn't found.
+     * Search proceeds in the following order:
+     * 
+     * <ul><ll>
+     * <li>qualified name</li>
+     * <li>in this class (inner)</li>
+     * <li>in this package</li>
+     * <li>in the class imports</li>
+     * <li>in the package imports</li>
+     * </ll></ul>
+     *
+     * @return the type specified by <code>classname</code>
+     *         from the context of <code>this</code>.
+     * @see    Util#findClass(ClassDoc,String,JavaCompiler)
+     * @see    <a href="http://java.sun.com/products/jdk/1.2/docs/tooldocs">
+     *         Javadoc Tool Homepage</a>
+     */
+    public com.sun.javadoc.ClassDoc findClass(String classname) {
+        // Sanity check
+        if (classname == null || classname.length() < 1) {
+            return null;
+        }
+
+        // The result
+        com.sun.javadoc.ClassDoc desired;
+
+        // [0] The trivial case, the classname is this class
+        if (classname.equals(name()) ||
+            classname.equals(qualifiedName())) {
+            return this;
+        }
+
+        // [1] Look up the fully qualified name.
+        if ((desired = ClassDocImpl.find(classname)) != null) {
+            return desired;
+        }
+
+        // [2] Search the inner classes.  We can assume that if
+        // classname refers to an inner class it is unqualified
+        // with respect to its package, because step [1] would have
+        // picked it up, then.  First look to see if the name
+        // matches, then search the inner class itself.  We check two
+        // values:
+        //  [1] innername: the unqualified inner class name
+        //  [2] classname: the qualified (with outer class) name
+        //  Example:
+        //           /**
+        //            * @see Inner
+        //            *   // classname == Inner              (f'cked)
+        //            *   // innername == Outer.Inner          (ok)
+        //            * @see Outer.Inner
+        //            *   // classname == Outer.Inner          (ok)
+        //            *   // innername == Outer.Outer.Inner  (f'cked)
+        //           class Outer {
+        //             static class Inner {}
+        //           }
+        String innername = name() + '.' + classname;
+        com.sun.javadoc.ClassDoc[] inners = innerClasses();
+        if (inners != null) {
+            for (int i = 0; i < inners.length; i++) {
+                if (classname.equals(inners[i].name()) ||
+                    innername.equals(inners[i].name())) {
+                    return inners[i];
+                }
+            }
+        }
+
+        // [3] Search in this package
+        if ((desired = containingPackage().findClass(classname)) != null) {
+            return desired;
+        }
+
+        // [4] Search the class imports. The order for this is specified
+        // by the compiler -- if you don't believe me read for yourself:
+        // http://java.sun.com/products/jdk/1.2/docs/tooldocs/win32/ (cont't)
+        // javadoc.html#seesearchorder
+        // We don't look in other package, so we assume classname
+        // is full package-qualified.
+        com.sun.javadoc.ClassDoc[] imports = importedClasses();
+        if (imports != null) {
+            for (int i = 0; i < imports.length; i++) {
+                if (classname.equals(imports[i].name())) {
+                    return imports[i];
+                }
+            }
+        }
+
+        // [5] Search the package imports for the fully-qualified name.
+        PackageDoc[] pkgs = importedPackages();
+        if (pkgs != null) {
+            for (int i = 0; i < pkgs.length; i++) {
+                if ((desired = pkgs[i].findClass(classname)) != null) {
+                    return desired;
+                }
+            }
+        }
+
+        // [5 1/2] OK, I lied above, we do search a couple packages,
+        // it should be java.lang, but we're aspectj, so we'll look in
+        // org.aspectj.lang, too.  We assume the names are package-unqualified
+        // in this step.
+        // TODO: check that this is made final, if not, make it static
+        String[] pkgnames = {"java.lang", "org.aspectj.lang"};
+        for (int i = 0; i < pkgnames.length; i++) {
+            PackageDoc pkg = PackageDocImpl.getPackageDoc(pkgnames[i]);
+            if (pkg != null) {
+                if ((desired = pkg.findClass(classname)) != null) {
+                    return desired;
+                }
+            }
+        }
+        // Found nothing.
+        return null;
+    }
+
+    /**
+     * Returns the fields visible in this type.
+     *
+     * @return an array of FieldDoc representing
+     *         the fields visible in this type.
+     */
+    public FieldDoc[] fields() {
+        if (fieldDocs == null) {
+            fieldDocs = createFields();
+        }
+        return (FieldDoc[])fieldDocs.toArray
+            (new org.aspectj.ajdoc.FieldDoc[fieldDocs.size()]);
+    }
+
+    /**
+     * Returns <code>true</code> is this type is externalizable.
+     *
+     * @return <code>true</code> is this type is externalizable.
+     */
+    public boolean isExternalizable() {
+        return false; //TODO
+    }
+
+    /**
+     * Returns <code>true</code> if this type is serializable.
+     *
+     * @return <code>true</code> if this type is serializable.
+     */
+    public boolean isSerializable() {
+        for (Iterator i = typeDec().getSuperInterfaceTypes().iterator();
+             i.hasNext();) {
+            if (((Type)i.next()).getId().equals("java.io.Serializable")) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the methods visible in this type.
+     *
+     * @return an array of MethodDoc representing the
+     *         methods visible in this type.
+     */
+    public MethodDoc[] methods() {
+        if (methodDocs == null) {
+            methodDocs = createMethods();
+        }
+        return (MethodDoc[])methodDocs.toArray
+            (new org.aspectj.ajdoc.MethodDoc[methodDocs.size()]);
+    }
+
+    /**
+     * Returns the serializable methods visible in this type.
+     *
+     * @return an array of MethodDoc representing the
+     *         serializable methods visible in this type.
+     */
+    public MethodDoc[] serializationMethods() {
+        List ser = new ArrayList();
+        MethodDoc[] mds = methods();
+        for (int i = 0, N = mds.length; i < N; i++) {
+            if (mds[i].tags("@serialized").length > 1) ser.add(mds[i]);
+        }
+        return (MethodDoc[])ser.toArray(new MethodDoc[ser.size()]);
+    }
+
+    /**
+     * Returns the serializable fields visible in this type.
+     *
+     * @return an array of MethodDoc representing the
+     *         serializable fields visible in this type.
+     */
+    public FieldDoc[] serializableFields() {
+        List ser = new ArrayList();
+        FieldDoc[] fds = fields();
+        for (int i = 0, N = fds.length; i < N; i++) {
+            if (fds[i].serialFieldTags().length > 1) ser.add(fds[i]);
+        }
+        return (FieldDoc[])ser.toArray(new FieldDoc[ser.size()]);
+    }
+
+    /**
+     * Returns <code>true</code> is this type contains
+     * visible serializable fields.
+     *
+     * @return <code>true</code> is this type contains
+     *         visible serializable fields.
+     */
+    public boolean definesSerializableFields() {
+        return serializableFields().length > 0;
+    }
+
+    /**
+     * Returns the super type of this type.  The return value
+     * is guaranteed to be non-null unless this represents
+     * java.lang.Object.
+     *
+     * @return a ClassDoc representing the super type of this type.
+     *         or null if this represents java.lang.Object.
+     */
+    public com.sun.javadoc.ClassDoc superclass() {
+        if ("java.lang.Object".equals(qualifiedTypeName())) {
+            return null;
+        } else {
+            TypeDec superType = typeDec().getSuperClassType().getTypeDec();
+            return ClassDocImpl.getInstance(superType);
+        }
+    }
+
+    /**
+     * Returns <code>true</code> is <code>c</code> is a
+     * subtype of <code>this</code>.
+     *
+     * @return  <code>true</code> is <code>c</code> is a
+     *          subtype of <code>this</code>.
+     */
+    public boolean subclassOf(com.sun.javadoc.ClassDoc c) {
+        return c != null && c.equals(superclass());
+    }
+
+    /**
+     * Returns the interfaces this type implements.
+     *
+     * @return an array of ClassDoc representing the
+     *         interfaces this type implements.
+     */
+    public com.sun.javadoc.ClassDoc[] interfaces() {
+        if (interfaceDocs == null) {
+            interfaceDocs = createInterfaces();
+        }
+        return (ClassDoc[])interfaceDocs.toArray
+            (new org.aspectj.ajdoc.ClassDoc[interfaceDocs.size()]);
+    }
+
+    /**
+     * Returns the constructors visible in this type.
+     *
+     * @return an array of ConstructorDoc representing the
+     *         visible constructors in this type.
+     */
+    public ConstructorDoc[] constructors() {
+        if (constructorDocs == null) {
+            constructorDocs = createConstructors();
+        }
+        return (ConstructorDoc[])constructorDocs.toArray
+            (new org.aspectj.ajdoc.ConstructorDoc[constructorDocs.size()]);
+    }
+
+    /**
+     * Returns the inner class visible in this type.
+     *
+     * @return an array of ClassDoc representing the inner
+     *         classes visible in this type.
+     */
+    public com.sun.javadoc.ClassDoc[] innerClasses() {
+        if (innerclassDocs == null) {
+            innerclassDocs = createInnerTypes();
+        }
+        final int size = innerclassDocs.size();
+        return (ClassDoc[])innerclassDocs.toArray
+            (new org.aspectj.ajdoc.ClassDoc[size]);
+    }
+
+        /**
+     * Returns the types imported on demand by this type.
+     *
+     * @return an array of ClassDoc representing the
+     *         types imported on demand by this type.
+     */
+    public com.sun.javadoc.ClassDoc[] importedClasses() {
+        return (ClassDoc[])importedClasses.toArray
+            (new org.aspectj.ajdoc.ClassDoc[importedClasses.size()]);
+    }
+
+    /**
+     * Returns the packages imported on demand by this type.
+     *
+     * @return an array of PackageDoc representing the
+     *         packages imported on demand by this type.
+     */
+    public PackageDoc[] importedPackages() {
+        return (PackageDoc[])importedPackages.toArray
+            (new org.aspectj.ajdoc.PackageDoc[importedPackages.size()]);
+    }
+
+    /**
+     * Returns the pointcuts visible in this type.
+     *
+     * @return an array of PointcutDoc representing the
+     *         pointcuts visible in this type.
+     */
+    public PointcutDoc[] pointcuts() {
+        if (pointcutDocs == null) {
+            pointcutDocs = createPointcuts();
+        }
+        return (PointcutDoc[])pointcutDocs.toArray
+            (new PointcutDoc[pointcutDocs.size()]);
+    }
+
+    /**
+     * Returns <code>true</code> is this type is <code>abstract</code>.
+     *
+     * @return <code>true</code> is this type is <code>abstract</code>.
+     */
+    public boolean isAbstract() {
+        return typeDec().isAbstract();
+    }
+
+    /**
+     * Returns <code>true</code> is this type is as exception.
+     *
+     * @return <code>true</code> is this type is an instance
+     *         of java.lang.Exception.
+     */
+    public boolean isException() {
+        //TODO: make lazy
+        for (com.sun.javadoc.ClassDoc superclass = superclass();
+             superclass != null &&
+                 !superclass.qualifiedTypeName().equals("java.lang.Object");
+             superclass = superclass.superclass()) {
+            if (superclass.qualifiedTypeName().equals("java.lang.Exception")) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns <code>true</code> is this type is an error.
+     *
+     * @return <code>true</code> is this type is an instance
+     *         of java.lang.Error.
+     */
+    public boolean isError() {
+        //TODO: make lazy
+        for (com.sun.javadoc.ClassDoc superclass = superclass();
+             superclass != null &&
+                 !superclass.qualifiedTypeName().equals("java.lang.Object");
+             superclass = superclass.superclass()) {
+            if (superclass.qualifiedTypeName().equals("java.lang.Error")) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the introductions affecting a ClassDoc's
+     * type hierarchy.
+     *
+     * @return an array of IntroducedSuperDoc representing the
+     *         introductions of this ClassDoc that affect its
+     *         type hierarchy.
+     */
+    public IntroducedSuperDoc[] introducers() {
+        if (introducers == null) {
+            introducers = createIntroducers();
+        }
+        return (IntroducedSuperDoc[])introducers.toArray
+            (new IntroducedSuperDoc[introducers.size()]);
+    }
+    
+    /**
+     * Returns <code>true</code> is this is an <code>interface</code>.
+     *
+     * @return <code>true</code> is this is an <code>interface</code>.
+     */
+    public boolean isInterface() {
+        return typeDec() instanceof InterfaceDec;
+    }
+
+    /**
+     * Returns <code>true</code> is this is a <code>class</code>.
+     *
+     * @return <code>true</code> is this is a <code>class</code>.
+     */
+    public boolean isClass() {
+        return typeDec() instanceof ClassDec;
+    }
+
+    /**
+     * Returns <code>true</code> is this is an <code>aspect</code>.
+     *
+     * @return <code>true</code> is this is an <code>aspect</code>.
+     */
+    public boolean isAspect() {
+        return typeDec() instanceof AspectDec;
+    }
+
+    /**
+     * Returns <code>true</code> is this class is neither
+     * an error nor an exception, but this still could be
+     * an aspect.
+     *
+     * @return <code>true</code> is this class is neither
+     *         an error nor an exception, but this still could be
+     *         an aspect.
+     */
+    public boolean isOrdinaryClass() {
+        return isClass() && !(isError() || isException());
+    }
+
+    /**
+     * Returns int modifiers with the 'interface' bit set.
+     *
+     * @return  int modifiers with the 'interface' bit set.
+     * @see     java.lang.reflect.Modifier.
+     */
+    public int modifierSpecifier() {
+        return super.modifierSpecifier()
+            |  (isInterface() ? Modifier.INTERFACE : 0);
+    }
+
+    
+    /* ------------------------------------------------------------
+     * Implementation of Type
+     * ------------------------------------------------------------
+     */
+
+    /**
+     * Returns the declaration of this type -- null if
+     * this isn't included.
+     *
+     * @return the ClassDoc represented by this Type or null
+     *         if this isn't included.
+     */
+    public com.sun.javadoc.ClassDoc asClassDoc() {
+        return isIncluded() ? this : null;
+    }
+
+    /**
+     * Returns this type's dimension information as a String.
+     *
+     * @return this type's dimension information as a String.
+     */
+    public String dimension() {
+        return "";
+    }
+
+    /**
+     * Returns qualified name of type excluding
+     * any dimension information.
+     *
+     * @return qualified name of type excluding
+     *         any dimension information.
+     */
+    public String qualifiedTypeName() {
+        return typeDec().getFullName().replace('$', '.');
+    }
+
+    /**
+     * Returns unqualified name of type excluding
+     * any dimension information.
+     *
+     * @return unqualified name of type excluding
+     *         any dimension information.
+     */
+    public String typeName() {
+        return typeDec().getId().replace('$', '.');
+    }
+
+    /**
+     * Returns the Collection of IntroducedSuperDec that
+     * introduce a type intro this's type hierarchy.  At the
+     * same time, the method makes sure <code>this</code> is
+     * added to every IntroducedSuperDec's list of targets.
+     *
+     * @return Collection of IntroducedSuperDec that
+     *         introduce a type intro this's type hierarchy.
+     */
+    private Collection createIntroducers() {
+        Set affectedBy = ajc().getCorrespondences().getAffectedBy(typeDec);
+        if (affectedBy.size() < 1) {
+            return Collections.EMPTY_LIST;
+        }
+        Collection list = new ArrayList();
+        for (Iterator i = affectedBy.iterator(); i.hasNext();) {
+            Object o = i.next();
+            if (o instanceof IntroducedSuperDec) {
+                IntroducedSuperDec dec = (IntroducedSuperDec)o;
+                TypeDec owner = ((NameType)dec.getDeclaringType()).getTypeDec();
+                AspectDocImpl ad = (AspectDocImpl)ClassDocImpl.getInstance(owner);
+                IntroducedSuperDocImpl id = (IntroducedSuperDocImpl)ad.introDocForDec(dec);
+                list.add(id);
+                id.addTarget(this);
+                
+            }
+        }
+        return list;
+    }
+
+    
+    /* ------------------------------------------------------------
+     * Factory instantiation
+     * ------------------------------------------------------------
+     */
+
+    /**
+     * Inner class in charge of creating instances of ClassDocImpl.
+     */
+    private final static class Factory {
+
+        private final Map typeDecsToClassDocs = new HashMap();
+        private final Map qualifiedNamesToClassDocs = new HashMap();
+
+        public final ClassDocImpl find(String qualifiedName) {
+            return (ClassDocImpl)qualifiedNamesToClassDocs.get(qualifiedName);
+        }
+
+        public final ClassDocImpl getInstance(TypeDec typeDec) {
+            if (typeDec == null) return null;
+            ClassDocImpl outerDoc = getInstance(typeDec.getEnclosingTypeDec());
+
+            return getInstance(outerDoc, typeDec);
+        }
+        public final ClassDocImpl getInstance(ClassDoc outerDoc, 
+                                              TypeDec typeDec) {
+            if (typeDec == null) return null;
+            ClassDocImpl cd = (ClassDocImpl)typeDecsToClassDocs.get(typeDec);
+            if (cd == null) {
+                cd = makeInstance(outerDoc, typeDec);
+                /*
+                Object o = typeDecsToClassDocs.put(typeDec, cd);
+                if (null != o) {
+                    throw new Error("new " + cd + " displaced " + o + " for " + typeDec);
+                }
+                */
+            }
+            return cd;
+        }
+        private final ClassDocImpl makeInstance(ClassDoc outerDoc, 
+                                                TypeDec typeDec) {
+            ClassDocImpl result = null;
+            if (typeDec instanceof AspectDec) {
+                result = new AspectDocImpl(outerDoc, (AspectDec)typeDec);
+            } else {
+                result = new ClassDocImpl(outerDoc, typeDec);
+            }
+            if (null == result.containingPackage()) {
+                System.err.println("Warning: unable to add " 
+                                   + result + " to package");
+            }
+            return result;
+        }
+
+        /** 
+         * constructor installs itself here before generating imports.
+         * fyi: not Thread-safe since available from factory before 
+         * construction completes
+         * @return object displaced, if any - error if not null
+         */
+        private final Object put(ClassDocImpl classdoc, TypeDec typeDec) {
+            Object result  = typeDecsToClassDocs.put(typeDec, classdoc);
+            if (null == result) {
+                result = qualifiedNamesToClassDocs.put(classdoc.qualifiedName(), classdoc);
+            }
+            return result;
+        }
+    } // factory
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/CodeDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/CodeDocImpl.java
new file mode 100644 (file)
index 0000000..b2de781
--- /dev/null
@@ -0,0 +1,82 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ast.ASTObject;
+import org.aspectj.compiler.base.ast.CodeDec;
+import org.aspectj.compiler.base.ast.Dec;
+import org.aspectj.compiler.base.ast.DummySourceLocation;
+import org.aspectj.compiler.base.ast.Formals;
+import org.aspectj.compiler.base.ast.NameType;
+import org.aspectj.compiler.base.ast.SourceLocation;
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.base.ast.TypeDs;
+import org.aspectj.compiler.crosscuts.ast.AdviceDec;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+public abstract class CodeDocImpl extends ExecutableMemberDocImpl {
+
+    /** The CodeDec to which we delegate. */
+    private final CodeDec codeDec;
+    
+    public CodeDocImpl(com.sun.javadoc.ClassDoc containingClass, CodeDec codeDec) {
+        super(containingClass);
+        this.codeDec = codeDec;
+    }
+
+    protected Collection createAdvice() {
+        Set affectedBy = ajc().getCorrespondences().getAffectedBy(codeDec());
+        if (affectedBy.size() < 1) return Collections.EMPTY_LIST;
+        List list = new ArrayList();
+        for (Iterator i = affectedBy.iterator(); i.hasNext();) {
+            AdviceDec adec = (AdviceDec)i.next();
+            TypeDec owner = ((NameType)adec.getDeclaringType()).getTypeDec();
+            AspectDocImpl ad = (AspectDocImpl)ClassDocImpl.getInstance(owner);
+            AdviceDocImpl adoc = ad.docForDec(adec);
+            list.add(adoc);
+        }
+        return list;
+    }
+    
+    protected Dec dec() {
+        return codeDec();
+    }
+
+    protected Formals getFormals() {
+        return codeDec().getFormals();
+    }
+
+    protected TypeDs getThrows() {
+        return codeDec().getThrows();
+    }
+
+    protected CodeDec codeDec() {
+        return codeDec;
+    }
+}
+
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Comment.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Comment.java
new file mode 100644 (file)
index 0000000..5565594
--- /dev/null
@@ -0,0 +1,336 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import com.sun.javadoc.Doc;
+import com.sun.javadoc.ParamTag;
+import com.sun.javadoc.SeeTag;
+import com.sun.javadoc.SerialFieldTag;
+import com.sun.javadoc.Tag;
+import com.sun.javadoc.ThrowsTag;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
+public class Comment {
+    
+    /** The parsed comment text. */
+    private String commentText;
+
+    /** The raw comment text. */
+    private String rawCommentText;
+
+    /** The list of tags. */
+    private List tags;
+
+    /** The Doc to which the Comment belongs. */
+    private Doc doc;
+
+    /** The Locale in which this comment resides. */
+    private Locale loc;
+
+    /** The ErrPrinter used by this Comment to output messages. */
+    private ErrPrinter err;
+
+    public Comment(Doc doc, String formalComment) {
+        this(doc, formalComment, ErrPrinter.instance);
+    }
+
+    public Comment(Doc doc, String formalComment, ErrPrinter err) {
+        this(doc, formalComment, err, Locale.US);
+    }
+
+    public Comment(Doc doc, String formalComment, ErrPrinter err, Locale loc) {
+        this.rawCommentText = Util.rawCommentText(formalComment);
+        this.commentText = Util.commentText(rawCommentText);
+        this.doc = doc;
+        this.err = err;
+        this.loc = loc;
+    }
+
+    /**
+     * Returns the parsed comment text.
+     *
+     * @return the parsed comment text.
+     */
+    public String commentText() {
+        return commentText;
+    }
+
+    /**
+     * Returns the full unprocessed text of the comment.
+     *
+     * @return the full unprocessed text of the comment.
+     */
+    public String getRawCommentText() {
+        return rawCommentText;
+    }
+
+    /**
+     * Sets the comment text.
+     *
+     * @param commentText the new comment text.
+     */
+    public void setCommentText(String commentText) {
+        this.commentText = commentText;
+    }
+    
+    /**
+     * Returns the raw comment text.
+     *
+     * @return the raw comment text.
+     */
+    public String rawCommentText() {
+        return rawCommentText;
+    }
+
+    /**
+     * Sets the raw comment text.
+     *
+     * @param rawCommentText the new raw comment text.
+     */
+    public void setRawCommentText(String rawCommentText) {
+        this.rawCommentText = rawCommentText;
+    }
+
+    /**
+     * Returns all this comment's tags.
+     *
+     * @return a List of tags whose elements are Comment instances
+     */
+    public List getTags() {
+        if (tags == null) {
+            tags = findTags();
+        }
+        return tags;
+    }
+    
+    /**
+     * Sets the Doc for this comment.
+     *
+     * @param doc the new Doc.
+     */
+    public void setDoc(Doc doc) {
+        this.doc = doc;
+    }
+
+    /**
+     * Returns the Doc for this comment.
+     *
+     * @return the Doc for this comment.
+     */
+    public Doc doc() {
+        return doc;
+    }
+
+    /**
+     * Sets the locale for this comment.
+     *
+     * @param loc the new locale for this comment.
+     */
+    public void setLocale(Locale loc) {
+        this.loc = loc;
+    }
+
+    /**
+     * Returns the Locale for this comment.
+     *
+     * @return the Locale for this comment.
+     */
+    public Locale locale() {
+        return loc;
+    }
+    
+    /**
+     * Sets the ErrPrinter for this comment.
+     *
+     * @param err the new ErrPrinter for this comment.
+     */
+    public void setErr(ErrPrinter err) {
+        this.err = err;
+    }
+
+    /**
+     * Returns the ErrPrinter for this comment.
+     *
+     * @return the ErrPrinter for this comment.
+     */
+    public ErrPrinter err() {
+        return err;
+    }
+
+    /**
+     * Initializes the Doc, Locale, and ErrPrinter.
+     *
+     * @param doc the new Doc.
+     * @param loc the new Locale.
+     * @param err the new ErrPrinter.
+     */
+    public void init(Doc doc, Locale loc, ErrPrinter err) {
+        setDoc(doc);
+        setLocale(loc);
+        setErr(err);
+    }
+   
+    /**
+     * Returns the comment as an array of Tag.
+     *
+     * @return an array of Tag representing the comment.
+     */
+    public Tag[] inlineTags() {
+        return Util.inlineTags(doc(),
+                               commentText(),
+                               locale(),
+                               err());
+    }
+
+    /**
+     * Returns all tags of the comment whose name equals
+     * <code>tagname</code>.
+     *
+     * @return an array of Tag representing all tags of the
+     *         comment whose name equals <code>tagname</code>.
+     */
+    public Tag[] tags(String type) {
+        type = type.startsWith("@") ? type : "@"+type;
+        List result = new ArrayList();
+        Tag tag;
+        for (Iterator i = getTags().iterator(); i.hasNext();) {
+            if ((tag = (Tag)i.next()).kind().equals(type)) {
+                result.add(tag);
+            }
+        }
+        return (Tag[])result.toArray(new Tag[result.size()]);
+    }
+
+    /**
+     * Returns the param tags describing parameters taken
+     * by this code.
+     *
+     * @return an array of ParamTag representing the
+     *         parameters taken by this code.
+     */
+    public ParamTag[] paramTags() {
+        List result = new ArrayList();
+        Tag tag;
+        for (Iterator i = getTags().iterator(); i.hasNext();) {
+            if ((tag = (Tag)i.next()) instanceof ParamTag) {
+                result.add((ParamTag)tag);
+            }
+        }
+        return (ParamTag[])result.toArray(new ParamTag[result.size()]);
+    }
+    
+    /**
+     * Returns the see tags of the comment.
+     *
+     * @return an array of SeeTag representing the
+     *         see tags of the comment.
+     */
+    public SeeTag[] seeTags() {
+        List result = new ArrayList();
+        Tag tag;
+        for (Iterator i = getTags().iterator(); i.hasNext();) {
+            if ((tag = (Tag)i.next()) instanceof SeeTag) {
+                result.add((SeeTag)tag);
+            }
+        }
+        return (SeeTag[])result.toArray(new SeeTag[result.size()]);
+    }
+
+    /**
+     * Returns the serial field tags for this field.
+     *
+     * @return an array of SerialFieldTag representing the
+     *         serial field tags for this field.
+     */
+    public SerialFieldTag[] serialFieldTags() {
+        List result = new ArrayList();
+        Tag tag;
+        for (Iterator i = getTags().iterator(); i.hasNext();) {
+            if ((tag = (Tag)i.next()) instanceof SerialFieldTag) {
+                result.add((SerialFieldTag)tag);
+            }
+        }
+        return (SerialFieldTag[])result.toArray
+            (new SerialFieldTag[result.size()]);
+    }
+
+    /**
+     * Returns the throw tags describing exceptions thrown
+     * declared by this code.
+     *
+     * @return an array of ThrowsTag representing the exception
+     *         this code declares to throw.
+     */
+    public ThrowsTag[] throwsTags() {
+        List result = new ArrayList();
+        Tag tag;
+        for (Iterator i = getTags().iterator(); i.hasNext();) {
+            if ((tag = (Tag)i.next()) instanceof ThrowsTag) {
+                result.add((ThrowsTag)tag);
+            }
+        }
+        return (ThrowsTag[])result.toArray
+            (new ThrowsTag[result.size()]);
+    }
+
+    /**
+     * Returns all tags of the comment.
+     *
+     * @return an array of Tag representing all
+     *         tags of the comment.
+     */
+    public Tag[] tags() {
+        return (Tag[])getTags().toArray
+            (new Tag[getTags().size()]);
+    }
+
+    /**
+     * Returns the Tags that comprise the first
+     * sentence of the comment.
+     *
+     * @return an array of Tag representing the first
+     *         sentence of the comment.
+     */
+    public Tag[] firstSentenceTags() {
+        return Util.firstSentenceTags(doc(),
+                                      commentText(),
+                                      locale(),
+                                      err());
+    }
+
+    /**
+     * Used to lazily initialize the tags of this comment.
+     *
+     * @return a List of tags whose elements of Tag instances
+     *         and each represent a tag in this comment.
+     */
+    private List findTags() {
+        return Util.findTags(doc(),
+                             rawCommentText(),
+                             locale(),
+                             err());
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ConstructorDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ConstructorDocImpl.java
new file mode 100644 (file)
index 0000000..b9bb4d3
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ast.ConstructorDec;
+
+import com.sun.javadoc.ClassDoc;
+
+public class ConstructorDocImpl
+    extends    CodeDocImpl
+    implements org.aspectj.ajdoc.ConstructorDoc {
+
+    public ConstructorDocImpl(ClassDoc containingClass, ConstructorDec constructor) {
+        super(containingClass, constructor);
+    }
+    
+    /**
+     * Returns <code>true</code>.
+     *
+     * @return <code>true</code>.
+     */
+    public boolean isConstructor() {
+        return true;
+    }
+
+    /**
+     * Returns the fully-qualified name -- i.e. the
+     * defining types ID.
+     *
+     * @return the fully-qualified name -- i.e. the
+     *         defining types ID.
+     */
+    public String qualifiedName() {
+        return containingClass().name();
+    }
+
+    /**
+     * Returns the name of this -- i.e. the qualified name.
+     *
+     * @return the name of this -- i.e. the qualified name.
+     */
+    public String name() {
+        return qualifiedName();
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/DocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/DocImpl.java
new file mode 100644 (file)
index 0000000..87dad67
--- /dev/null
@@ -0,0 +1,280 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.Doc;
+
+import com.sun.javadoc.SeeTag;
+import com.sun.javadoc.Tag;
+
+import java.util.Locale;
+
+public abstract class DocImpl
+    implements org.aspectj.ajdoc.Doc {
+
+    /** Keep track of whether this is included or not. */
+    private boolean isIncluded = true;
+
+    /** The comment for this Doc. */
+    private Comment comment;
+
+    /** The error printer for this Doc. */
+    private ErrPrinter err;
+    
+    /** Keep track of whether this is included or not. */
+    private boolean isInterface = true;
+
+    /** The locale of the object -- default to <code>Locale.US</code>. */
+    private Locale locale = Locale.US; //TODO
+
+    /**
+     * Returns the locale.
+     *
+     * @return the locale.
+     */
+    public Locale locale() { //XXX
+        return locale;
+    }
+
+    
+    public void setErr(ErrPrinter err) { this.err = err; }
+    public ErrPrinter err() { return ErrPrinter.instance; }
+
+    public void setComment(Comment comment) { this.comment = comment; }
+    public Comment getComment() { return comment; }
+
+    /**
+     * Delegates to {@link Util#compareTo(Object)} to compare
+     * with another Object.
+     *
+     * @return a negative integer, zero, or a positive integer
+     *         as this object is less than, equal to, or greater
+     *         than the specified object based on name.
+     * @see    java.lang.Comparable.compareTo(Object)
+     */
+    public int compareTo(Object other) {
+        return other instanceof Doc
+            ?  Util.compareTo(this, (Doc)other)
+            :  -1;
+    }
+
+    /**
+     * Returns the Tags that comprise the first
+     * sentence of the comment.
+     *
+     * @return an array of Tag representing the first
+     *         sentence of the comment.
+     */
+    public Tag[] firstSentenceTags() {
+        return getComment() != null
+            ?  getComment().firstSentenceTags()
+            :  new Tag[0];
+    }
+
+    /**
+     * Returns the full unprocessed text of the comment.
+     *
+     * @return the full unprocessed text of the comment.
+     */
+    public String getRawCommentText() {
+        return getComment() != null
+            ?  getComment().rawCommentText()
+            :  "";
+    }
+
+    /**
+     * Sets the full unprocessed text of the comment.
+     *
+     * @param rawCommentText the new full unprocessed text of the comment..
+     */
+    public void setRawCommentText(String rawCommentText) {
+        if (getComment() != null) {
+            getComment().setRawCommentText(rawCommentText);
+        }
+    }
+
+    /**
+     * Returns the comment as an array of Tag.
+     *
+     * @return an array of Tag representing the comment.
+     */
+    public Tag[] inlineTags() {
+        return getComment() != null
+            ?  getComment().inlineTags()
+            :  new Tag[0];
+    }
+    
+    /**
+     * Returns the see tags of the comment.
+     *
+     * @return an array of SeeTag representing the
+     *         see tags of the comment.
+     */
+    public SeeTag[] seeTags() {
+        return getComment() != null
+            ?  getComment().seeTags()
+            :  new SeeTag[0];
+    }
+
+    /**
+     * Returns all tags of the comment.
+     *
+     * @return an array of Tag representing all
+     *         tags of the comment.
+     */
+    public Tag[] tags() {
+        return getComment() != null
+            ?  getComment().tags()
+            :  new Tag[0];
+    }
+
+    /**
+     * Returns all tags of the comment whose name equals
+     * <code>tagname</code>.
+     *
+     * @return an array of Tag representing all tags of the
+     *         comment whose name equals <code>tagname</code>.
+     */
+    public Tag[] tags(String tagname) {
+        return getComment() != null
+            ?  getComment().tags(tagname)
+            :  new Tag[0];
+    }
+
+    /**
+     * Returns the commext text for non-null comments,
+     * otherwise the empty String.
+     *
+     * @return non-null comment text.
+     */
+    public String commentText() {
+        return getComment() != null
+            ?  getComment().commentText()
+            :  "";
+    }
+
+    /**
+     * Sets <code>isIncluded</code>.
+     *
+     * @param isIncluded the new value of <code>isIncluded</code>.
+     */
+    public void setIncluded(boolean isIncluded) {
+        this.isIncluded = isIncluded;
+    }
+    
+    /**
+     * Returns <code>false</code> by default.
+     *
+     * @return <code>false</code> by default.
+     */
+    public boolean isClass() {
+        return false;
+    }
+    
+    /**
+     * Returns <code>false</code> by default.
+     *
+     * @return <code>false</code> by default.
+     */
+    public boolean isConstructor() {
+        return false;
+    }
+
+    /**
+     * Returns <code>false</code> by default.
+     *
+     * @return <code>false</code> by default.
+     */
+    public boolean isError() {
+        return false;
+    }
+    
+    /**
+     * Returns <code>false</code> by default.
+     *
+     * @return <code>false</code> by default.
+     */
+    public boolean isException() {
+        return false;
+    }
+    /**
+     * Returns <code>false</code> by default.
+     *
+     * @return <codealse</code> by default./
+     */
+    public boolean isField() {
+        return false;
+    }
+    /**
+     * Returns <code>isIncluded</code> by default.
+     *
+     * @return <codesIncluded</code> by default./
+     */
+    public boolean isIncluded() {
+        return isIncluded;
+    }
+    
+    /**
+     * Returns <code>false</code> by default.
+     *
+     * @return <codealse</code> by default./
+     */
+    public boolean isInterface() {
+        return false;
+    }
+    
+    /**
+     * Returns <code>false</code> by default.
+     *
+     * @return <codealse</code> by default./
+     */
+    public boolean isMethod() {
+        return false;
+    }
+    
+    /**
+     * Returns <code>false</code> by default.
+     *
+     * @return <codealse</code> by default./
+     */
+    public boolean isOrdinaryClass() {
+        return false;
+    }
+    
+    /**
+     * Returns <code>false</code> by default.
+     *
+     * @return <codealse</code> by default./
+     */
+    public boolean isPointcut() {
+        return false;
+    }
+    
+    /**
+     * Returns <code>false</code> by default.
+     *
+     * @return <codealse</code> by default./
+     */
+    public boolean isAdvice() {
+        return false;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/DocletProxy.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/DocletProxy.java
new file mode 100644 (file)
index 0000000..9fea741
--- /dev/null
@@ -0,0 +1,145 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+
+package org.aspectj.tools.ajdoc;
+import org.aspectj.tools.doclets.standard.AbstractStandard;
+import org.aspectj.tools.doclets.standard.Standard;
+
+import com.sun.javadoc.DocErrorReporter;
+import com.sun.javadoc.RootDoc;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ */
+public interface DocletProxy {
+    public static final DocletProxy STANDARD 
+        = JavadocStandardProxy.SINGLETON;
+    public static final DocletProxy DEFAULT 
+        = StandardProxy.SINGLETON;
+    public int optionLength(String arg);
+    public boolean start(RootDoc root) 
+        throws IOException;
+    public boolean validOptions(List options, DocErrorReporter handler) 
+        throws IOException;
+}
+
+/**
+ * This proxy delegates to Standard singleton,
+ * but delays alerts about it being unavailable until first use
+ */
+class StandardProxy implements DocletProxy {
+    public static final DocletProxy SINGLETON = new StandardProxy();
+    private StandardProxy() { }
+
+    /** check and delegate to standard */
+    public int optionLength(String arg) {
+        return Standard.optionLength(arg);
+    }
+    /** check and delegate to standard */
+    public boolean validOptions(List options, DocErrorReporter handler) 
+        throws IOException {
+        return AbstractStandard.validOptions(docletOptions(options), handler);
+    }
+    // todo: validate that this is the expected format for doclet options
+    protected String[][] docletOptions(List options) {
+        if ((null == options) || (1 > options.size())) {
+            return new String[][]{};
+        }
+        Object[] ra = options.toArray();
+        String[] strs = new String[ra.length];
+        for (int i = 0; i < ra.length; i++) {
+            strs[i] = (null == ra[i] ? null : ra[i].toString());
+        }
+        return new String[][] {strs};
+    }
+
+    /** check and delegate to standard */
+    public boolean start(RootDoc root) throws IOException {
+        return Standard.start(root);
+    }
+} // StandardProxy
+
+/**
+ * This proxy delegates to javadoc Standard singleton.
+ */
+class JavadocStandardProxy implements DocletProxy {
+    public static final DocletProxy SINGLETON = new JavadocStandardProxy();
+    private JavadocStandardProxy() { }
+
+    /** check and delegate to standard */
+    public int optionLength(String arg) {
+        return com.sun.tools.doclets.standard.Standard.optionLength(arg);
+    }
+    /** check and delegate to standard */
+    public boolean validOptions(List options, DocErrorReporter handler) 
+        throws IOException {
+        return com.sun.tools.doclets.standard.Standard.validOptions(docletOptions(options), handler);
+    }
+    // todo: validate that this is the expected format for doclet options
+    protected String[][] docletOptions(List options) {
+        if ((null == options) || (1 > options.size())) {
+            return new String[][]{};
+        }
+        Object[] ra = options.toArray();
+        String[] strs = new String[ra.length];
+        for (int i = 0; i < ra.length; i++) {
+            strs[i] = (null == ra[i] ? null : ra[i].toString());
+        }
+        return new String[][] {strs};
+    }
+
+    /** check and delegate to standard */
+    public boolean start(RootDoc root) throws IOException {
+        return com.sun.tools.doclets.standard.Standard.start(root);
+    }
+} // JavadocStandardProxy
+
+/** Wrap a Throwable as a RuntimeException 
+ * This will render stack trace as the delegate stack trace,
+ * notwithstanding any call to fillInStackTrace.
+class ExceptionWrapper extends RuntimeException {
+    Throwable delegate;
+    public ExceptionWrapper(Throwable t) {
+        delegate = (null == t ? new Error("null") : t);
+    }
+    public void printStackTrace() {
+        delegate.printStackTrace();
+    }
+    public void printStackTrace(PrintStream stream) {
+        delegate.printStackTrace(stream);
+    }
+    public void printStackTrace(PrintWriter stream) {
+        delegate.printStackTrace(stream);
+    }
+    public String getMessage() {
+        return delegate.getMessage();
+    }
+    public String getLocalizedMessage() {
+        return delegate.getLocalizedMessage();
+    }
+    public Throwable fillInStackTrace() {
+        return delegate.fillInStackTrace();
+    }
+}
+*/
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ErrPrinter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ErrPrinter.java
new file mode 100644 (file)
index 0000000..96d2e7b
--- /dev/null
@@ -0,0 +1,627 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ErrorHandler;
+import org.aspectj.compiler.base.InternalCompilerError;
+
+import com.sun.javadoc.DocErrorReporter;
+
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * A class to handler errors in ajdoc.
+ *
+ * @author Jeff Palm
+ */
+public class ErrPrinter
+    extends ErrorHandler
+    implements DocErrorReporter
+{
+
+    /** The global instance that anyone can use. */
+    public final static ErrPrinter instance = new ErrPrinter();
+
+    private String programName;
+    private PrintWriter out;
+    private PrintWriter err;
+    private ResourceBundle bundle;
+    private List keys = new ArrayList();
+    private List msgs = new ArrayList();
+
+    static int cnt = 0;
+
+    /**
+     * Construct with program name <code>programName</code>
+     * and printstreams <code>err</code> and <code>out</code>.
+     *
+     * @param programName program name.
+     * @param err         error stream.
+     * @param out         output stream.
+     */
+    public ErrPrinter(String programName,
+                      PrintWriter err,
+                      PrintWriter out) {
+        super(err);
+        this.programName = programName;
+        this.err = err;
+        this.out = out;
+       try {
+            bundle = ResourceBundle.getBundle
+                ("org.aspectj.tools.ajdoc.resources.ajdoc");
+       } catch (MissingResourceException e) {
+           throw new Error("Can't find ajdoc.properties: " + e);
+       }  
+    }
+    
+    /**
+     * Construct with program name <code>programName</code>
+     * and printstreams <code>System.err</code> and <code>System.out</code>
+     *
+     * @param programName program name.
+     */
+    public ErrPrinter(String programName) {
+        this(programName,
+             new PrintWriter(System.err, true),
+             new PrintWriter(System.out, true));
+    }
+    
+    /**
+     * Construct with program name <code>"ajdoc"</code>
+     * and printstreams <code>System.err</code> and <code>System.out</code>
+     */
+    public ErrPrinter() {
+        this("ajdoc");
+    }
+
+    /**
+     * Print <code>error</code> and increment the error count.
+     *
+     * @param error error message to print.
+     */
+    public void printError(String error) {
+        errors++;
+        err.println(error);
+        err.flush();
+    }
+    
+    /**
+     * Print <code>warning</code> and increment the warning count.
+     *
+     * @param warning warning message to print.
+     */
+    public void printWarning(String warning) {
+        warnings++;
+        err.println(warning);
+        err.flush();
+    }
+
+    /**
+     * Print <code>notice</code>.
+     *
+     * @param notice notice message to print.
+     */
+    public void printNotice(String notice) {
+        out.println(notice);
+        out.flush();
+    }
+
+    /**
+     * Returns the number of errors.
+     *
+     * @return number of errors.
+     */
+    public int getNumErrors() {
+        return errors;
+    }
+
+    /**
+     * Returns the number of warnings.
+     *
+     * @return number of warnings.
+     */
+    public int getNumWarnings() {
+        return warnings;
+    }
+
+    /**
+     * Returns the keys in the resource bundle.
+     *
+     * @return keys in the resource bundle.
+     */
+    public List getKeys() {
+        return new ArrayList(keys);
+    }
+
+    /**
+     * Returns the messages in the resource bundle.
+     *
+     * @return messages in the resource bundle.
+     */
+    public List getMsgs() {
+        return new ArrayList(msgs);
+    }
+
+    /**
+     * Handles InvocationTargetExceptions.
+     *
+     * @param e          the exception.
+     * @param classname  the class on which the method was trying
+     *                   to be invoked.
+     * @param methodName the name of the method trying to be invoked.
+     * @return           the exception.
+     */
+    public synchronized Throwable invocationTargetException
+        (InvocationTargetException e,
+         String classname,
+         String methodName) {
+        Throwable t = e.getTargetException();
+        if (t != null) {
+            if (t instanceof OutOfMemoryError) {
+                error("out_of_memory");
+            } else {
+                error("exception_thrown", "", classname, methodName, t+"");
+                t.printStackTrace();
+            }
+        }
+        return t != null ? t : e;
+    }
+
+    /**
+     * Handles an internal error.
+     *
+     * @param key key of the message to use.
+     * @param t   exception thrown.
+     */
+    public synchronized void internalError(String key, Throwable t) {
+        internalError(key, "", t);
+    }
+
+    /**
+     * Handles an internal error.
+     *
+     * @param key key of the message to use.
+     * @param s0  first argument in the message.
+     * @param t   exception thrown.
+     */
+    public synchronized void internalError(String key, String s0, Throwable t) {
+        if (t instanceof InternalCompilerError) {
+            t = ((InternalCompilerError)t).uncaughtThrowable;
+        }
+        error(key, s0, t != null ? t.getMessage() : "");
+        if (t != null) t.printStackTrace();
+        internalError(t, null);
+    }
+
+    
+    /**
+     * Prints an error message for key <code>key</code>
+     * ,and returns the number of errors.
+     *
+     * @param key           key of the message.
+     * @return              number of errors.
+     */
+    public final int error(String key) {
+        printError(text(key));
+        return errors;
+    }
+
+    /**
+     * Prints an error message for key <code>key</code>
+     * and argument <code>s0</code>,
+     * and returns the number of errors.
+     *
+     * @param key           key of the message.
+     * @param s0            argument to message.
+     * @return              number of errors.
+     */
+    public final int error(String key, String s0) {
+        printError(text(key,s0));
+        return errors;
+    }
+
+    /**
+     * Prints an error message for key <code>key</code>
+     * and arguments <code>s0,s1</code>,
+     * and returns the number of errors.
+     *
+     * @param key           key of the message.
+     * @param s0            argument to message.
+     * @param s1            argument to message.
+     * @return              number of errors.
+     */
+    public final int error(String key, String s0, String s1) {
+        printError(text(key,s0,s1));
+        return errors;
+    }
+
+    /**
+     * Prints an error message for key <code>key</code>
+     * and arguments <code>s0,s1,s2</code>,
+     * and returns the number of errors.
+     *
+     * @param key           key of the message.
+     * @param s0            argument to message.
+     * @param s1            argument to message.
+     * @param s2            argument to message.
+     * @return              number of errors.
+     */
+    public final int error(String key, String s0, String s1,
+                            String s2) {
+        printError(text(key,s0,s1,s2));
+        return errors;
+    }
+    /**
+     * Prints an error message for key <code>key</code>
+     * and arguments <code>s0,s1,s2,cookieMonster</code>,
+     * and returns the number of errors.
+     *
+     * @param key            key of the message.
+     * @param s0             argument to message.
+     * @param s1             argument to message.
+     * @param s2             argument to message.
+     * @param cookieMonster  argument to message.
+     * @return               number of errors.
+     */
+    public final int error(String key, String s0, String s1,
+                            String s2, String cookieMonster) {
+        printError(text(key,s0,s1,s2,cookieMonster));
+        return errors;
+    }
+
+    /**
+     * Handles the thrown exception <code>t</code>
+     * with message key <code>key</code>, and returns
+     * the number of errors.
+     *
+     * @param t             thrown exception.
+     * @param key           message key.
+     * @return              number of errors.
+     */
+    public final int ex(Throwable t, String key) {
+        error(key);
+        if (t != null) t.printStackTrace();
+        return errors;
+    }
+
+    /**
+     * Handles the thrown exception <code>t</code>
+     * with message key <code>key</code> and
+     * argument <code>s0</code>, and returns
+     * the number of errors.
+     *
+     * @param t             thrown exception.
+     * @param key           message key.
+     * @param s0            argument to message.
+     * @return              number of errors.
+     */
+    public final int ex(Throwable t, String key, String s0) {
+        error(key,s0);
+        if (t != null) t.printStackTrace();
+        return errors;
+    }
+
+    /**
+     * Handles the thrown exception <code>t</code>
+     * with message key <code>key</code> and
+     * arguments <code>s0,s1</code>, and returns
+     * the number of errors.
+     *
+     * @param t             thrown exception.
+     * @param key           message key.
+     * @param s0            argument to message.
+     * @param s1            argument to message.
+     * @return              number of errors.
+     */
+    public final int ex(Throwable t, String key, String s0, String s1) {
+        error(key,s0,s1);
+        if (t != null) t.printStackTrace();
+        return errors;
+    }
+
+    /**
+     * Handles the thrown exception <code>t</code>
+     * with message key <code>key</code> and
+     * arguments <code>s0,s1,s2</code>, and returns
+     * the number of errors.
+     *
+     * @param t             thrown exception.
+     * @param key           message key.
+     * @param s0            argument to message.
+     * @param s1            argument to message.
+     * @param s2            argument to message.
+     * @return              number of errors.
+     */
+    public final int ex(Throwable t, String key, String s0, String s1,
+                            String s2) {
+        error(key,s0,s1,s2);
+        if (t != null) t.printStackTrace();
+        return errors;
+    }
+
+    /**
+     * Handles the thrown exception <code>t</code>
+     * with message key <code>key</code> and
+     * arguments <code>s0,s1,s2,snuffulufugus</code>, and returns
+     * the number of errors.
+     *
+     * @param t             thrown exception.
+     * @param key           message key.
+     * @param s0            argument to message.
+     * @param s1            argument to message.
+     * @param s2            argument to message.
+     * @param snuffulufugus argument to message.
+     * @return              number of errors.
+     */
+    public final int ex(Throwable t, String key, String s0, String s1,
+                            String s2, String snuffulufugus) {
+        error(key,s0,s1,s2,snuffulufugus);
+        if (t != null) t.printStackTrace();
+        return errors;
+    }
+
+    /**
+     * Prints the warning with key <code>key</code>
+     * and returns the number of warnings.
+     *
+     * @param key message key.
+     * @return    number of warnings.
+     */
+    public final int warning(String key) {
+        printWarning(text(key));
+        return warnings;
+    }
+
+    /**
+     * Prints the warning with key <code>key</code> and
+     * argument <code>s0</code>,
+     * and returns the number of warnings.
+     *
+     * @param key           message key.
+     * @param s0            argument to message.
+     * @return              number of warnings.
+     */
+    public final int warning(String key, String s0) {
+        printWarning(text(key,s0));
+        return warnings;
+    }
+
+    /**
+     * Prints the warning with key <code>key</code> and
+     * arguments <code>s0,s1</code>,
+     * and returns the number of warnings.
+     *
+     * @param key           message key.
+     * @param s0            argument to message.
+     * @param s1            argument to message.
+     * @return              number of warnings.
+     */
+    public final int warning(String key, String s0, String s1) {
+        printWarning(text(key,s0,s1));
+        return warnings;
+    }
+
+    /**
+     * Prints the warning with key <code>key</code> and
+     * arguments <code>s0,s1,s2</code>,
+     * and returns the number of warnings.
+     *
+     * @param key           message key.
+     * @param s0            argument to message.
+     * @param s1            argument to message.
+     * @param s2            argument to message.
+     * @return              number of warnings.
+     */
+    public final int warning(String key, String s0, String s1,
+                            String s2) {
+        printWarning(text(key,s0,s1,s2));
+        return warnings;
+    }
+
+    /**
+     * Prints the warning with key <code>key</code> and
+     * arguments <code>s0,s1,s2,josefStalin</code>,
+     * and returns the number of warnings.
+     *
+     * @param key          message key.
+     * @param s0           argument to message.
+     * @param s1           argument to message.
+     * @param s2           argument to message.
+     * @param josefStalin  argument to message.
+     * @return             number of warnings.
+     */
+    public final int warning(String key, String s0, String s1,
+                            String s2, String josefStalin) {
+        printWarning(text(key,s0,s1,s2,josefStalin));
+        return warnings;
+    }
+
+    /**
+     * Print a notice with message key <code>key</code>.
+     *
+     * @param key      message key.
+     */
+    public final void notice(String key) {
+        printNotice(text(key));
+    }
+
+    /**
+     * Print a notice with message key <code>key</code>
+     * and argument <code>s0</code>.
+     *
+     * @param key      message key.
+     * @param s0       argument to message.
+     */
+    public final void notice(String key, String s0) {
+        printNotice(text(key,s0));
+    }
+
+    /**
+     * Print a notice with message key <code>key</code>
+     * and arguments <code>s0,s1</code>.
+     *
+     * @param key      message key.
+     * @param s0       argument to message.
+     * @param s1       argument to message.
+     */
+    public final void notice(String key, String s0, String s1) {
+        printNotice(text(key,s0,s1));
+    }
+
+    /**
+     * Print a notice with message key <code>key</code>
+     * and arguments <code>s0,s1,s2</code>.
+     *
+     * @param key      message key.
+     * @param s0       argument to message.
+     * @param s1       argument to message.
+     * @param s2       argument to message.
+     */
+    public final void notice(String key, String s0, String s1,
+                            String s2) {
+        printNotice(text(key,s0,s1,s2));
+    }
+
+    /**
+     * Print a notice with message key <code>key</code>
+     * and arguments <code>s0,s1,s2,bigbird</code>.
+     *
+     * @param key      message key.
+     * @param s0       argument to message.
+     * @param s1       argument to message.
+     * @param s2       argument to message.
+     * @param bigbird  argument to message.
+     */
+    public final void notice(String key, String s0, String s1,
+                            String s2, String bigbird) {
+        printNotice(text(key,s0,s1,s2,bigbird));
+    }
+    
+    /**
+     * Returns the String for message key <code>key</code>.
+     *
+     * @return               String for message
+     *                       key <code>key</code>.
+     */
+    protected final String text(String key) {
+        return text(key, "");
+    }
+
+    /**
+     * Returns the String for message key <code>key</code>
+     * and argument <code>s0</code>
+     *
+     * @param  s0             argument to message.
+     * @return                String for message
+     *                        key <code>key</code>. 
+     */
+    protected final String text(String key, String s0) {
+        return text(key, s0, "");
+    }
+
+    /**
+     * Returns the String for message key <code>key</code>
+     * and arguments <code>s0,s1</code>
+     *
+     * @param  s0             argument to message.
+     * @param  s1             argument to message.
+     * @return                String for message
+     *                        key <code>key</code>.
+     */
+    protected final String text(String key, String s0, String s1) {
+        return text(key, s0, s1, "");
+    }
+
+    /**
+     * Returns the String for message key <code>key</code>
+     * and arguments <code>s0,s1,s2</code>
+     *
+     * @param  s0             argument to message.
+     * @param  s1             argument to message.
+     * @param  s2             argument to message.
+     * @return                String for message
+     *                        key <code>key</code>.
+     */
+    protected final String text(String key, String s0, String s1,
+                              String s2) {
+        return text(key, s0, s1, s2, "");
+    }
+
+    /**
+     * Returns the String for message key <code>key</code>
+     * and arguments <code>s0,s1,s2,oscarTheGrouch</code>
+     *
+     * @param  s0             argument to message.
+     * @param  s1             argument to message.
+     * @param  s2             argument to message.
+     * @param  oscarTheGrouch argument to message.
+     * @return                String for message
+     *                        key <code>key</code>.
+     */
+    protected final String text(String key, String s0, String s1,
+                              String s2, String oscarTheGrouch) {
+        return text(key, new String[]{s0,s1,s2,oscarTheGrouch});
+    }
+
+    /**
+     * Returns the String for the message key <code>key</code>
+     * with arguments contained in <code>args</code>.
+     *
+     * @param key  message key.
+     * @param args array of arguments to substitute.
+     * @return     String for message with key
+     *             <code>key</code> and arguments
+     *             <code>args</code>
+     */
+    protected final String text(String key, String[] args) {
+        String msg = MessageFormat.format(string(key), args);
+        msgs.add(msg);
+        return msg;
+    }
+
+    /**
+     * Returns the String with message <code>key</code>.
+     *
+     * @param key message key.
+     * @return String for message with key <code>key</code>.
+     */
+    protected final String string(String key) {
+        keys.add(key);
+        try {
+            return bundle.getString(key);
+        } catch (MissingResourceException e) {
+            throw new Error("Can't find " + key + " in " + bundle);
+        }
+    }
+    PrintWriter getErr() { 
+        return err;
+    }
+    PrintWriter getOut() { 
+        return out;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ExecutableMemberDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ExecutableMemberDocImpl.java
new file mode 100644 (file)
index 0000000..807ef08
--- /dev/null
@@ -0,0 +1,307 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.AdviceDoc;
+import org.aspectj.compiler.base.ast.Formals;
+import org.aspectj.compiler.base.ast.NameType;
+import org.aspectj.compiler.base.ast.TypeDs;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ExecutableMemberDoc;
+import com.sun.javadoc.ParamTag;
+import com.sun.javadoc.Parameter;
+import com.sun.javadoc.ThrowsTag;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public abstract class ExecutableMemberDocImpl
+    extends MemberDocImpl
+    implements ExecutableMemberDoc {
+
+    /*
+     * These three fields should be final, but can't because
+     * they contain calls to abstract methods that aren't
+     * valid until after the subclasses constructor is run.
+     * To compensate the accessor methods lazily evaluate
+     * them, and these methods are final.
+     */
+
+    /** The collection of advice placed on each ExecutableMemberDoc. */
+    private Collection advice;
+
+    /** The List of parameters. */
+    private Collection parameters;
+
+    /** The List of thrown exceptions. */
+    private Collection thrownExceptions;
+
+    /** The full signature. */
+    private String signature;
+
+    /** The flat signature. */
+    private String flatSignature;
+
+    /**
+     * Constructs a new Doc with the enclosing ClassDoc.
+     *
+     * @param containingClass enclosing ClassDoc.
+     */
+    public ExecutableMemberDocImpl(ClassDoc containingClass) {
+        super(containingClass);
+    }
+    
+    /**
+     * Returns a non-null Collection of AdviceDoc
+     * representing the advice placed on the underlying Dec.
+     *
+     * @return a non-null Collection of AdviceDoc
+     *         representing the advice placed on the
+     *         underlying Dec.
+     */
+    protected abstract Collection createAdvice();
+
+    /**
+     * Returns the Formals of the underlying Dec.
+     *
+     * @return the Formals of the underlying Dec.
+     */
+    protected abstract Formals getFormals();
+
+    /**
+     * Returns the TypeDs representing the exceptions
+     * thrown by the underlying Dec.
+     *
+     * @return the TypeDs representing the exceptions
+     *         thrown by the underlying Dec.
+     */
+    protected abstract TypeDs getThrows();
+
+
+    /**
+     * Converts the passed in Formals to a Collection of
+     * Parameter and sets our parameters to this value.
+     *
+     * @param formals the Formals to use.
+     */
+    public void makeParameters(Formals formals) {
+        parameters = createParameters(formals);
+    }
+
+    /**
+     * Converts the passed in TypeDs to a Collection of
+     * ClassDoc and sets our thrownExceptions to this value.
+     *
+     * @param thrown the TypeDs to use.
+     */
+    public void makeThrownExceptions(TypeDs thrown) {
+        thrownExceptions = createThrownExceptions(thrown);
+    }
+
+    /**
+     * Returns the advice affecting this member.
+     *
+     * @return an array of AdviceDoc representing the advice
+     *         affecting this member.
+     */
+    public final AdviceDoc[] advice() {
+        if (advice == null) advice = createAdvice();
+        return (AdviceDoc[])advice.toArray(new AdviceDoc[advice.size()]);
+    }
+
+    /**
+     * Returns the exceptions this code declares to throw.
+     *
+     * @return an array of ClassDoc representing the exceptions
+     *         this code declares to throw.
+     */
+    public final ClassDoc[] thrownExceptions() {
+        if (thrownExceptions == null) makeThrownExceptions(getThrows());
+        return (ClassDoc[])thrownExceptions.toArray
+            (new ClassDoc[thrownExceptions.size()]);
+    }
+
+    /**
+     * Returns the parameters taken by this code.
+     *
+     * @return an array of Parameter representing the
+     *         parameters this code takes.
+     */
+    public final Parameter[] parameters() {
+        if (parameters == null) makeParameters(getFormals());
+        return (Parameter[])parameters.toArray
+            (new Parameter[parameters.size()]);
+    }
+
+    /**
+     * Returns the flat signature.
+     *
+     * @return the flat signature with all types unqualified.
+     */
+    public String flatSignature() {
+        if (flatSignature == null) {
+            flatSignature = Util.flatSignature(parameters());
+        }
+        return flatSignature;
+    }
+
+    /**
+     * Returns the full signature.
+     *
+     * @return the full signature with all types qualified.
+     */
+    public String signature() {
+        if (signature == null) {
+            signature = Util.signature(parameters());
+        }
+        return signature;
+    }
+
+    /**
+     * Returns <code>true</code> if this code is <code>synchronized</code>.
+     *
+     * @return <code>true</code> if this code is <code>synchronized</code>.
+     */
+    public boolean isSynchronized() {
+        //return getModifiers().isSynchronized();
+        return Modifier.isSynchronized(modifierSpecifier());
+    }
+    
+    /**
+     * Returns <code>true</code>if this code is <code>native</code>.
+     *
+     * @return <code>true</code>if this code is <code>native</code>.
+     */
+    public boolean isNative() {
+        //return (modifierSpecifier() & Modifiers.NATIVE) != 0;
+        return Modifier.isNative(modifierSpecifier());
+    }
+
+    /**
+     * Returns the throw tags describing exceptions thrown
+     * declared by this code.
+     *
+     * @return an array of ThrowsTag representing the exception
+     *         this code declares to throw.
+     */
+    public ThrowsTag[] throwsTags() {
+        return getComment().throwsTags();
+    }
+
+    /**
+     * Returns the param tags describing parameters taken
+     * by this code.
+     *
+     * @return an array of ParamTag representing the
+     *         parameters taken by this code.
+     */
+    public ParamTag[] paramTags() {
+        return getComment().paramTags();
+    }
+
+    /**
+     * Returns the simple name followed the parameters
+     * enclosed in parens.
+     *
+     * @return the simple name followed the parameters
+     *         enclosed in parens.
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer(name());
+        sb.append('(');
+        Parameter[] params = parameters();
+        for (int i = 0, N = params.length; i < N; i++) {
+            if (i > 0) sb.append(",");
+            sb.append(params[i].type().qualifiedTypeName());
+            sb.append(params[i].type().dimension());
+        }
+        sb.append(')');
+        return sb.toString();
+    }
+
+    /**
+     * Returns a Collection of Parameter corresponding to
+     * the Formals passed in.
+     *
+     * @param formals the Formals to use.
+     * @return        a Collection of Parameter corresponding to
+     *                the Formals passed in.
+     */
+    private Collection createParameters(Formals formals) {
+        if (formals == null) return Collections.EMPTY_LIST;
+        List list = new ArrayList(formals.size());
+        for (int i = 0, N = formals.size(); i < N; i++) {
+            list.add(new ParameterImpl(formals.get(i)));
+        }
+        return list;
+    }
+
+    /**
+     * Returns a Collection of ClassDoc corresponding to
+     * the TypeDs passed in.
+     *
+     * @param thrown the TypeDs to use
+     * @return        a Collection of ClassDoc corresponding to
+     *                the TypeDs passed in.
+     */
+    private Collection createThrownExceptions(TypeDs typeds) {
+        if (typeds == null) return Collections.EMPTY_LIST;
+        List list = new ArrayList(typeds.size());
+        for (int i = 0, N = typeds.size(); i < N; i++) {
+            list.add(ClassDocImpl.getInstance
+                     (((NameType)typeds.get(i).getType()).getTypeDec()));
+        }
+        return list;
+    }
+
+    /**
+     * Returns <code>true</code> if the passed in Object is
+     * an ExecutableMemberDocImpl, its name equals ours, and
+     * its parameters <code>equals</code> ours.
+     *
+     * @return equality based on name and parameters.
+     */
+    public boolean weakEquals(Object md) {
+        if (!(md instanceof ExecutableMemberDocImpl)) {
+            return false;
+        }
+        ExecutableMemberDocImpl emdi = (ExecutableMemberDocImpl)md;
+        if (!name().equals(emdi.name())) {
+            return false;
+        }
+        Parameter[] ourPds = this.parameters();
+        Parameter[] edsPds = emdi.parameters();
+        if (ourPds.length != edsPds.length) {
+            return false;
+        }
+        for (int i = 0, N = ourPds.length; i < N; i++) {
+            if (!ourPds[i].equals(edsPds[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/FieldDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/FieldDocImpl.java
new file mode 100644 (file)
index 0000000..2f0ca4c
--- /dev/null
@@ -0,0 +1,140 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ast.Dec;
+import org.aspectj.compiler.base.ast.FieldDec;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.SerialFieldTag;
+
+import java.lang.reflect.Modifier;
+
+public class FieldDocImpl
+    extends    MemberDocImpl
+    implements org.aspectj.ajdoc.FieldDoc {
+
+    /** The FieldDec that corresponds to this FieldDoc. */
+    private final FieldDec field;
+
+    /**
+     * The type of this field.  This can't be set initially
+     * because the compiler doesn't resolve the types for
+     * introductions, yet, so we have to allow others to set it.
+     */
+    private org.aspectj.compiler.base.ast.Type type;
+
+    /**
+     * Sets the org.apectj.compiler.base.ast.Type used to return
+     * the com.sun.javadoc.Type.
+     *
+     * @param type the new org.aspectj.compiler.base.ast.Type used
+     *             to find the com.sun.javadoc.Type.
+     * @hack       This is only needed because of unresolved
+     *             introduced fields.
+     */
+    public void setType(org.aspectj.compiler.base.ast.Type type) {
+        this.type = type;
+    }
+
+    public FieldDocImpl(ClassDoc containingClass, FieldDec field) {
+        super(containingClass);
+        this.field = field;
+        setType(field.getType());
+    }
+
+    protected Dec dec() {
+        return field;
+    }
+
+    
+    protected FieldDec fieldDec() {
+        return field;
+    }
+
+    /**
+     * Returns <code>true</code>.
+     *
+     * @return <code>true</code>.
+     */
+    public boolean isField() {
+        return true;
+    }
+
+    /**
+     * Returns the type of this field.
+     *
+     * @return the type of this field.
+     */
+    public com.sun.javadoc.Type type() {
+        return TypeImpl.getInstance(type);
+    }
+
+    /**
+     * Return <code>true</code> is this field is <code>volatile</code>.
+     *
+     * @return <code>true</code> is this field is <code>volatile</code>.
+     */
+    public boolean isVolatile() {
+        return Modifier.isVolatile(modifierSpecifier());
+    }
+
+    /**
+     * Return <code>true</code> is this field is <code>transient</code>.
+     *
+     * @return <code>true</code> is this field is <code>transient</code>.
+     */
+    public boolean isTransient() {
+        return Modifier.isTransient(modifierSpecifier());
+    }
+
+    /**
+     * Returns the serial field tags for this field.
+     *
+     * @return an array of SerialFieldTag representing the
+     *         serial field tags for this field.
+     */
+    public SerialFieldTag[] serialFieldTags() {
+        return getComment().serialFieldTags();
+    }
+
+    /**
+     * Returns the name of the field.
+     *
+     * @return the name of the field.
+     */
+    public String toString() {
+        return name();
+    }
+
+    /**
+     * Returns <code>true</code> is <code>md</code> is a
+     * FieldDocImpl and has the same name.
+     *
+     * @return <code>true</code> is <code>md</code> is a
+     *         FieldDocImpl and has the same name.
+     */
+    public boolean weakEquals(Object md) {
+        if (!(md instanceof FieldDocImpl)) return false;
+        return name().equals(((FieldDocImpl)md).name());
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/FilteredDecList.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/FilteredDecList.java
new file mode 100644 (file)
index 0000000..df137ad
--- /dev/null
@@ -0,0 +1,219 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ast.ConstructorDec;
+import org.aspectj.compiler.base.ast.Dec;
+import org.aspectj.compiler.base.ast.FieldDec;
+import org.aspectj.compiler.base.ast.MethodDec;
+import org.aspectj.compiler.base.ast.Type;
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.crosscuts.ast.PointcutDec;
+
+import java.util.ArrayList;
+
+/**
+* Factory collection with Type-specific "add" methods which 
+* checks if ..Dec should be included and if so constructs and adds.
+* A Dec should be included if AccessChecker.canAccess({Dec variants}) 
+* and the type is the same (if type is specified).
+* This consolidates construction of DocImpl for classes and class members.
+*/
+public class FilteredDecList extends ArrayList {
+    final protected AccessChecker filter ; 
+    final protected ClassDocImpl classDocImpl ; 
+    final protected Type declaringType ; 
+
+    /**
+     * Create a declaration list enforced by a filter and
+     * optionally a ClassDocImpl.  If the ClassDocImpl is not null,
+     * then you cannot add members outside its type; if it is null,
+     * attempting to add members has undefined results.  (You may
+     * still create ClassDoc.)
+     * @param filter the AccessChecker used to test for inclusion
+     *           (use AccessChecker.PUBLIC if null)
+     * @param type the classDocImpl used to construct added members
+     *             and ensure they are declared in this type
+     *             (ignore test if null)
+     */
+    FilteredDecList(AccessChecker filter, ClassDocImpl classDocImpl) {
+        this.filter = (null != filter ? filter
+                       : AccessChecker.PUBLIC);
+        this.classDocImpl = classDocImpl;
+        TypeDec td = (null == classDocImpl? null
+                              : classDocImpl.typeDec());
+        this.declaringType = (null == td? null : td.getType());
+    }
+
+    /** 
+     * Check for match with our type (if set)
+     * @param dec the Dec to get the incoming declaring type from
+     * @return true unless our type is set and does not equals dec declaring type 
+     */
+    protected final boolean sameType(Dec dec) {
+        Type other = (null == dec ? null : dec.getDeclaringType());
+        boolean result = ((null != dec) 
+                          && ((declaringType == null) 
+                              || declaringType.equals(other))) ;
+        /*
+          System.err.println("sameType("+dec+") " + declaringType 
+          + " ?= " + other);
+          if (!result) {
+          System.err.println("false FilteredDecList.sameType(" + dec 
+          + ") us " + declaringType);
+          }
+        */
+        return result;
+    }
+
+    /**
+     * Implements policy on incoming TypeDec.
+     * @param dec the TypeDec to check
+     * @throws IllegalArgumentException if null == dec
+     */
+    protected void checkDec(Dec dec) {
+        if (null == dec) throw new IllegalArgumentException("null dec");
+    }
+
+    /**
+     * Construct and add inner class from dec
+     * if outer is included and dec should be included.
+     * @param outer the ClassDocImpl which encloses this dec
+     * @param dec the TypeDec for the inner class to add to this list, enclosed by outer
+     * @return false if dec is null or true if added
+     * @throws IllegalArgumentException if outer is null or dec is null
+     */
+    public boolean add(ClassDocImpl outer, TypeDec dec) {
+        checkDec(dec);
+        if (null == outer) throw new IllegalArgumentException("null outer");
+        if ((filter.canAccess(outer.typeDec()) && filter.canAccess(dec))) {
+            ClassDocImpl doc = ClassDocImpl.getInstance(outer, dec);
+            if (null != doc) {
+                doc.setIncluded(true);
+                return add((Object) doc);
+            }
+        }
+        denied(outer, dec);
+        return false;
+    }
+            
+    /** 
+     * Add ClassDocImpl if dec should be included 
+     * and ClassDocImpl.getInstance(..) returns something.
+     * Also sets the included property to true;
+     * @param dec the TypeDec for the class to add
+     * @return false if dec is null or true if added
+     * @throws IllegalArgumentException if outer is null or dec is null
+     */
+    public boolean add(TypeDec dec) {
+        checkDec(dec);
+        if (filter.canAccess(dec)) {
+            ClassDocImpl doc = ClassDocImpl.getInstance(dec);
+            if (null != doc) {
+                doc.setIncluded(true);
+                return add((Object) doc);
+            }
+        }
+        denied(dec);
+        return false;
+    }
+
+    /** 
+     * Add MethodDocImpl to this list if dec should be included 
+     * @param dec the MethodDoc for the method to add
+     * @return true if added
+     * @throws IllegalArgumentException if dec is null
+     */
+    public boolean add(MethodDec dec) {
+        checkDec(dec);
+        if (sameType(dec) && filter.canAccess(dec)) {
+            return add((Object) new MethodDocImpl(classDocImpl, dec));
+        }
+        denied(dec);
+        return false;
+    }
+
+    /** 
+     * Add ConstructorDocImpl to this list if dec should be included 
+     * @param dec the ConstructorDoc for the constructor to add
+     * @return true if added
+     * @throws IllegalArgumentException if dec is null
+     */
+    public boolean add(ConstructorDec dec) {
+        checkDec(dec);
+        if (sameType(dec) && filter.canAccess(dec)) {
+            return add((Object) new ConstructorDocImpl(classDocImpl, dec));
+        }
+        denied(dec);
+        return false;
+    }
+
+    /** 
+     * Add FieldDocImpl to this list if dec should be included 
+     * @param dec the FieldDoc for the field to add
+     * @return true if added
+     * @throws IllegalArgumentException if dec is null
+     */
+    public boolean add(FieldDec dec) {
+        checkDec(dec);
+        if (sameType(dec) && filter.canAccess(dec)) {
+            return add((Object) new FieldDocImpl(classDocImpl, dec));
+        }
+        denied(dec);
+        return false;
+    }
+
+    /** 
+     * Add PointcutDocImpl to this list if dec should be included 
+     * @param dec the PointcutDoc for the pointcut to add
+     * @return true if added
+     * @throws IllegalArgumentException if dec is null
+     */
+    public boolean add(PointcutDec dec) {
+        checkDec(dec);
+        if (sameType(dec) && filter.canAccess(dec)) {
+            return add((Object) new PointcutDocImpl(classDocImpl, dec));
+        }
+        denied(dec);
+        return false;
+    }
+
+    /** 
+     * Called when some dec and outer is denied addition. 
+     * Currently does nothing. 
+     * @param outer the ClassDocImpl which encloses this dec
+     * @param dec the TypeDec for the inner class to add to this list, enclosed by outer
+     */
+    protected void denied(ClassDocImpl outer, TypeDec dec) {
+        // System.err.println(this + " denied " + o + " with " + p);
+    }
+
+    /** 
+     * signalled when some dec is denied addition. 
+     * Currently does nothing. 
+     * @param dec the Dec denied addition
+     */
+    protected void denied(Dec dec) {
+        // System.err.println(this + " denied " + o);
+    }
+} // class FilteredDecList
+
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/IntroducedDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/IntroducedDocImpl.java
new file mode 100644 (file)
index 0000000..f496697
--- /dev/null
@@ -0,0 +1,169 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.ClassDoc;
+import org.aspectj.ajdoc.IntroducedDoc;
+import org.aspectj.ajdoc.MemberDoc;
+import org.aspectj.compiler.base.ast.ConstructorDec;
+import org.aspectj.compiler.base.ast.Dec;
+import org.aspectj.compiler.base.ast.FieldDec;
+import org.aspectj.compiler.base.ast.MethodDec;
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.crosscuts.ast.GenTypeName;
+import org.aspectj.compiler.crosscuts.ast.IntroducedDec;
+
+import java.util.Iterator;
+import java.util.Set;
+
+public class IntroducedDocImpl extends IntroductionDocImpl implements IntroducedDoc {
+
+    /** The introduction to which we delegate. */
+    private final IntroducedDec introducedDec;
+
+    /** The member this introduction introduced. */
+    private final MemberDocImpl member;
+
+    public IntroducedDocImpl(com.sun.javadoc.ClassDoc containingClass,
+                             IntroducedDec introducedDec) {
+        super(containingClass);
+        this.introducedDec = introducedDec; // used by findMember
+        (member = findMember()).setIntroduced(this);
+        createTargets();
+    }
+
+    protected Dec dec() {
+        return introducedDec;
+    }
+
+    protected void createTargets() {
+        /*
+         * HACK:
+         * Because the compiler doesn't resolve the types
+         * of introductions, yet, we have to set the introduced
+         * doc (member) with the appropriate fields, whether it's a
+         *  - field
+         *  - method
+         *  - constructor
+         */
+        Set affects = ajc().getCorrespondences().getAffects(introducedDec);
+        if (affects.size() < 1) return;
+    nextType:
+        for (Iterator it = affects.iterator(); it.hasNext();) {
+            Object o = it.next();
+            if (o instanceof TypeDec) {
+                TypeDec owner = (TypeDec)o;
+                ClassDoc cd = ClassDocImpl.getInstance(owner);
+                com.sun.javadoc.FieldDoc[] fs = cd.fields();
+                for (int i = 0; i < fs.length; i++) {
+                    if (member.weakEquals(fs[i])) { // XXX weakEquals is unimplemented
+                        ((FieldDocImpl)fs[i]).setIntroduced(this);
+                        addTarget(cd);
+                        ((FieldDocImpl)member).setType(((FieldDocImpl)fs[i]).
+                                                       fieldDec().getType());
+                        // why fixup only fields?
+                        continue nextType;
+                    }
+                }
+                com.sun.javadoc.MethodDoc[] ms = cd.methods();
+                for (int i = 0; i < ms.length; i++) {
+                    if (member.weakEquals(ms[i])) {
+                        ((MethodDocImpl)ms[i]).setIntroduced(this);
+                        addTarget(cd);
+                        ((MethodDocImpl)member).setType(((MethodDocImpl)ms[i]).
+                                                        codeDec().getResultTypeD().
+                                                        getType());
+                        ((ExecutableMemberDocImpl)member).
+                            makeParameters(((MethodDocImpl)ms[i]).
+                                           codeDec().getFormals());
+                        continue nextType;
+                    }
+                }
+                com.sun.javadoc.ConstructorDoc[] cs = cd.constructors();
+                for (int i = 0; i < cs.length; i++) {
+                    if (member.weakEquals(cs[i])) {
+                        ((ConstructorDocImpl)cs[i]).setIntroduced(this);
+                        addTarget(cd);
+                        ((ExecutableMemberDocImpl)member).
+                            makeParameters(((ConstructorDocImpl)cs[i]).
+                                           codeDec().getFormals());
+                        continue nextType;
+                    }
+                }
+            }
+        }
+    }
+
+    public MemberDoc member() {
+        return member;
+    }
+
+    /**
+     * Returns the name of the member introduction.
+     *
+     * @return the name.
+     */
+    public String name() { // XXX unused?
+        Dec indec = introducedDec.getDec();
+        if (indec != null) {
+            return "" + indec.getId(); // XXX
+        } else {
+            return "";
+        }
+    }
+    
+    private MemberDocImpl findMember() {
+        Dec dec = introducedDec.getDec();
+        // fix applied all, though bug was only in methods and constructors
+        // verified working in all, including fields
+        dec.setSourceLocation(introducedDec.getSourceLocation()); // PR790, 712
+        //TODO: a little hacky now
+        if (dec instanceof FieldDec) {
+            return new FieldDocImpl(containingClass(),
+                                      (FieldDec)dec);
+
+        } else if (dec instanceof ConstructorDec) {
+            return new ConstructorDocImpl(containingClass(),
+                                          (ConstructorDec)dec);
+        } else if (dec instanceof MethodDec) {
+            return new MethodDocImpl(containingClass(),
+                                     (MethodDec)dec);
+        } else {
+            return null;
+        }
+        // should print type pattern for type of introduced member,
+        // but it messes up source/target associations
+//      GenTypeName gtn = introducedDec.getTargets();
+//      if (null != gtn) {
+//         name = gtn.toShortString() + name;
+//      }
+    }
+     /**
+      * Returns the toString() of the member.
+      *
+      * @return the toString() of the member.
+      */
+     public String toString() {
+         return member.toString();
+     }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/IntroducedSuperDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/IntroducedSuperDocImpl.java
new file mode 100644 (file)
index 0000000..52dd851
--- /dev/null
@@ -0,0 +1,103 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.IntroducedSuperDoc;
+import org.aspectj.compiler.base.ast.Dec;
+import org.aspectj.compiler.base.ast.TypeDs;
+import org.aspectj.compiler.crosscuts.ast.IntroducedSuperDec;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class IntroducedSuperDocImpl
+    extends    IntroductionDocImpl
+    implements IntroducedSuperDoc {
+
+    /** The introduction to which we delegate. */
+    private final IntroducedSuperDec introducedSuperDec;
+
+    /** The types we introduce onto our targets. */
+    private final Collection types;
+
+    public IntroducedSuperDocImpl(com.sun.javadoc.ClassDoc containingClass,
+                                  IntroducedSuperDec introducedSuperDec) {
+        super(containingClass);
+        this.introducedSuperDec = introducedSuperDec;
+        types = createTypes();
+    }
+
+    protected Dec dec() {
+        return introducedSuperDec;
+    }
+
+    /**
+     * Returns <code>true</code> is this introduction
+     * places <code>implements</code> introductions on its
+     * targets.
+     *
+     * @return <code>true</code> is this introduction
+     *         places <code>implements</code> introductions
+     *         on its targets.
+     */
+    public boolean isImplements() {
+        return introducedSuperDec.getIsImplements();
+    }
+
+    /**
+     * Returns the types that this introduction introduces
+     * into it's targets type hierarchy.
+     *
+     * @return an array of org.aspectj.ajdoc.Type representing
+     *         the types this introduction has introducted onto
+     *         its targets type hierarchy.
+     */
+    public org.aspectj.ajdoc.Type[] types() {
+        return (org.aspectj.ajdoc.Type[])types.toArray
+            (new org.aspectj.ajdoc.Type[types.size()]);
+    }
+
+    /**
+     * Returns the name of the type introduction. 
+     *
+     * @return the name.
+     */
+    public String name() { if (true) return ""; // XXX unimplemented
+        return (introducedSuperDec.getTypeDs().size() != 0)
+            ?  ((org.aspectj.ajdoc.Type)introducedSuperDec.getTypeDs().
+                get(0).getType()).typeName()
+            :  "";
+        //TODO: This could fuck us up!!!
+    }
+
+    private final Collection createTypes() {
+        TypeDs typeds = introducedSuperDec.getTypeDs();
+        if (typeds == null) return Collections.EMPTY_LIST;
+        List list = new ArrayList();
+        for (int i = 0, N = typeds.size(); i < N; i++) {
+            list.add(ClassDocImpl.getInstance(typeds.get(i).getType().getTypeDec()));
+        }
+        return list;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/IntroductionDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/IntroductionDocImpl.java
new file mode 100644 (file)
index 0000000..84be926
--- /dev/null
@@ -0,0 +1,86 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.ClassDoc;
+import org.aspectj.ajdoc.IntroductionDoc;
+import org.aspectj.compiler.crosscuts.ast.IntroducedDec;
+import org.aspectj.compiler.crosscuts.ast.IntroducedSuperDec;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public abstract class IntroductionDocImpl
+    extends    MemberDocImpl
+    implements IntroductionDoc {
+
+    /** Creats a new instance of IntroductionDoc from <code>o</code>. */
+    public static IntroductionDocImpl getInstance(AspectDoc ad, Object o) {
+        return factory.getInstance(ad, o);
+    }
+
+    /** The factory in charge of creating instances of IntroductionDocImpl. */
+    private final static Factory factory = new Factory();
+
+    private final Collection targets = new ArrayList();
+    
+    public void addTarget(ClassDoc cd) { targets.add(cd); }
+
+    protected IntroductionDocImpl(com.sun.javadoc.ClassDoc containingClass) {
+        super(containingClass);
+    }
+
+    //protected abstract Collection createTargets();
+
+    /**
+     * Returns the classes that are affected by this introduction.
+     *
+     * @return an array of ClassDoc representing the classes
+     *         affected by this introduction.
+     */
+    public final ClassDoc[] targets() {
+        //if (targets == null) targets = createTargets();
+        return (ClassDoc[])targets.toArray(new ClassDoc[targets.size()]);
+    }
+
+    /**
+     * The class is in charge of creating
+     * instances of IntroductionDocImpl.
+     */
+    private final static class Factory {
+        public static IntroductionDocImpl getInstance(AspectDoc ad, Object o) {
+            if (o instanceof IntroducedSuperDec) {
+                return new IntroducedSuperDocImpl(ad, (IntroducedSuperDec)o);
+            }
+            if (o instanceof IntroducedDec) {
+                return new IntroducedDocImpl(ad, (IntroducedDec)o);
+            }
+            return null;
+        }
+    }
+
+    /** TODO */
+    public boolean weakEquals(Object md) {
+        return false; // TODO
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Main.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Main.java
new file mode 100644 (file)
index 0000000..c640b5d
--- /dev/null
@@ -0,0 +1,112 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+/**
+ * Entry point for ajdoc.
+ *
+ * @author Jeff Palm
+ */
+public class Main {
+    /** 
+     * value returned from execute(..) 
+     * when the JDK tools are not supported 
+     */
+    public static final int PLATFORM_ERROR = 3;
+
+    /**
+     * Call {@link #execute} and exit with
+     * its exit code.
+     *
+     * @param args Command line arguments.
+     */
+    public static void main(String[] args) {
+        System.exit(execute(args));
+    }
+
+    /**
+     * Programmatic entry without calling <code>System.exit</code>,
+     * returning the result of {@link Ajdoc#execute(String[])}.
+     *
+     * @param args Command line arguments.
+     * @return PLATFORM_ERROR if platformErrorMessage() is not null
+     *         or the result of calling {@link Ajdoc#execute(String[])}.
+     * @throw Error if bad platform - look at message
+     */
+    public static int execute(String[] args) {
+        int result = 0;
+        String platformError = platformErrorMessage();
+        if (null != platformError) {
+            result = PLATFORM_ERROR;
+            System.err.println(platformError);
+        } else {
+            Ajdoc me  = new Ajdoc();
+            result = me.execute(args);
+        }
+        return result;
+    }
+
+    /**
+     * Generate version error message if we cannot run in this VM
+     * or using this class path.
+     * @return null if no error or String describing error otherwise
+     */
+    public static String platformErrorMessage() {
+        // todo: stolen from ajc.Main
+        boolean failed = false;
+        final String[] versions = new String[] 
+        { "java.lang.reflect.Proxy"   // 1.3: failed if class not found
+          // permit users to run in 1.4 iff using 1.3 tools.jar
+          //, "java.lang.CharSequence"  // 1.4: failed if class found
+        };
+        for (int i = 0; i < versions.length; i++) {
+            try {
+                Class.forName(versions[i]);
+                failed = (i == 1);
+            } catch (ClassNotFoundException cnfe) {
+                failed = (i == 0);
+            } catch (Error err) {
+                failed = (i == 0);
+            }
+            if (failed) {
+                String version = "(unknown version)";
+                try { version = System.getProperty("java.version"); }
+                catch (Throwable t) { } // ignore
+                return "Ajdoc requires J2SE 1.3; not java " + version;
+            }
+        }
+        // now looking for tools.jar
+        try {
+            Class.forName("com.sun.javadoc.RootDoc"); // may be version error
+            Class.forName("com.sun.javadoc.Type"); // not in 1.4 
+        } catch (ClassNotFoundException cnfe) {
+            // System.err.println(cnfe.getMessage());
+            // cnfe.printStackTrace(System.err); // XXX
+            return "Requires tools.jar from J2SE 1.3 (not 1.2 or 1.4) be on the class path";
+        } catch (Error err) { // probably wrong version of the class
+            // System.err.println(err.getMessage());
+            // err.printStackTrace(System.err); // XXX
+            return "Requires tools.jar from J2SE 1.3 (not 1.2 or 1.4) be on the class path";
+        }
+        return null;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/MemberDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/MemberDocImpl.java
new file mode 100644 (file)
index 0000000..63e6fed
--- /dev/null
@@ -0,0 +1,82 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.IntroducedDoc;
+import org.aspectj.ajdoc.MemberDoc;
+
+public abstract class MemberDocImpl
+    extends ProgramElementDocImpl
+    implements MemberDoc {
+    
+    /**
+     * The introduction that introduces this member
+     * to its enclosing type.
+     */
+    private IntroducedDoc introduced;
+
+    public MemberDocImpl(com.sun.javadoc.ClassDoc containingClass) {
+        super(containingClass);
+    }
+
+    /**
+     * Returns whether the passed in Object is equals
+     * based on type <b>names</b> and the name
+     * of the declaration.
+     *
+     * @return <code>true</code> if the passed in Object
+     *         is equal to this based on type names
+     *         and field names.
+     */
+    public abstract boolean weakEquals(Object other);
+
+    /**
+     * Sets this member's introduction.
+     *
+     * @param introduced the new introduction.
+     */
+    protected void setIntroduced(IntroducedDoc introduced) {
+        this.introduced = introduced;
+    }
+
+    /**
+     * Returns the introduction that introduced this member onto
+     * its enclosing type -- this value may be <code>null</code>
+     * if the member wasn't introduced.
+     *
+     * @return an IntroducedDoc representing the introduction
+     *         that introduced this member onto its enclosing
+     *         type.  The return value may be <code>null</code>.
+     */
+    public IntroducedDoc introduced() {
+        return introduced;
+    }
+
+    /**
+     * Returns <code>true</code>if this code is <i>synthetic</i>.
+     *
+     * @return <code>true</code>if this code is <i>synthetic</i>.
+     */
+    public boolean isSynthetic() {
+        return (!dec().isLanguageVisible());
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/MethodDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/MethodDocImpl.java
new file mode 100644 (file)
index 0000000..ff1d850
--- /dev/null
@@ -0,0 +1,125 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ast.MethodDec;
+import org.aspectj.compiler.base.ast.NameType;
+import org.aspectj.compiler.base.ast.TypeDec;
+
+import com.sun.javadoc.ClassDoc;
+
+import java.lang.reflect.Modifier;
+
+public class MethodDocImpl
+    extends    CodeDocImpl
+    implements org.aspectj.ajdoc.MethodDoc {
+
+    /*
+     * This is a hack because the compiler isn't resolving
+     * introduced types.
+     */
+    private org.aspectj.compiler.base.ast.Type type;
+    public void setType(org.aspectj.compiler.base.ast.Type type) {
+        this.type = type;
+    }
+
+    public MethodDocImpl(ClassDoc containingClass, MethodDec methodDec) {
+        super(containingClass, methodDec);
+        setType(codeDec().getResultTypeD().getType());
+    }
+    
+    protected MethodDec methodDec() {
+        return (MethodDec)codeDec();
+    }
+
+    /**
+     * Returns <code>true</code>.
+     *
+     * @return <code>true</code>.
+     */
+    public boolean isMethod() {
+        return true;
+    }
+
+    /**
+     * Returns <code>true</code> if this method is <code>abstract</code>.
+     *
+     * @return <code>true</code> if this method is <code>abstract</code>.
+     */
+    public boolean isAbstract() {
+        return methodDec().isAbstract();
+    }
+    
+    /**
+     * Returns the return type of this method.
+     *
+     * @return the Type representing the type this
+     *         method returns.
+     */
+    public com.sun.javadoc.Type returnType() {
+        return TypeImpl.getInstance(type);
+        //return null; //TODO getResultTypeD().getType();
+    }
+
+    /**
+     * Returns the type that nearest super class that defines
+     * this method.
+     *
+     * @return the type that nearest super class that defines
+     *         this method.
+     */
+    public ClassDoc overriddenClass() {
+        //Exprs params = getFormals().makeExprs(); // do this for side-effect?XXX
+        TypeDec where = methodDec().getDeclaringType().getTypeDec();
+        NameType superType = (NameType)where.getSuperClassType();
+        while (superType != null) {
+            MethodDec method = Util.methodDec(superType,
+                                              methodDec().getId(),
+                                              methodDec().getFormals());
+            if (method != null && !method.getId().equals("not$found")) {
+                if (method.getDeclaringType().equals(superType)) {
+                    return null;
+                }
+            }
+            if (superType.getTypeDec().getFullName().
+                equals("java.lang.Object")) {
+                return null;
+            }
+            superType = (NameType)superType.getTypeDec().getSuperClassType();
+        }
+        return null;
+    }
+
+    /**
+     * Returns the int modifiers for this method.
+     *
+     * @return the int modifiers for this method.
+     * @see    java.lang.reflect.Modifier
+     */
+    public int modifierSpecifier() {
+        //XXX interface methods have the ABSTRACT bit set
+        if (containingClass().isInterface()) {
+            return super.modifierSpecifier() & ~Modifier.ABSTRACT;
+        }
+        return super.modifierSpecifier();
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/OfClauseDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/OfClauseDocImpl.java
new file mode 100644 (file)
index 0000000..b788934
--- /dev/null
@@ -0,0 +1,95 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.ClassDoc;
+import org.aspectj.ajdoc.OfClauseDoc;
+import org.aspectj.ajdoc.OfEachObjectDoc;
+import org.aspectj.compiler.crosscuts.ast.Pcd;
+import org.aspectj.compiler.crosscuts.ast.PerCFlow;
+import org.aspectj.compiler.crosscuts.ast.PerClause;
+import org.aspectj.compiler.crosscuts.ast.PerObject;
+import org.aspectj.compiler.crosscuts.ast.PerSingleton;
+
+import java.util.Collections;
+import java.util.List;
+
+public class OfClauseDocImpl {
+
+    /** TODO */
+    public final static OfClauseDoc getInstance(PerClause clause) {
+        return factory.getInstance(clause);
+    }
+
+    /** The factory used to create the instance. */
+    private final static Factory factory = new Factory();
+
+    /** TODO */
+    private final static class OfEachObjectDocImpl implements OfEachObjectDoc {
+        private final List instances;
+        private OfEachObjectDocImpl(PerObject eo) {
+            instances = createInstances(eo);
+        }
+        public ClassDoc[] instances() {
+            return (ClassDoc[])instances.toArray(new ClassDoc[instances.size()]);
+        }
+        public OfEachObjectDoc.Kind kind() {
+            return OfClauseDoc.Kind.EACH_OBJECT;
+        }
+        private List createInstances(PerObject eo) {
+            Pcd pc = eo.getPcd();
+            if (pc == null) {
+                return Collections.EMPTY_LIST;
+            }
+            return Collections.EMPTY_LIST;
+        }
+    }
+
+    /** TODO */
+    private static class Factory {
+
+        private final static OfClauseDoc EACH_CFLOW = new OfClauseDoc(){
+                public OfClauseDoc.Kind kind() {
+                    return OfClauseDoc.Kind.EACH_CFLOW;
+                }
+            };
+
+        private final static OfClauseDoc EACH_JVM = new OfClauseDoc() {
+                public OfClauseDoc.Kind kind() {
+                    return OfClauseDoc.Kind.EACH_JVM;
+                }
+            };
+
+        public final OfClauseDoc getInstance(PerClause clause) {
+            if (clause instanceof PerCFlow) {
+                return EACH_CFLOW;
+            }
+            if (clause instanceof PerSingleton) {
+                return EACH_JVM;
+            }
+            if (clause instanceof PerObject) {
+                return new OfEachObjectDocImpl((PerObject)clause);
+            }
+            return null; //??? error
+        }
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/PackageDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/PackageDocImpl.java
new file mode 100644 (file)
index 0000000..3715e39
--- /dev/null
@@ -0,0 +1,336 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.PackageDoc;
+import org.aspectj.compiler.base.ast.Type;
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.crosscuts.AspectJCompiler;
+
+import com.sun.javadoc.ClassDoc;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents a package in the aspectj-world.
+ * A package is a passive container of classes given to it.
+ * It does not enforce visibility rules. However, you can
+ * purge packages without classes from the static list of packages.
+ * @author Jeff Palm
+ */
+public class PackageDocImpl
+    extends DocImpl
+    implements org.aspectj.ajdoc.PackageDoc {
+
+    public final static String UNNAMED_PACKAGE = ""; //unnamed-package";
+
+    private static AjdocCompiler ajdoc = Ajdoc.instance();
+    private static AspectJCompiler ajc = ajdoc;
+    public AspectJCompiler ajc() { return ajc; }
+    private Set allClasses = new HashSet();
+    private Comment comment;
+    private String name;
+
+    /**
+     * Only want to create these within the static access.
+     *
+     * @param name name of the new package.
+     */
+    private PackageDocImpl(String name) {
+        this.name = name;
+        findDocumentation();
+    }
+
+    /**
+     * Adds a class to this package.
+     *
+     * @param classDoc The new class.
+     */
+    public void addClass(ClassDoc classDoc) {
+        allClasses.add(classDoc);
+    }
+    
+    /**
+     * Attempts to find a class with name <code>className</code>
+     * in this package.
+     *
+     * @param className name of the class to find.
+     */
+    public ClassDoc findClass(String className) {
+        Type type = ajc.getTypeManager().
+            findType(name(), className);
+        if (type != null) {
+            return ClassDocImpl.getInstance(type.getTypeDec());
+        }
+        for (Iterator i = allClasses.iterator(); i.hasNext();) {
+            ClassDoc cd = (ClassDoc)i.next();
+            if (className.equals(cd.name())) {
+                return cd; //todo wes was null?
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns all the classes in this package.
+     *
+     * @return an array of ClassDoc representing all
+     *         the classes in this package.
+     */
+    public ClassDoc[] allClasses() {
+        return (ClassDoc[])allClasses.toArray(new ClassDoc[allClasses.size()]);
+    }
+
+    /**
+     * Returns all the aspects in this package.
+     *
+     * @return an array of AspectDoc representing all
+     *         the aspects in this package.
+     */
+    public AspectDoc[] aspects() {
+        List list = new ArrayList();
+        for (Iterator i = allClasses.iterator(); i.hasNext();) {
+            org.aspectj.ajdoc.ClassDoc doc = (org.aspectj.ajdoc.ClassDoc)i.next();
+            if (doc.isAspect()) list.add(doc);
+        }
+        return (AspectDoc[])list.toArray
+            (new AspectDoc[list.size()]);  
+    }
+
+    /**
+     * Returns all the ordinary classes in this package.
+     *
+     * @return an array of ClassDoc representing all
+     *         the ordinary classes in this package.
+     */
+    public ClassDoc[] ordinaryClasses() {
+        List list = new ArrayList();
+        for (Iterator i = allClasses.iterator(); i.hasNext();) {
+            ClassDoc doc = (ClassDoc)i.next();
+            if (doc.isOrdinaryClass()) list.add(doc);
+        }
+        return (ClassDoc[])list.toArray
+            (new ClassDoc[list.size()]);
+    }
+    
+    /**
+     * Returns all the exceptions in this package.
+     *
+     * @return an array of ClassDoc representing all
+     *         the exceptions in this package.
+     */
+    public ClassDoc[] exceptions() {
+        List list = new ArrayList();
+        for (Iterator i = allClasses.iterator(); i.hasNext();) {
+            ClassDoc doc = (ClassDoc)i.next();
+            if (doc.isException()) list.add(doc);
+        }
+        return (ClassDoc[])list.toArray
+            (new ClassDoc[list.size()]);
+    }
+
+    /**
+     * Returns all the errors in this package.
+     *
+     * @return an array of ClassDoc representing all
+     *         the errors in this package.
+     */    
+    public ClassDoc[] errors() {
+        List list = new ArrayList();
+        for (Iterator i = allClasses.iterator(); i.hasNext();) {
+            ClassDoc doc = (ClassDoc)i.next();
+            if (doc.isError()) list.add(doc);
+        }
+        return (ClassDoc[])list.toArray
+            (new ClassDoc[list.size()]);
+    }
+
+    /**
+     * Returns all the interfaces in this package.
+     *
+     * @return an array of ClassDoc representing all
+     *         the interfaces in this package.
+     */  
+    public ClassDoc[] interfaces() {
+        List list = new ArrayList();
+        for (Iterator i = allClasses.iterator(); i.hasNext();) {
+            ClassDoc doc = (ClassDoc)i.next();
+            if (doc.isInterface()) list.add(doc);
+        }
+        return (ClassDoc[])list.toArray
+            (new ClassDoc[list.size()]);
+    }
+
+    /**
+     * Returns the name if included -- null otherwise.
+     *
+     * @return the name if included -- null otherwise.
+     */
+    public String name() {
+        return isIncluded() ? name : null;
+    }
+
+    /**
+     * Compare based on <code>name()</code>.
+     *
+     * @param  other other Object.
+     * @return       <code>true</code> if the other Object is a
+     *               PackageDocImpl and has the same name.
+     */
+    public boolean equals(Object other) {
+        return other instanceof PackageDocImpl && other != null
+            ?  name().equals(((PackageDocImpl)other).name())
+            :  super.equals(other);
+    }
+
+    /**
+     * Returns the name.
+     *
+     * @return the name.
+     */
+    public String toString() {
+        return name();
+    }
+
+    private void findDocumentation() {
+        if (ajdoc == null) return;
+        String filename = (name.equals("")
+                           ? name
+                           : name.replace('.',File.separatorChar)
+                           + File.separatorChar) + "package.html";
+        File html = ajdoc.findFile(filename, false);
+        if (html == null) return;
+        String rawCommentText = Util.documentation(html, ajdoc.err());
+
+        //TODO: should be done in aspect from Aspects.java
+        //FormalComment comment = new FormalComment(rawCommentText);
+        setComment(new Comment(this, rawCommentText));
+    }
+
+
+    /* ------------------------------------------------------------
+     * Factory stuff
+     * ------------------------------------------------------------
+     */
+
+    private static Map namesToPackages = new HashMap();
+
+    /**
+     * Returns the collection of known packages.
+     *
+     * @return a Collection representing the known packages.
+     */
+    public static Collection packages() {
+        return namesToPackages.values();
+    }
+
+    /**
+     * Inits the world and AspectJCompiler with these
+     * packages.
+     *
+     * @param world current World.
+     * @param ajc   current compiler.
+     */
+    public static void init(AspectJCompiler ajc) {
+        PackageDocImpl.ajc = ajc;
+        if (ajc instanceof AjdocCompiler) {
+            PackageDocImpl.ajdoc = (AjdocCompiler)ajc;
+        }
+    }
+
+    /**
+     * Returns a package for a TypeDec.
+     *
+     * @param typeDec TypeDec whose package is desired.
+     * @return        a PackageDocImpl for a given TypeDec.
+     */
+    public static PackageDocImpl getPackageDoc(TypeDec typeDec) {
+        return getPackageDoc(typeDec.getPackageName());
+    }
+    
+    /**
+     * Returns a package for a name.
+     *
+     * @param packageName package name for which to look.
+     * @return            a PackageDocImpl for a given package name.
+     */
+    public static PackageDocImpl getPackageDoc(String packageName) {
+        return addPackageDoc(packageName);
+    }
+
+    /**
+     * Adds a package with name <code>name</code> if it
+     * already doesn't exist, and returns the new package
+     * (if own with the same name didn't exist) or the
+     * existing package.
+     *
+     * @param name name of the new package.
+     * @return     current package mapping to
+     *             <code>name</code>.
+     */
+    public static PackageDocImpl addPackageDoc(String name) {
+        if (name == null) name = UNNAMED_PACKAGE;
+        PackageDocImpl packageDoc = (PackageDocImpl)namesToPackages.get(name);
+        if (packageDoc == null) {
+            packageDoc = new PackageDocImpl(name);
+            addPackageDoc(packageDoc);
+        }
+        return packageDoc;
+    }
+
+    /**
+     * Adds the PackageDoc if one doesn't already exist
+     * with the same name, and returns the existing or created
+     * package with the same name as the one passed in .
+     *
+     * @param packageDoc PackageDoc we want to add.
+     * @return           package in the world with the same
+     *                   name as <code>packageDoc</code>.
+     */
+    public static PackageDocImpl addPackageDoc(PackageDoc packageDoc) {
+        if (packageDoc == null) return null;
+        return (PackageDocImpl)namesToPackages.put(packageDoc.name(),
+                                                   packageDoc);
+    }
+
+    /** 
+     * Sets the include flag to false for empty packages
+     * todo: remove instead?
+     */
+    public static void excludeEmptyPackages() {
+        for (Iterator i = packages().iterator(); i.hasNext();) {
+            PackageDocImpl pkg = (PackageDocImpl)i.next();
+            if (pkg.allClasses().length < 1) {
+                pkg.setIncluded(false);
+            }
+        }
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ParamTagImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ParamTagImpl.java
new file mode 100644 (file)
index 0000000..2f4b1cf
--- /dev/null
@@ -0,0 +1,86 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import com.sun.javadoc.Doc;
+import com.sun.javadoc.ParamTag;
+
+import java.util.Locale;
+
+/**
+ * The implementation of a param tag.
+ *
+ * @author Jeff Palm
+ */
+public class ParamTagImpl extends TagImpl implements ParamTag {
+
+    private String parameterComment;
+    private String parameterName;
+
+    /**
+     * Constructs the new tag with given parameters.
+     *
+     * @param doc    the new value for <code>doc</code>.
+     * @param name   the new value for <code>name</code>.
+     * @param text   the new value for <code>text</code>.    
+     * @param locale the new value for <code>locale</code>.
+     * @param err    the new value for <code>err</code>.
+     */
+    public ParamTagImpl(Doc doc,
+                        String name,
+                        String text,
+                        Locale loc,
+                        ErrPrinter err) {
+        super(doc, name, null, loc, err);
+        String[] split = split(text);
+        parameterName = split[0];
+        parameterComment = split[1];
+        setText(parameterComment);
+    }
+
+    /**
+     * Returns the parameter comment.
+     *
+     * @return the parameter comment.
+     */
+    public String parameterComment() {
+        return parameterComment;
+    }
+
+    /**
+     * Returns the name of the parameter.
+     *
+     * @return the name of the parameter.
+     */
+    public String parameterName() {
+        return parameterName;
+    }
+
+    /**
+     * Returns <code>param</code>.
+     *
+     * @return <code>param</code>.
+     */
+    public String kind() {
+        return "@param";
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ParameterImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ParameterImpl.java
new file mode 100644 (file)
index 0000000..04bc966
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ast.FormalDec;
+
+import com.sun.javadoc.Type;
+
+public class ParameterImpl implements org.aspectj.ajdoc.Parameter {
+
+    private final FormalDec formalDec;
+
+    public ParameterImpl(FormalDec formalDec) {
+        this.formalDec = formalDec;
+    }
+
+    /**
+     * Returns the name of this formal.
+     *
+     * @return the name of this formal.
+     */
+    public String name() {
+        return formalDec.getId();
+    }
+    
+    /**
+     * Returns the type of this formal.
+     *
+     * @return the type of this formal.
+     */
+    public Type type() {
+        return TypeImpl.getInstance(formalDec.getType());
+    }
+
+    /**
+     * Returns the type name of this formal including
+     * any dimension information.
+     *
+     * @return the type name of this formal including
+     *         any dimension information.
+     */
+    public String typeName() {
+        return type().qualifiedTypeName() + type().dimension();
+    }
+
+    public boolean equals(Object o) {
+        if (!(o instanceof ParameterImpl)) return false;
+        ParameterImpl p = (ParameterImpl)o;
+        return typeName().equals(p.typeName());
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/PointcutDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/PointcutDocImpl.java
new file mode 100644 (file)
index 0000000..bd35c92
--- /dev/null
@@ -0,0 +1,143 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.ClassDoc;
+import org.aspectj.ajdoc.PointcutDoc;
+import org.aspectj.compiler.base.ast.Dec;
+import org.aspectj.compiler.base.ast.Formals;
+import org.aspectj.compiler.base.ast.NameType;
+import org.aspectj.compiler.base.ast.TypeD;
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.base.ast.TypeDs;
+import org.aspectj.compiler.crosscuts.ast.PointcutDec;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public class PointcutDocImpl
+    extends ExecutableMemberDocImpl
+    implements PointcutDoc {
+
+    /** The pointcut to which we delegate. */
+    private final PointcutDec pointcutDec;
+
+    public PointcutDocImpl(ClassDoc containingClass, PointcutDec pointcutDec) {
+        super(containingClass);
+        this.pointcutDec = pointcutDec;
+    }
+
+    /**
+     * Returns a empty list because advice cannot
+     * be placed on a pointcut.
+     *
+     * @return Collection.EMPTY_LIST;
+     */
+    protected Collection createAdvice() {
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Returns the underlying Dec -- a PointcutDec.
+     *
+     * @return the underlying Dec -- a PointcutDec.
+     */
+    protected Dec dec() {
+        return pointcutDec;
+    }
+
+    /**
+     * Returns the Formals of the underlying PointcutDec.
+     *
+     * @return the Formals of the underlying PointcutDec.
+     */
+    protected Formals getFormals() {
+        return pointcutDec.getFormals();
+    }
+
+    /**
+     * Returns null because pointcut cannot throw execptions.
+     *
+     * @return null.
+     */
+    public TypeDs getThrows() {
+        return null;
+    }
+
+    /**
+     * Returns the return type of this method.
+     *
+     * @return the Type representing the type this
+     *         method returns.
+     */
+    public com.sun.javadoc.Type resultType() {
+        TypeD typed = pointcutDec.getResultTypeD();
+        if (typed == null) return null; //TODO: maybe return VOID
+        return null; //TODOtyped.getType();
+    }
+
+    /**
+     * Returns the type that nearest super class that defines
+     * this method.
+     *
+     * @return the type that nearest super class that defines
+     *         this method.
+     */
+    public com.sun.javadoc.ClassDoc overriddenClass() {
+        //TODO: This sucks!!!
+        TypeDec where = pointcutDec.getDeclaringType().getTypeDec();
+        NameType superType = (NameType)where.getSuperClassType();
+        while (superType != null) {
+            PointcutDec pc = Util.pointcutDec(superType,
+                                              pointcutDec.getId(),
+                                              pointcutDec.getFormals());
+            if (pc != null && !pc.getId().equals("NOT_FOUND")) {
+                // XXX TypeDec result = superType.getTypeDec();
+                return null; //TODOresult;
+            }
+            if (superType.getTypeDec().getFullName().
+                equals("java.lang.Object")) {
+                return null;
+            }
+            superType = (NameType)superType.getTypeDec().getSuperClassType();
+        }
+        return null;
+    }
+    
+    /**
+     * Returns <code>true</code>.
+     *
+     * @return <code>true</code>.
+     */
+    public boolean isPointcut() {
+        return true;
+    }
+    
+    /**
+     * Returns <code>true</code> if this method is <code>abstract</code>.
+     *
+     * @return <code>true</code> if this method is <code>abstract</code>.
+     */
+    public boolean isAbstract() {
+        return pointcutDec.isAbstract();
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ProgramElementDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ProgramElementDocImpl.java
new file mode 100644 (file)
index 0000000..007a56a
--- /dev/null
@@ -0,0 +1,203 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ast.Dec;
+import org.aspectj.compiler.base.ast.Modifiers;
+import org.aspectj.compiler.base.ast.NameType;
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.crosscuts.AspectJCompiler;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.PackageDoc;
+
+import java.lang.reflect.Modifier;
+
+public abstract class ProgramElementDocImpl
+    extends    DocImpl
+    implements org.aspectj.ajdoc.ProgramElementDoc {
+
+    /** The containing ClassDoc. */
+    private final ClassDoc containingClass;
+    
+    /*
+     construction of ProgramElementDocImpl must not recursively 
+     invoke construction of instances of subclass ClassDocImpl 
+     or endless recursion will be possible
+    */
+    public ProgramElementDocImpl(ClassDoc containingClass) {
+        this.containingClass = containingClass;
+    }
+    
+    /**
+     * Returns the underlying Dec used for a number of methods.
+     *
+     * @return the underlying Dec used for a number of methods.
+     */
+    protected abstract Dec dec();
+
+    /**
+     * Returns the AspectJCompiler that this tree.  Delegates
+     * to the underlying {@link #dec()}.
+     *
+     * @return the AspectJCompiler that compiled this tree.
+     */
+    protected final AspectJCompiler ajc() {
+        return (AspectJCompiler)dec().getCompiler();
+    }
+
+    /**
+     * Returns this's Comment.
+     *
+     * @return the Comment for this Doc.
+     */
+    public Comment getComment() {
+        if (super.getComment() == null) {
+            setComment(new Comment(this, dec().getFormalComment(), err()));
+        }
+        return super.getComment();
+    }
+   
+    /**
+     * Returns the nearest enclosing class.  The returned value
+     * is <code>null</code> if this is a top-level entity.
+     *
+     * @return a ClassDoc representing the nearest
+     *         enclosing class.  This can be null for
+     *         top-level entities.
+     */
+    public ClassDoc containingClass() {
+        return containingClass;
+    }
+
+    /**
+     * Returns the package in which this Dec was declared.
+     *
+     * @return a PackageDoc representing the package
+     *         in which this Dec was declared.
+     */
+    public PackageDoc containingPackage() {
+        return PackageDocImpl.getPackageDoc(nonNullTypeDec());
+    }
+
+    /**
+     */
+    public TypeDec nonNullTypeDec() {
+        if (dec().getDeclaringType() == null) return null;
+        return ((NameType)dec().getDeclaringType()).getTypeDec();
+    }
+
+    /**
+     * An int form of this Dec's modifiers.
+     *
+     * @return an int form this Dec's modifiers.
+     * @see    java.lang.reflect.Modifier
+     */
+    public int modifierSpecifier() {
+        return dec().getModifiers().getValue();
+    }
+    
+    /**
+     * Returns the modifiers as a String.
+     *
+     * @return a String representing to modifiers.
+     */
+    public String modifiers() {
+        return Modifier.toString(modifierSpecifier());
+    }
+
+    /**
+     * Returns <code>true</code> if this is <code>public</code>.
+     *
+     * @return <code>true</code> if this is <code>public</code>.
+     */
+    public boolean isPublic() {
+        return dec().isPublic();
+    }
+
+    /**
+     * Returns <code>true</code> if this is <code>protected</code>.
+     *
+     * @return <code>true</code> if this is <code>protected</code>.
+     */
+    public boolean isProtected() {
+        return dec().isProtected();
+    }
+
+    /**
+     * Returns <code>true</code> if this is <i>package private</i>.
+     *
+     * @return <code>true</code> if this is <i>package private</i>.
+     */
+    public boolean isPackagePrivate() {
+        Modifiers mods = dec().getModifiers();
+        // todo: consider creating Dec.isPackagePrivate()
+        // todo: consider NPE if mods null
+        return ((null != mods) && mods.isPackagePrivate());
+    }
+
+    /**
+     * Returns <code>true</code> if this is <code>private</code>.
+     *
+     * @return <code>true</code> if this is <code>private</code>.
+     */
+    public boolean isPrivate() {
+        return dec().isPrivate();
+    }
+
+    /**
+     * Returns <code>true</code> if this is <code>static</code>.
+     *
+     * @return <code>true</code> if this is <code>static</code>.
+     */
+    public boolean isStatic() {
+        return dec().isStatic();
+    }
+
+    /**
+     * Returns <code>true</code> if this is <code>final</code>.
+     *
+     * @return <code>true</code> if this is <code>final</code>.
+     */
+    public boolean isFinal() {
+        return dec().isFinal();
+    }
+
+    /**
+     * Returns the fully-qualified type name of this Dec (not member name).
+     *
+     * @return the fully-qualified name.
+     */
+    public String qualifiedName() {
+        return name();
+    }
+    
+    /**
+     * Returns the name -- e.g. ID.
+     *
+     * @return the name of the Dec.
+     */
+    public String name() {
+        return dec().getId();
+    }  
+    
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Quietable.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Quietable.java
new file mode 100644 (file)
index 0000000..055bb29
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+/**
+ * Utility interface to allow us to shut up
+ * the writers from redeclaring the generatio
+ * of files.
+ *
+ * @author Jeff Palm
+ */
+public interface Quietable {
+
+    /**
+     * Tell someone to be quiet.
+     */
+    public void quiet();
+
+    /**
+     * Allow someone to speak again.
+     */
+    public void speak();
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/RootDocImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/RootDocImpl.java
new file mode 100644 (file)
index 0000000..f0befd6
--- /dev/null
@@ -0,0 +1,404 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.base.ast.World;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.PackageDoc;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This is responsible for constituting the world
+ * of specified[classes|packages] and all classes.
+ * It ensures that any classes compiled are included (if appropriate)
+ * but does not ensure that linked classes are.
+ */
+public class RootDocImpl
+    extends DocImpl
+    implements org.aspectj.ajdoc.RootDoc,
+               Quietable {
+
+    /** The collection of packages specified to be documented. */
+    private final Set specifiedPackages;
+
+    /** The collection of types specified to be documented. */
+    private final Set specifiedClasses;
+
+    /** The collection of packages visible in this world. */
+    private final Set packages = new HashSet();
+
+    /** The collection of classes visible in this world. */
+    private final Set classes = new HashSet();
+
+    /** The documentation options. */
+    private final String[][] options;
+
+    /** The World delegate. */
+    private final World world;
+
+    /** Determines whether items are included */
+    private final AccessChecker filter;
+
+    public RootDocImpl(World world, String[][] options,
+                       Collection pkgnames, Collection classnames,
+                       AccessChecker filter) {
+        this.world = world;
+        this.options = options;
+        this.filter = (null != filter ? filter : AccessChecker.PUBLIC);
+        Set set = createSpecifiedPackages(pkgnames);
+        specifiedPackages = set; // modifiable to prune empty packages
+        set = createSpecifiedClasses(classnames);
+        specifiedClasses = Collections.unmodifiableSet(set);
+        // adds all world classes and packages for classes and packages
+        // addWorldTypes();  // todo re-enable as needed
+        // make sure specified are added - should duplicate world
+        // but should come after since packages are removed if empty
+        addSpecifiedPackages();
+        addSpecifiedClasses();
+        setupDominatesRelations();
+        ensureWorldInclusion();
+    }
+    /* ------------------------------------------------------------
+     * Implementation of RootDoc
+     * ------------------------------------------------------------
+     */
+
+    /**
+     * Returns the classes visible in this world.
+     *
+     * @return an array of ClassDoc representing the visible
+     *         classes in this world.
+     */
+    public ClassDoc[] classes() {
+        return (ClassDoc[])classes.toArray
+            (new org.aspectj.ajdoc.ClassDoc[classes.size()]);
+    }
+    
+    /**
+     * Returns a type visible in this world
+     * for the name <code>className</code>.  If there is
+     * no visible package, this method will return
+     * <code>null</code>.
+     *
+     * @return an instance of ClassDoc in this world
+     *         that corresponds to <code>className</code>.
+     *         <code>null</code> is returned if there exists
+     *         no such visible type named <code>className</code>.
+     */
+    public ClassDoc classNamed(String className) {
+        ClassDoc[] docs = classes();
+        for (int i = 0; i < docs.length; i++) {
+            ClassDoc doc = docs[i];
+            if (doc.name().equals(className)) {
+                return doc;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns a package visible in this world
+     * for the name <code>packageName</code>.  If there is
+     * no visible package, this method will return
+     * <code>null</code>.
+     *
+     * @return an instance of PackageDoc in this world
+     *         that corresponds to <code>packageName</code>.
+     *         <code>null</code> is returned if there exists
+     *         no such visible package named <code>packageName</code>.
+     */
+    public PackageDoc packageNamed(String packageName) {
+        for (Iterator i = packages.iterator(); i.hasNext();) {
+            PackageDoc doc = (PackageDoc)i.next();
+            if (doc.name().equals(packageName)) {
+                return doc;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the underlying world.
+     *
+     * @return an instance of World representing all
+     *         the CompilationUnits.
+     */
+    public World world() {
+        return world;
+    }
+
+    /**
+     * Returns the documentation options.
+     *
+     * @return the documentation options.
+     */
+    public String[][] options() {
+        return options;
+    }
+
+    /**
+     * Returns the types specified to be documented.
+     *
+     * @return an array of ClassDoc representing the
+     *         specified types.
+     */
+    public ClassDoc[] specifiedClasses() {
+        return (ClassDoc[])specifiedClasses.toArray
+            (new org.aspectj.ajdoc.ClassDoc[specifiedClasses.size()]);
+    }
+
+    /**
+     * Returns the packages specified to be documented.
+     *
+     * @return an array of PackageDoc representing the
+     *         specified packages.
+     */
+    public PackageDoc[] specifiedPackages() {
+        return (PackageDoc[])specifiedPackages.toArray
+            (new org.aspectj.ajdoc.PackageDoc[specifiedPackages.size()]);
+    }
+
+
+    /* ------------------------------------------------------------
+     * Implementation of Quietable
+     * ------------------------------------------------------------
+     */
+
+    /** <code>true</code> when notices should be printed. */
+    private boolean notice = true;
+
+    /** Supresses output notices. */
+    public void quiet() { notice = false; }
+
+    /** Allows output notices. */
+    public void speak() { notice = true; }
+
+
+    /* ------------------------------------------------------------
+     * Implementation of DocErrReporter
+     * ------------------------------------------------------------
+     */
+
+    /**
+     * Prints the error message <code>msg</code> using
+     * the current error handler.
+     *
+     * @param msg the error message.
+     */
+    public void printError(String msg) {
+        err().printError(msg);
+    }
+
+    /**
+     * Prints the notice message <code>msg</code> using
+     * the current error handler.
+     *
+     * @param msg the notice message.
+     */
+    public void printNotice(String msg) {
+        if (notice) err().printNotice(msg);
+    }
+
+    /**
+     * Prints the warning message <code>msg</code> using
+     * the current error handler.
+     *
+     * @param msg the warning message.
+     */
+    public void printWarning(String msg) {
+        err().printWarning(msg);
+    }
+
+
+    /* ------------------------------------------------------------
+     * Implementation of Doc
+     * ------------------------------------------------------------
+     */
+
+    /**
+     * Returns <code>null</code>.
+     *
+     * @return <code>null</code>.
+     */
+    public String name() {
+        return "who knows???";
+    }
+
+
+    /* ------------------------------------------------------------
+     * Helper methods
+     * ------------------------------------------------------------
+     */
+    
+    /**
+     * Creates only PackageDocs that were included on the command
+     * line, even if they are empty.  Should be used only for 
+     * specifiedPackages.
+     */
+    private HashSet createSpecifiedPackages(Collection pkgnames) {
+        HashSet result = new HashSet();
+        for (Iterator i = pkgnames.iterator(); i.hasNext();) {
+            String pkgname = (String)i.next();
+            PackageDocImpl pkgdoc = PackageDocImpl.getPackageDoc(pkgname);
+            pkgdoc.setIncluded(true);
+            result.add(pkgdoc);
+        }
+        return result;
+    }
+    private void addWorldTypes() {
+        for (Iterator i = world.getTypes().iterator(); i.hasNext();) {
+            TypeDec td = (TypeDec)i.next();
+            ClassDocImpl cd = ClassDocImpl.getInstance(td);
+            addClass(cd);
+            cd.setIncluded(filter.canAccess(td));
+        }
+    }
+
+    /**
+     * Creates only ClassDocs that were included on the command
+     * line, and then only if they pass the filter.  
+     * Should be used only for specifiedClasses.
+     * todo: createClasses uses to use all classes if no names 
+     */
+    private HashSet createSpecifiedClasses(Collection classnames) {
+        HashSet result = new HashSet();
+        if (classnames != null) {
+            for (Iterator i = classnames.iterator(); i.hasNext();) {
+                String classname = (String)i.next();
+                for (Iterator j = world.getTypes().iterator(); j.hasNext();) {
+                    TypeDec td = (TypeDec)j.next();
+                    if (filter.canAccess(td)) {
+                        ClassDoc cd = ClassDocImpl.getInstance(td);
+                        if (cd.qualifiedName().equals(classname)) {
+                            result.add(cd);
+                            // add inner classes since not specified explicitly
+                            ClassDoc[] inners = cd.innerClasses(); // no cycles, right?
+                            if (null != inners) {
+                                for (int l = 0; l < inners.length; l++) {
+                                    result.add(inners[l]); 
+                                }
+                            }
+                            break;
+                        }
+                    }
+                }
+                // todo: warn if class specified but not in world? 
+            }
+        }
+        return result;
+    }
+
+    private void addSpecifiedClasses() {
+        for (Iterator i = new ArrayList(specifiedClasses).iterator(); i.hasNext();) {
+            ClassDoc cd = (ClassDoc)i.next();
+            addClass(cd);
+        }
+    }
+
+    private void addSpecifiedPackages() {
+        for (Iterator i = new ArrayList(specifiedPackages).iterator(); i.hasNext();) {
+            PackageDoc pd = (PackageDoc)i.next();
+            ClassDoc[] allClasses = pd.allClasses();
+            if (allClasses.length == 0) {
+                specifiedPackages.remove(pd);
+            } else {
+                for (int j = 0; j < allClasses.length; j++) {
+                    addClass(allClasses[j]);
+                }
+            }
+        }
+    }
+
+    /** 
+     * If filter accepts this ClassDoc,
+     * Add it and and inner classes to classes
+     * and add package to packages.
+     */
+    private void addClass(ClassDoc cd) {
+        if (null == cd) return;
+        ClassDocImpl impl = (ClassDocImpl) cd;
+        if (filter.canAccess(impl.typeDec()) 
+            && (!classes.contains(impl))) {
+            impl.setIncluded(true);
+            classes.add(impl);
+            packages.add(impl.containingPackage());
+            ClassDoc[] inners = impl.innerClasses();
+            for (int i = 0; i < inners.length; i++) {
+                addClass(inners[i]);
+            }
+        } // todo: flag classes not added?
+    }
+
+    /** Read all classes to find any dominates relations */
+    private void setupDominatesRelations() {
+        // Find just the aspects
+        List aspects = new ArrayList();
+        ClassDoc[] classes = classes();
+        for (int i = 0; i < classes.length; i++) {
+            ClassDocImpl cd = (ClassDocImpl)classes[i];
+            if (cd.isAspect()) {
+                aspects.add(cd);
+            }
+        }
+
+        // Iterate over the aspects, if
+        for (Iterator i = aspects.iterator(); i.hasNext();) {
+            AspectDocImpl aspect1 = (AspectDocImpl)i.next();
+            for (Iterator j = aspects.iterator(); j.hasNext();) {
+                AspectDocImpl aspect2 = (AspectDocImpl)j.next();
+                if (aspect1.dominates(aspect2)) {
+                    aspect1.addDominatee(aspect2);
+                    aspect2.addDominator(aspect1);
+                }
+            }
+        }
+    }
+
+    /**
+     * Ensure compiled classes are included if they pass the filter
+     * and excluded otherwise.
+     * todo: The set of types available includes the world plus reachable
+     * types from there; I would like to exclude the reachable ones,
+     * but do not know how.
+     */
+    private void ensureWorldInclusion() {
+        for (Iterator i = world.getTypes().iterator(); i.hasNext();) {
+            TypeDec td = (TypeDec)i.next();
+            ClassDocImpl cd = ClassDocImpl.getInstance(td);
+            boolean isIncluded = cd.isIncluded();
+            // todo: update to consider enclosing class privileges
+            boolean shouldInclude = filter.canAccess(td);
+            if (shouldInclude != isIncluded) {
+                cd.setIncluded(shouldInclude);
+            }
+        }
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/RootDocMaker.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/RootDocMaker.java
new file mode 100644 (file)
index 0000000..efe1f32
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import com.sun.javadoc.DocErrorReporter;
+import com.sun.javadoc.RootDoc;
+
+import java.util.List;
+
+/**
+ * Interface specifying types that
+ * can produce RootDocs.
+ *
+ * @author Jeff Palm
+ */
+public interface RootDocMaker {
+
+    /**
+     * Returns a RootDoc using the passed in parameters.
+     * Throw a CannotMakeRootDocException is something
+     * goes awry.
+     *
+     * @param sourcepath           sourcepath to use.
+     * @param classpath            classpath to use.
+     * @param bootclasspath        bootclasspath to use.
+     * @param extdirs              extdirs to use.
+     * @param flags                flags to use.
+     * @param encoding             encoding to use.
+     * @param locale               locale to use.
+     * @param source               source to use.
+     * @param filenamesAndPackages filenamesAndPackages to use.
+     * @param options              options to use.
+     * @param err                  ErrPrinter to use.
+     * @param programName          program name to use.
+     * @param filter               filter to use.
+     * @return                     a RootDoc.
+     */
+    public RootDoc makeRootDoc(String sourcepath,
+                               String classpath,
+                               String bootclasspath,
+                               String extdirs,
+                               long flags,
+                               String encoding,
+                               String locale,
+                               String source,
+                               List filenamesAndPackages,
+                               List options,
+                               DocErrorReporter err,
+                               String programName,
+                               AccessChecker filter)
+    throws CannotMakeRootDocException;
+                               
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/SeeTagImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/SeeTagImpl.java
new file mode 100644 (file)
index 0000000..f7324b8
--- /dev/null
@@ -0,0 +1,874 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.ajdoc.AdviceDoc;
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.PointcutDoc;
+import org.aspectj.compiler.base.JavaCompiler;
+import org.aspectj.compiler.base.ast.ASTObject;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ConstructorDoc;
+import com.sun.javadoc.Doc;
+import com.sun.javadoc.FieldDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.javadoc.MethodDoc;
+import com.sun.javadoc.PackageDoc;
+import com.sun.javadoc.Parameter;
+import com.sun.javadoc.SeeTag;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+/**
+ * Implementation of see tags in the aspectj-world.
+ * See source for bug comments
+ * @author Jeff Palm
+ */
+public class SeeTagImpl extends TagImpl implements SeeTag {
+ /*
+ * This implementation handles
+ *<pre>{@link  package.class#member  label}
+ * @see  package.class#member  label
+ * @see "some reference"
+ * @see <any tag - should be url></pre>.
+ * It has errors since the tag-separating code which provides
+ * input is wrong, and it's very weak in how it handles
+ * text and URLs.  Most of the action is in resolve().
+ */
+
+    /** The package name specified by the user -- may be null. */
+    private String packageName;
+
+    /** The class name specified by the user -- may be null. */
+    private String className;
+
+    /** The member name specified by the user -- may be null. */
+    private String memberName;
+
+    /** The referenced package. */
+    private PackageDoc packageDoc;
+
+    /** The referenced class. */
+    private ClassDoc classDoc;
+
+    /** The referenced member. */
+    private MemberDoc memberDoc;
+
+    /** The label associated with the tag. */
+    private String label = "";
+
+    /** A shared instance of the compiler -- a little hacky. */
+    private static JavaCompiler ajc = AjdocCompiler.instance();
+
+    /**
+     * Constructs the new tag with given parameters and
+     * calls resolve to parse the class, package, and members.
+     *
+     * @param doc    the new value for <code>doc</code>.
+     * @param name   the new value for <code>name</code>.
+     * @param text   the new value for <code>text</code>.    
+     * @param locale the new value for <code>locale</code>.
+     * @param err    the new value for <code>err</code>.
+     */
+    public SeeTagImpl(Doc doc,
+                      String name,
+                      String text,
+                      Locale loc,
+                      ErrPrinter err) {
+        super(doc, name, text, loc, err);
+        resolve();
+    }
+    
+    /**
+     * Returns the label.
+     *
+     * @return the label.
+     */
+    public String label() {
+        return label;
+    }
+
+    /**
+     * Returns the referenced package's name.
+     * This <b>can</b> be <code>null</code>.
+     *
+     * @return the referenced package's name.
+     */
+    public String referencedPackageName() {
+        return packageName;
+    }
+
+    /**
+     * Returns the referenced package.
+     * This <b>can</b> be <code>null</code>.
+     *
+     * @return a PackageDoc with name packageName.
+     */
+    public PackageDoc referencedPackage() {
+        look();
+        return packageDoc;
+    }
+
+    /**
+     * Returns the referenced class's name.
+     * This <b>can</b> be <code>null</code>.
+     *
+     * @return the referenced class's name.
+     */
+    public String referencedClassName() {
+        return className;
+    }
+
+    /**
+     * Returns the referenced class.
+     * This <b>can</b> be <code>null</code>.
+     *
+     * @return a ClassDoc with name className.
+     */
+    public ClassDoc referencedClass() {
+        look();
+        return classDoc;
+    }
+
+    /**
+     * Returns the referenced members's name.
+     * This <b>can</b> be <code>null</code>.
+     * This can be null.
+     *
+     * @return the referenced class's name.
+     */
+    public String referencedMemberName() {
+        return memberName;
+    }
+
+    /**
+     * Returns the referenced member.
+     * This <b>can</b> be <code>null</code>.
+     *
+     * @return a ClassDoc with name memberName.
+     */    
+    public MemberDoc referencedMember() {
+        look();
+        return memberDoc;
+    }
+
+    /**
+     * Returns <code>see</code>.
+     *
+     * @return <code>see</code>.
+     */
+    public String kind() {
+        return "@see";
+    }
+
+    protected JavaCompiler ajc() {
+        if (ajc != null) {
+            return ajc;
+        } else if (doc() instanceof ASTObject) {
+            return ajc = ((ASTObject)doc()).getCompiler();
+        } else if (doc() instanceof PackageDocImpl) {
+            return ajc = ((PackageDocImpl)doc()).ajc();
+        }
+        return null;
+    }
+
+       void debugState(String m, PrintStream err) {
+        if (System.getProperty("seetag.debug") != null) {
+            if (null == err) err = System.err;
+            err.println("\t______________________ " + m
+                                               + "\n\tpackageName: "+packageName
+                                               + "\n\t packageDoc: " +packageDoc
+                                               + "\n\t  className: " +className
+                                               + "\n\t   classDoc: " +classDoc
+                                               + "\n\t memberName: " +memberName
+                                               + "\n\t  memberDoc: " +memberDoc
+                                               + "\n\t      label: " +label
+                                               );
+        }
+       }
+    private boolean looked = false;
+    private void look() {
+        if (!looked) {
+            looked = true;
+            dolook();
+        }
+               debugState("SeeTagImpl.look()", null);
+    }
+
+    private void dolook() {
+
+        // For null or empty classnames set the current doc
+        // to the referenced class
+        if (className == null || className.length() < 1) {
+            classDoc = classDoc(doc());
+        } else {
+            
+            // Use the class in which this doc is contained
+            // as a starting point...
+            ClassDoc container = classDoc(doc());
+
+            // ..and try to find the class from there
+            if (container == null) {
+                //TODO: Find class somewhere else
+            } else {
+                String fullName;
+                if (packageName == null || packageName.length() < 1) {
+                    fullName = className;
+                } else {
+                    fullName = packageName + '.' + className;
+                }
+
+                // As per the language spec...
+                // http://java.sun.com/docs/books/jls/second_edition/ (con't)
+                // html/names.doc.html#32725
+                // We must first consider types before identifiers,
+                // therefore, if there is no right parent in the member name
+                // we have to consider this first an inner class, and if
+                // one is found set the member name to nul
+                if (memberName != null &&
+                    memberName.indexOf('(') == -1) {
+                    classDoc = container.findClass(fullName + '.' + memberName);
+
+                    // If we found an inner class, don't look for a member
+                    if (classDoc != null) {
+                        memberName = null;
+                    }
+                }
+
+                // Now if we didn't find an inner class, just look
+                // up the full name
+                if (classDoc == null) {
+                    classDoc = container.findClass(fullName);
+                }
+            }
+        }
+
+        // If we found a class, then the package is that
+        // class's contained package
+        if (classDoc != null) {
+            packageDoc = classDoc.containingPackage();
+        } else if (packageName == null) {
+            
+            // If we didn't find a class, but the class name
+            // contains no periods, maybe the class name's really
+            // a package name
+            if (classDoc == null && className != null &&
+                className.indexOf('.') == -1) {
+                packageDoc = PackageDocImpl.getPackageDoc(className);
+            }
+            
+            // Otherwise, if the referenced class isn't null, set the
+            // referenced package to that class's contained package
+            else if (classDoc != null) {
+                packageDoc = classDoc.containingPackage();
+            }
+            
+            // Lastly, if the current doc is a package (i.e. package.html)
+            // then set the referenced package to the current doc
+            else if (doc() instanceof PackageDoc) {
+                packageDoc = (PackageDoc)doc();
+            }
+        } else {
+            
+            // Look for the fully qualified name of the
+            // package elsewhere
+            packageDoc = PackageDocImpl.getPackageDoc(packageName != null
+                                                      ? packageName
+                                                      : "");
+        }
+
+        // Look for the member if the member name wasn't null
+        if (memberName != null) {
+            lookForMember(memberName, (org.aspectj.ajdoc.ClassDoc)classDoc);
+        }
+    }
+
+    private void lookForMember(String spec,
+                               org.aspectj.ajdoc.ClassDoc container) {
+        int ilparen = spec.indexOf('(');
+        String name;
+        
+        // No parens mean a field or a method
+        // The order is for looking is:
+        //  [1] field
+        //  [2] method
+        //  [3] pointcut
+        if (ilparen == -1) {
+            name = spec;
+            if ((memberDoc = fieldDoc(name, container)) != null) {
+                return;
+            }
+            if ((memberDoc = methodDoc(name, container, null)) != null) {
+                return;
+            }
+            if ((memberDoc = pointcutDoc(name, container, null)) != null) {
+                return;
+            }
+        } else {
+            name = spec.substring(0, ilparen);
+        }
+        int irparen = spec.lastIndexOf(')');
+
+        // Crop out the parameters
+        String paramsString;
+        if (irparen != -1) {
+            paramsString = spec.substring(ilparen+1, irparen);
+        } else {
+            paramsString = spec.substring(ilparen+1, spec.length()-1);
+        }
+
+        // Convert the raw parameters to an array
+        String[] paramNames = paramNames(paramsString);
+
+        // Try to match the name and parameters if the following order:
+        //  [1] method
+        //  [2] constructor
+        //  [3] pointcut
+        //  [4] advice
+        if ((memberDoc = methodDoc(name, container, paramNames)) != null) {
+            return;
+        }
+        if ((memberDoc = constructorDoc(container, paramNames)) != null) {
+            return;
+        }
+        if ((memberDoc = pointcutDoc(name, container, paramNames)) != null) {
+            return;
+        }
+        if (container instanceof AspectDoc) {
+            if ((memberDoc = adviceDoc(name,
+                                       (AspectDoc)container,
+                                       paramNames)) != null) {
+                return;
+            }
+        }
+    }
+
+    private String[] paramNames(String restNoParens) {
+        if (restNoParens == null || restNoParens.length() == 0) {
+            return new String[0];
+        }
+        List params = new ArrayList();
+        for (StringTokenizer t = new StringTokenizer(restNoParens, ",", false);
+             t.hasMoreTokens();) {
+            String spec = t.nextToken().trim();
+            int ispace = spec.indexOf(' ');
+            if (ispace != -1) {
+                spec = spec.substring(0, ispace);
+            }
+            params.add(spec);
+        }
+        return (String[])params.toArray(new String[params.size()]);
+    }
+
+    private FieldDoc fieldDoc(String name, ClassDoc container) {
+        for (ClassDoc cd = container; cd != null; cd = cd.superclass()) {
+            FieldDoc[] docs = cd.fields();
+            for (int i = 0, N = docs.length; i < N; i++) {
+                if (docs[i].name().equals(name)) {
+                    return docs[i];
+                }
+            }
+        }
+        return null;
+    }
+
+    private PointcutDoc pointcutDoc(String name,
+                                    org.aspectj.ajdoc.ClassDoc container,
+                                    String[] paramNames) {
+        if (null == name) return null; // XXX warn or error                                           
+        
+        for (org.aspectj.ajdoc.ClassDoc cd = container;
+             cd != null;
+             cd = (org.aspectj.ajdoc.ClassDoc)cd.superclass()) {
+            PointcutDoc[] docs = cd.pointcuts();
+            if (null == docs) {
+                continue;
+            }
+            for (int i = 0, N = docs.length; i < N; i++) {
+                PointcutDoc md = docs[i];
+                if ((null != md) 
+                    && (name.equals(md.name()))
+                    && ((null == paramNames)
+                        || parametersMatch(md.parameters(), paramNames, container))) {
+                    return md;
+                }
+            }
+        }
+        return null;
+    }
+
+    private MethodDoc methodDoc(String name, ClassDoc container,
+                                String[] paramNames) {
+        for (ClassDoc cd = container; cd != null; cd = cd.superclass()) {
+            MethodDoc[] docs = cd.methods();
+            for (int i = 0, N = docs.length; i < N; i++) {
+                MethodDoc md = docs[i];
+                if (!md.name().equals(name)) {
+                    continue;
+                }
+                if (paramNames == null) {
+                    return md;
+                } else {
+                    if (parametersMatch(md.parameters(),
+                                        paramNames,
+                                        container)) {
+                        return md;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private ConstructorDoc constructorDoc(ClassDoc container,
+                                          String[] paramNames) {
+        for (ClassDoc cd = container; cd != null; cd = cd.superclass()) {
+            ConstructorDoc[] docs = cd.constructors();
+            for (int i = 0, N = docs.length; i < N; i++) {
+                ConstructorDoc md = docs[i];
+                if (paramNames == null) {
+                    return md;
+                } else {
+                    if (parametersMatch(md.parameters(),
+                                        paramNames,
+                                        container)) {
+                        return md;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private AdviceDoc adviceDoc(String name,
+                                AspectDoc container,
+                                String[] paramNames) {
+        
+        AspectDoc cd = container;
+        while (cd != null) {
+            AdviceDoc[] docs = cd.advice();
+            for (int i = 0, N = docs.length; i < N; i++) {
+                AdviceDoc md = docs[i];
+                if (!(name.equals(md.name()))) {
+                    continue;
+                }
+                if (paramNames == null) {
+                    return md;
+                } else {
+                    if (parametersMatch(md.parameters(),
+                                        paramNames,
+                                        container)) {
+                        return md;
+                    }
+                }
+            }
+            Object o = cd.superclass();
+            if (o instanceof AspectDoc) {
+                cd = (AspectDoc) o;
+            } else {
+                cd = null;
+            }
+        }
+        return null;
+    }
+
+    private boolean parametersMatch(Parameter[] params,
+                                    String[] paramNames,
+                                    ClassDoc container) {
+        if ((null == params) || (null == paramNames) || (null == container)) {
+            return false;
+        }
+        if (params.length != paramNames.length) {
+            return false;
+        }
+        for (int i = 0, N = params.length; i < N; i++) {
+            com.sun.javadoc.Type type1 = params[i].type();
+            com.sun.javadoc.Type type2 = TypeImpl.getInstance(paramNames[i],
+                                                              container);
+            if ((null == type1) || (!type1.equals(type2))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private ClassDoc classDoc(Doc d) {
+        if (d instanceof ClassDoc) {
+            return (ClassDoc)d;
+        }
+        if (d instanceof MemberDoc) {
+            return ((MemberDoc)d).containingClass();
+        }
+        return null;
+    }
+   
+    /** find next (matching) char x, ignoring instances
+     * preceded by escape character '\'.
+     */
+    private static int findNextChar(final String s, final int start, final char x) {  // XXX to Util
+        if ((null != s) && (start >= 0)) {
+            boolean escaped = false;
+            for (int i = start; i < s.length(); i++) {
+                char c = s.charAt(i);
+                if (('\\' == c) && !escaped) {
+                    escaped = true;
+                    continue;
+                } else if ((x == c) && !escaped) {
+                    return i;
+                }
+                if (escaped) {
+                    escaped = false;
+                }
+            }
+        }
+        return -1;
+    }
+    
+    /**
+     * This looks a bit hideous, and it is, I had a state diagram
+     * with every thing labled, but I lost it -- sorry ;).
+        * <pre>{@link  package.class#member  label} </pre>
+        * http://java.sun.com/j2se/1.3/docs/tooldocs/solaris/javadoc.html#\{@link}
+     */
+    private void resolve() {
+        String str = text();
+
+        if (str == null || str.length() < 1) {
+            return;
+        }
+
+        str = str.trim();
+
+        int N = str.length();
+        
+        char first = str.charAt(0);
+        if (first == '<') {
+            if ((N < 4) || (str.charAt(N-1) != '>')) {
+                err().error("see_tag_unterminated_url",str);
+            } else {
+                char second = str.charAt(1);
+                if ((second == 'a') || (second == 'A')) {
+                    label = str;
+                } else {
+                    err().error("see_tag_unterminated_url",str); // XXX wrong message
+                }
+            }
+            return;
+        }
+        
+        if (first == '"') {
+            if (N == 1) {
+                err().error("see_tag_unterminated_string",str);
+            } else if (str.charAt(N-1) == '"') {
+                label = str;
+            } else {
+                int loc = findNextChar(str, 1, '"');
+                if (-1 == loc) {
+                    err().error("see_tag_unterminated_string",str);
+                } else {
+                    label = str.substring(0, loc+1);
+                }
+            }
+            return;
+        }
+        // XXX but does not handle URLs?
+        char c = 0;
+        int state = 0, next = 0;
+        boolean finished = false;
+
+        int iclassEnd = -1;
+        int isharp = -1;
+        int ilastDot = -1;
+        int iStartLabel = -1;
+               int iEndMemberLabel = -1; // membername plus parameters
+        boolean sharp = false;
+        int i;
+    done:
+        for (i = 0; i < N; i++, state = next) {
+            c = str.charAt(i);
+            switch (state) {
+                
+            case 0: // seeking initial: [type|memberName]
+                if      (ident(c)) { next = 1; }
+                else if (c == '#') { next = 2; iclassEnd = i-1; }
+                else {
+                    err().error("see_tag_dot_sharp_or_id","\""+c+"\"@0",str);
+                    return;
+                }
+                break;
+
+            case 1: // reading initial [type|memberName] 
+                if      (ident(c)) { next = 1; }
+                else if (c == '#') { next = 2; iclassEnd = i-1; }
+                else if (c == '.') { next = 3; ilastDot = i; }
+                else if (space(c)) { iclassEnd = i-1; next = 16; }
+                else {
+                    err().error("see_tag_invalid_package_or_class","\""+c+"\"@1",str);
+                    return;
+                }
+                break;
+                
+            case 2: // start reading membername (field only?)
+                sharp = true;
+                if      (ident(c)) { next = 4; isharp = i; }
+                else {
+                    err().error("see_tag_expecting_field_name","\""+c+"\"@2",str);
+                    return;
+                }
+                break;
+
+            case 3: // reading qualified type name
+                if      (ident(c)) { next = 1; }
+                else {
+                    err().error("see_tag_invalid_id","\""+c+"\"@3",str);
+                    return;
+                }
+                break;
+
+            case 4: //  reading membername
+                if      (ident(c)) { next =  4; }
+                else if (space(c)) { next = 13; iEndMemberLabel = i-1;}
+                else if (c == '(') { next = 15; }
+                else {
+                    err().error("see_tag_invalid_param_start","\""+c+"\"@4",str);
+                    return;
+                }
+                break;
+
+            case 5: // start reading parms
+                if      (ident(c)) { next =  6; }
+                               else if (space(c)) { next = 5; }
+                else if (c == ')') { next = 13; iEndMemberLabel = i;}
+                else {
+                    err().error("see_tag_premature_param_end","\""+c+"\"@5",str);
+                    return;
+                }
+                break;
+
+            case 6: // reading parm (or type?)
+                if      (ident(c)) { next =  6; }
+                else if (c == '.') { next =  7; }
+                else if (c == '[') { next =  8; }
+                else if (space(c)) { next = 10; }
+                else if (c == ',') { next = 12; }
+                else if (c == ')') { iEndMemberLabel = i; next = 16; }
+                else {
+                    err().error("see_tag_invalid_parameter_type","\""+c+"\"@6",str);
+                    return;
+                }
+                break;
+
+            case 7: // reading qualified parameter type .
+                if      (ident(c)) { next =  6; }
+                else {
+                    err().error("see_tag_invalid_parameter_type_ident","\""+c+"\"@7",str);
+                    return;
+                }
+                break;
+
+            case 8: // reading end of [] 
+                if      (c == ']') { next =  9; }
+                else if (space(c)) { next = 8; }
+                else {
+                    err().error("see_tag_unterminated_array_type","\""+c+"\"@8",str);
+                    return;
+                }
+                break;
+
+            case 9: // maybe completed parameter type 
+                if      (c == '[') { next =  8; }
+                else if (space(c)) { next = 10; }
+                else if (c == ',') { next = 12; }
+                else if (c == ')') { iEndMemberLabel = i; next = 16; }
+                else {
+                    err().error("see_tag_invalid_parameter_type","\""+c+"\"@9",str);
+                    return;
+                }
+                break;
+
+            case 10: // completed parm type?
+                if      (ident(c)) { next = 11; }
+                else if (space(c)) { next = 12; }
+                else if (c == ',') { next = 14; }
+                else if (c == ')') { iEndMemberLabel = i; next = 16; }
+                else {
+                    err().error("see_tag_invalid_parameters","\""+c+"\"@10",str);
+                    return;
+                }
+                break;
+
+            case 11: // reading parm type?
+                if      (ident(c)) { next = 11; }
+                else if (space(c)) { next = 12; }
+                else if (c == ',') { next = 14; }
+                else if (c == ')') { iEndMemberLabel = i; next = 16; }
+                 else {
+                    err().error("see_tag_invalid_parameters","\""+c+"\"@11",str);
+                    return;
+                }
+                break;
+
+            case 12: // looking for next parm? 
+                if      (space(c)) { next = 12; }
+                else if (c == ',') { next = 14; }
+                else if (ident(c)) { next = 15; }
+                else if (c == ')') { iEndMemberLabel = i; next = 16; }
+                else {
+                    err().error("see_tag_invalid_parameters","\""+c+"\"@12",str);
+                    return;
+                }
+                break;
+
+            case 13: // seeking parms or label
+                if (space(c)) { next = 13; } 
+                else if (c == '(') { next =  5; } // start reading parms
+                else if (ident(c)) {    // start reading label
+                    iStartLabel = i; next = 17; 
+                 }
+                else {
+                    err().error("see_tag_invalid_parameters","\""+c+"\"@13",str);
+                    return;
+                }
+                break;
+
+            case 14: // type name (or identifier)
+                if      (ident(c)) { next =  6; }
+                else if (space(c)) { next = 14; }
+                else {
+                    err().error("see_tag_expecting_typename_or_whitespace","\""+c+"\"@14",str);
+                    return;
+                }
+                break;
+
+            case 15: // reading parms
+                if      (ident(c)) { next =  6; }
+                else if (space(c)) { next = 15; }
+                else if (c == ')') { iEndMemberLabel = i; next = 16; }
+                else {
+                    err().error("see_tag_premature_param_end","\""+c+"\"@15",str);
+                    return;
+                }
+                break;
+             case 16 :  // seeking label
+                if      (ident(c)) { iStartLabel = i; next = 17; }
+                else if (space(c)) { next = 16; }
+                else {
+                    String s = "\"" + c + "\" in \"" + text() + "\"";
+                    err().error("see_tag_premature_param_end",s + "@16",str);
+                    return;
+                }
+               break;
+             case 17 :  // reading label - may have internal spaces
+                if      (ident(c)) { next =  17; }
+                else if (space(c)) { next = 17; }
+                // XXX known limitation - labels may only be ident + whitespace (no -)
+                else {
+                    err().error("see_tag_premature_param_end","\""+c+"\"@17",str);
+                    return;
+                }
+               break;
+            }
+
+            if (i == N-1) {
+                finished = next == -1
+                    || next == 1 || next == 13
+                                       || next == 16 || next == 17
+                    || next == 4 || next == 12;
+            }
+            
+        }
+
+        if (sharp) {
+            if (ilastDot != -1) {
+                packageName = str.substring(0, ilastDot);
+            }
+        } else {
+            if (ilastDot == -1) {
+                //packageName = str;
+            } else {
+                packageName = str.substring(0, ilastDot);
+            }
+        }
+
+        if (sharp) {
+            if (iclassEnd != -1) {
+                if (ilastDot == -1) {
+                    className = str.substring(0, iclassEnd+1);
+                } else {
+                    className = str.substring(ilastDot+1, iclassEnd+1);
+                }
+            }
+        } else {
+            if (ilastDot == -1) {
+                if (iclassEnd != -1) {
+                   className = str.substring(0, iclassEnd+1);
+                } else {
+                       className = str;
+                }
+            } else {
+                if (iclassEnd != -1) {
+                   className = str.substring(ilastDot+1, iclassEnd+1);
+                } else {
+                   className = str.substring(ilastDot+1);
+                   }
+            }
+        }
+
+        if (sharp) {
+            if (-1 != iEndMemberLabel) {
+                   memberName = str.substring(isharp, iEndMemberLabel+1).trim();
+            } else {
+                   memberName = str.substring(isharp).trim();
+            }
+            // hack to remove spaces between method name and parms
+            int parmLoc = memberName.indexOf("(");
+            if (-1 != parmLoc) {
+                               int spaceLoc = memberName.indexOf(" ");
+                               if ((-1 != spaceLoc) && (spaceLoc < parmLoc)) {
+                                       memberName = memberName.substring(0,spaceLoc)
+                                               + memberName.substring(parmLoc).trim();
+                               }
+            }
+        }
+
+        if (!finished) {
+            err().error("see_tag_prematurely_done",str);
+        } else {
+            if (iStartLabel != -1) {
+                label = str.substring(iStartLabel).trim();
+            } else if (i < N-1) { // when does this happen?
+                label = str.substring(i).trim();
+            }        
+        }
+    }
+    
+    // test-only methods
+    String getPackageName() {return packageName;}
+       String getClassName() { return className;}
+       String getMemberName() { return memberName; }
+       String getLabel() { return label; }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/SerialFieldTagImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/SerialFieldTagImpl.java
new file mode 100644 (file)
index 0000000..3b00549
--- /dev/null
@@ -0,0 +1,173 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.Doc;
+import com.sun.javadoc.SerialFieldTag;
+
+import java.util.Locale;
+
+/**
+ * Represents a serial field tag in the aspectj-world.
+ *
+ * @author Jeff Palm
+ */
+public class SerialFieldTagImpl
+    extends TagImpl implements SerialFieldTag,
+                               Comparable {
+
+    private String description;
+    private String fieldName;
+    private String fieldType;
+    private ClassDoc fieldTypeDoc;
+
+    /**
+     * Constructs the new tag with given parameters and
+     * then tries to resolve the names of the text.
+     *
+     * @param doc    the new value for <code>doc</code>.
+     * @param name   the new value for <code>name</code>.
+     * @param text   the new value for <code>text</code>.    
+     * @param locale the new value for <code>locale</code>.
+     * @param err    the new value for <code>err</code>.
+     */
+    public SerialFieldTagImpl(Doc doc,
+                              String name,
+                              String text,
+                              Locale loc,
+                              ErrPrinter err) {
+        super(doc, name, text, loc, err);
+        resolveNames(text);
+    }
+
+    /**
+     * Returns the description.
+     *
+     * @return the description.
+     */
+    public String description() {
+        return description;
+    }
+
+    /**
+     * Returns the field name.
+     *
+     * @return the field name.
+     */
+    public String fieldName() {
+        return fieldName;
+    }
+
+    /**
+     * Returns the field type.
+     *
+     * @return the field type.
+     */
+    public String fieldType() {
+        return fieldType;
+    }
+
+    /**
+     * Returns the class of the field type.
+     *
+     * @return a ClassDoc with type name fieldType.
+     */
+    public ClassDoc fieldTypeDoc() {
+        return fieldTypeDoc;
+    }
+
+    //XXX
+    //TODO: implement
+    public int compareTo(Object other) {
+        return -1;
+    }
+    
+    /**
+     * Returns <code>serialField</code>.
+     *
+     * @return <code>serialField</code>.
+     */
+    public String kind() {
+        return "@serialField";
+    }
+    
+    
+    private void resolveNames(String str) {
+        //
+        // @serialField  field-name  field-type  field-description
+        //
+        if (str == null || (str = str.trim()).length() < 1) return;
+        final int N = str.length();
+        
+        int i = 0;
+        int start;
+
+        // Find the first char in the field-name
+        start = i;
+        if (i < N && !start(str.charAt(i++))) {
+            err().error("serialField_tag_invalid_field_name_start",
+                        ""+str.charAt(i));
+            return;
+        }
+
+        // Find the rest of the field-name
+        while (i < N && !space(str.charAt(i))) {
+            if (!ident(str.charAt(i))) {
+                err().error("serialField_tag_invalid_field_name_part",
+                            ""+str.charAt(i));
+                return;
+            }
+            i++;
+        }
+
+        // Found the field-name
+        fieldName = str.substring(start, i).trim();
+
+        // Find the first char in the field-type
+        start = i;
+        if (i < N && !start(str.charAt(i++))) {
+            err().error("serialField_tag_invalid_type_name_start",
+                        ""+str.charAt(i));
+            return;
+        }
+
+        // Find the rest of the field-name
+        while (i < N && !space(str.charAt(i))) {
+            if (!(str.charAt(i) == '[' ||
+                  str.charAt(i) == ']' ||
+                  ident(str.charAt(i)))) {
+                err().error("serialField_tag_invalid_type_name_part",
+                            ""+str.charAt(i));
+                return;
+            }
+        }
+
+        // Found the field-type
+        fieldType = str.substring(start, i).trim();
+
+        // The rest is the field-description
+        if (i < N) {
+            description = str.substring(i).trim();
+        }
+    }    
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/TagImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/TagImpl.java
new file mode 100644 (file)
index 0000000..4fe4eff
--- /dev/null
@@ -0,0 +1,181 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import com.sun.javadoc.Doc;
+import com.sun.javadoc.Tag;
+
+import java.util.Locale;
+
+public class TagImpl implements Tag {
+
+    private Locale locale;
+    private ErrPrinter err;
+    private String name;
+    private String text;
+    private Doc doc;
+
+    /**
+     * Constructs the new tag with given parameters.
+     *
+     * @param doc    the new value for <code>doc</code>.
+     * @param name   the new value for <code>name</code>.
+     * @param text   the new value for <code>text</code>.    
+     * @param locale the new value for <code>locale</code>.
+     * @param err    the new value for <code>err</code>.
+     */
+    public TagImpl(Doc doc,
+                   String name,
+                   String text,
+                   Locale locale,
+                   ErrPrinter err) {
+        this.doc = doc;
+        this.name = name;
+        this.text = text;
+        this.locale = locale;
+        this.err = err;
+    }
+
+    /**
+     * Returns the Doc associated with this tag.
+     *
+     * @return the Doc associated with this tag.
+     */
+    protected final Doc doc() {
+        return doc;
+    }
+
+    /**
+     * Returns the ErrPrinter associated with this tag.
+     *
+     * @return the ErrPrinter associated with this tag.
+     */
+    protected final ErrPrinter err() {
+        return err == null ? ErrPrinter.instance : err;
+    }
+
+    /**
+     * Delegates to {@link Util#start(char)}.
+     *
+     * @see Util#start(char)
+     */
+    protected final static boolean start(char c) { return Util.start(c); }
+
+    /**
+     * Delegates to {@link Util#ident(char)}.
+     *
+     * @see Util#ident(char)
+     */
+    protected final static boolean ident(char c) { return Util.ident(c); }
+
+    /**
+     * Delegates to {@link Util#space(char)}.
+     *
+     * @see Util#space(char)
+     */
+    protected final static boolean space(char c) { return Util.space(c); }
+
+    /**
+     * Delegates to {@link Util#split(char)}.
+     *
+     * @see Util#split(char)
+     */
+    protected final static String[] split(String s) { return Util.split(s); }
+
+    /**
+     * Returns the name.
+     *
+     * @return the name.
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * Returns the kind followed by the String text.
+     *
+     * @return kind followed by the String text.
+     */
+    public String toString() {
+        return kind() + " " + text;
+    }
+
+    /**
+     * Returns the kind of tag.
+     *
+     * @return kind of the tag.
+     */
+    public String kind() {
+        return name;
+    }
+
+    /**
+     * Returns the String text of this tag.
+     *
+     * @return String text of this tag.
+     */
+    public String text() {
+        return text;
+    }
+
+    /**
+     * Sets the String text.
+     *
+     * @param text the new value for <code>text</code>.
+     */
+    protected void setText(String text) {
+        this.text = text;
+    }
+
+    /**
+     * Returns the locale.
+     *
+     * @return the locale.
+     */
+    public Locale locale() {
+        return locale;
+    }
+
+    /**
+     * Returns the inline tags in this tag.
+     *
+     * @return an array of Tag representing the inline
+     *         tags in this tag.
+     * @see    Util#inlineTags
+     */
+    public Tag[] inlineTags() {
+        return Util.inlineTags(doc(), text(), locale(), err()); //doc());
+    }
+
+    /**
+     * Returns the first sentence tags in this tag.
+     *
+     * @return an array of Tag representing the first sentence
+     *         tags in this tag.
+     * @see    Util#firstSentenceTags
+     */
+    public Tag[] firstSentenceTags() {
+        return Util.firstSentenceTags(doc(), text(), locale(), err());
+    }
+
+
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ThrowsTagImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/ThrowsTagImpl.java
new file mode 100644 (file)
index 0000000..f6ade10
--- /dev/null
@@ -0,0 +1,104 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.Doc;
+import com.sun.javadoc.ThrowsTag;
+
+import java.util.Locale;
+
+/**
+ * Represents a throws tag in the aspectj-world.
+ *
+ * @author Jeff Palm
+ */
+public class ThrowsTagImpl extends TagImpl implements ThrowsTag {
+
+    private ClassDoc exception;
+    private String exceptionComment;
+    private String exceptionName;
+
+    /**
+     * Constructs the new tag with given parameters and
+     * splits the text.
+     *
+     * @param doc    the new value for <code>doc</code>.
+     * @param name   the new value for <code>name</code>.
+     * @param text   the new value for <code>text</code>.    
+     * @param locale the new value for <code>locale</code>.
+     * @param err    the new value for <code>err</code>.
+     */
+    public ThrowsTagImpl(Doc doc,
+                         String name,
+                         String text,
+                         Locale loc,
+                         ErrPrinter err) {
+        super(doc, name, text, loc, err);
+        String[] split = split(text);
+        exceptionName = split[0];
+        exceptionComment = split[1];
+        exception = findException();
+    }
+
+    /**
+     * Returns the exception thrown.
+     *
+     * @return a ClassDoc that represents the thrown exception.
+     */
+    public ClassDoc exception() {
+        return exception;
+    }
+
+    /**
+     * Returns the comment text.
+     *
+     * @return a String of the comment text.
+     */
+    public String exceptionComment() {
+        return exceptionComment;
+    }
+
+    /**
+     * Returns the name of the type of exception thrown.
+     *
+     * @return a String name of the type of exception thrown.
+     */
+    public String exceptionName() {
+        return exceptionName;
+    }
+
+    /**
+     * Returns <code>throws</code>.
+     *
+     * @return <code>throws</code>.
+     */
+    public String kind() {
+        return "@throws";
+    }
+
+    //XXX
+    //TODO: implement         FUUUUUUCCCCCCCCCKKKKKKKKKKKK
+    private ClassDoc findException() {
+        return null;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/TypeImpl.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/TypeImpl.java
new file mode 100644 (file)
index 0000000..683848c
--- /dev/null
@@ -0,0 +1,165 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ast.ArrayType;
+import org.aspectj.compiler.base.ast.NameType;
+import org.aspectj.compiler.base.ast.PrimitiveType;
+import org.aspectj.compiler.base.ast.Type;
+
+import com.sun.javadoc.ClassDoc;
+
+public class TypeImpl { //implements org.aspectj.ajdoc.Type {
+
+    public static com.sun.javadoc.Type getInstance(Type type) {
+        return factory.getInstance(type);
+    }
+
+    public static com.sun.javadoc.Type getInstance(String spec,
+                                                   ClassDoc where) {
+        return factory.getInstance(spec, where);
+    }
+
+    private final static class Primitive implements org.aspectj.ajdoc.Type {
+
+
+
+        public final static Primitive getInstance(PrimitiveType type) {
+            return getInstance(type.getName());
+        }
+        
+        public final static Primitive getInstance(String name) {
+            if ("void".equals(name))     return    voidType;
+            if ("boolean".equals(name))  return booleanType;
+            if ("byte".equals(name))     return    byteType;
+            if ("char".equals(name))     return    charType;
+            if ("short".equals(name))    return   shortType;
+            if ("int".equals(name))      return     intType;
+            if ("long".equals(name))     return    longType;
+            if ("float".equals(name))    return   floatType;
+            if ("double".equals(name))   return  doubleType;
+            return null;
+        }
+
+        public final static boolean isPrimitive(String name) {
+            return name.equals("boolean")
+                || name.equals("byte")
+                || name.equals("char")
+                || name.equals("short")
+                || name.equals("int")
+                || name.equals("long")
+                || name.equals("float")
+                || name.equals("double");
+        }
+        
+        private final String name;
+        private Primitive(String name) { this.name = name; }
+        
+        public String          toString() { return name; }
+        public String          typeName() { return name; }
+        public String qualifiedTypeName() { return name; }
+        public String         dimension() { return   ""; }
+        public ClassDoc      asClassDoc() { return null; }
+        
+        private final static Primitive    voidType = new Primitive("void");
+        private final static Primitive booleanType = new Primitive("boolean");
+        private final static Primitive    byteType = new Primitive("byte");
+        private final static Primitive    charType = new Primitive("char");
+        private final static Primitive   shortType = new Primitive("short");
+        private final static Primitive     intType = new Primitive("int");
+        private final static Primitive    longType = new Primitive("long");
+        private final static Primitive   floatType = new Primitive("float");
+        private final static Primitive  doubleType = new Primitive("double");
+    }
+
+    private final static class Array implements org.aspectj.ajdoc.Type {
+        protected final com.sun.javadoc.Type type;
+        protected final int dimension;
+        private Array(com.sun.javadoc.Type type, int dimension) {
+            this.type = type;
+            //TODO: tune this later
+            this.dimension = dimension;
+        }
+
+        public String          toString() { return type.toString();          }
+        public String          typeName() { return type.typeName();          }
+        public String qualifiedTypeName() { return type.qualifiedTypeName(); }
+        public ClassDoc      asClassDoc() { return type.asClassDoc();        }
+        public String         dimension() {
+            String str = "";
+            for (int i = 0; i < dimension; i++) str += "[]";
+            return str;
+        }
+
+        public boolean equals(Object other) {
+            if (!(other instanceof Array)) {
+                return super.equals(other);
+            }
+            Array array = (Array)other;
+            return array.type.equals(type)
+                && array.dimension == dimension;
+        }
+    }
+        
+
+    private static final Factory factory = new Factory();
+    private final static class Factory {
+
+        private com.sun.javadoc.Type getInstance(Type type) {
+            if (type instanceof PrimitiveType) {
+                return Primitive.getInstance((PrimitiveType)type);
+            } else if (type instanceof ArrayType) {
+                ArrayType arrayType = (ArrayType)type;
+                Type component = arrayType.getComponentType();
+                while (component instanceof ArrayType) {
+                    component = ((ArrayType)component).getComponentType();
+                }
+                return new Array(getInstance(component),
+                                 arrayType.getArrayDimCount());
+            } else {
+                return ClassDocImpl.getInstance(((NameType)type).getTypeDec());
+            }
+        }
+
+        private com.sun.javadoc.Type getInstance(String spec,
+                                                 ClassDoc where) {
+            int ibracket = spec.indexOf('[');
+            String name;
+            int dimension;
+            if (ibracket != -1) {
+                name = spec.substring(0, ibracket);
+                dimension = spec.substring(ibracket+1).length()/2;
+            } else {
+                name = spec;
+                dimension = 0;
+            }
+            com.sun.javadoc.Type type = Primitive.getInstance(name);
+            if (type == null) {
+                type = where.findClass(name); //TODO
+            }
+            if (dimension > 0) {
+                type = new Array(type, dimension);
+            }
+            return type;
+        }
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Util.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/Util.java
new file mode 100644 (file)
index 0000000..eaf7fda
--- /dev/null
@@ -0,0 +1,933 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc;
+
+import org.aspectj.compiler.base.ast.Constructor;
+import org.aspectj.compiler.base.ast.ConstructorDec;
+import org.aspectj.compiler.base.ast.Exprs;
+import org.aspectj.compiler.base.ast.Field;
+import org.aspectj.compiler.base.ast.FieldDec;
+import org.aspectj.compiler.base.ast.Formals;
+import org.aspectj.compiler.base.ast.Method;
+import org.aspectj.compiler.base.ast.MethodDec;
+import org.aspectj.compiler.base.ast.NameType;
+import org.aspectj.compiler.base.ast.Type;
+import org.aspectj.compiler.base.ast.TypeDec;
+import org.aspectj.compiler.crosscuts.ast.PointcutDec;
+import org.aspectj.compiler.crosscuts.ast.PointcutSO;
+
+import com.sun.javadoc.Doc;
+import com.sun.javadoc.ExecutableMemberDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.javadoc.Parameter;
+import com.sun.javadoc.Tag;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+/**
+ * A utility class used by lots of folks.
+ *
+ * @author Jeff Palm
+ */
+public class Util {
+
+    /**
+     * Delegate to Character.isJavaIdentifierStart(char).
+     *
+     * @return <code>true</code> if <code>c</code> can
+     *         start a java identifier.
+     */
+    public final static boolean start(char c) {
+        return Character.isJavaIdentifierStart(c);
+    }
+
+    /**
+     * Delegate to Character.isJavaIdentifierPart(char).
+     *
+     * @return <code>true</code> if <code>c</code> can
+     *         be a part of a java identifier.
+     */
+    public final static boolean ident(char c) {
+        return Character.isJavaIdentifierPart(c);
+    }
+
+    /**
+     * Delegate to Character.isWhitespace(char).
+     *
+     * @return <code>true</code> if <code>c</code> is
+     *         valid white space.
+     */
+    public final static boolean space(char c) {
+        return Character.isWhitespace(c);
+    }
+
+    /**
+     * Returns true is <code>c</code> is a newline character.
+     *
+     * @return <code>true</code> if
+     *         <code>c == '\n' || c == '\r'</code>.
+     */
+    public final static boolean newline(char c) {
+        return c == '\n' || c == '\r';
+    }
+
+    /**
+     * Returns two strings split at the first white space.
+     *
+     * @return an array of two Strings split at
+     *         the first white space.
+     */
+    public static String[] split(String str) {
+        String[] strs = new String[2];
+        for (int i = 0; i < str.length(); i++) {
+            if (space(str.charAt(i))) {
+                strs[0] = str.substring(0, i);
+                strs[1] = str.substring(i+1);
+                break;
+            }
+        }
+        if (strs[0] == null) {
+            strs[0] = str;
+            strs[1] = "";
+        }
+        return strs;
+    }
+
+    /**
+     * Returns the inline tags found in <code>str</code>.
+     *
+     * @param doc Doc to give to the new tag.
+     * @param str String from which to create the tags.
+     * @param loc Locale to give to the new tag.
+     * @param err ErrPrinter to give to the new tag.
+     * @return    an array of Tag representing the inline
+     *            tags found in str.
+     */
+    public final static Tag[] inlineTags(Doc doc,
+                                         String str,
+                                         Locale loc,
+                                         ErrPrinter err) {
+        if (str == null || str.length() < 1) {
+            return new Tag[0];
+        }
+        
+        int N = str.length();
+
+        List list = new ArrayList();
+       
+        int i = 0;
+        for (int j = i; i < N; j = i) {
+            
+            // Try to match a link tag
+            int ileft = str.indexOf("{@", i);
+            
+            // If there are no more link tags, return the rest
+            // of str as a 'Text' Tag
+            if (ileft == -1) {
+                list.add(new TagImpl(doc, "Text",
+                                     str.substring(i),
+                                     loc, err));
+                break;
+            }
+
+            if (j < ileft) {
+                list.add(new TagImpl(doc, "Text",
+                                     str.substring(j, ileft),
+                                     loc, err));
+            }
+
+            // If there is a tag and it's name is 'link ' try to
+            // match it
+            i = ileft;
+            if (i+7 < N &&
+                str.substring(i+2, i+7).toLowerCase().equals("link ")) {
+                i += 7;
+                for (; str.charAt(i) != '}'; i++) {
+                    if (i == N-1) {
+                        err.error("tag_unterminated_link_tag",
+                                    str.substring(i));
+                        break;
+                    }
+                }
+                list.add(new SeeTagImpl(doc, "@link",
+                                        str.substring(ileft+7, i),
+                                        loc, err));
+            } else {
+                err.error("tag_invalid_link_tag",
+                            str.substring(i));
+            }
+
+            // Don't want to include the right brace
+            i += 1;           
+        }
+        return (Tag[])list.toArray(new Tag[list.size()]);
+    }
+
+    /**
+     * Returns the first sentence tags found in <code>str</code>.
+     *
+     * @param doc Doc to give to the new tag.
+     * @param str String from which to create the tags.
+     * @param loc Locale to give to the new tag.
+     * @param err ErrPrinter to give to the new tag.
+     * @return    an array of Tag representing the first
+     *            sentence tags found in str.
+     */
+    public final static Tag[] firstSentenceTags(Doc doc,
+                                                String str,
+                                                Locale loc,
+                                                ErrPrinter err) {
+        return inlineTags(doc, firstSentenceText(str, loc, err), loc, err);
+    }
+
+    /**
+     * Returns the first sentence tags found in <code>str</code>,
+     * using <code>Locale.US</code> as the default locale.
+     *
+     * @param doc Doc to give to the new tag.
+     * @param str String from which to create the tags.
+     * @param err ErrPrinter to give to the new tag.
+     * @return    an array of Tag representing the first
+     *            sentence tags found in str.
+     */
+    private static String firstSentenceText(String str,
+                                            Locale loc,
+                                            ErrPrinter err) {
+        if (str == null || loc == null || !loc.equals(Locale.US)) {
+            return "";
+        }
+        final int N = str.length();
+        int i;
+        for (i = 0; i < N; i++) {
+            
+            // A period at the end of the text or a
+            // period followed by white space is the
+            // end of a sentence
+            if (str.charAt(i) == '.') {
+                if (i == N-1) {
+                    return str.substring(0, i+1);
+                }
+                if (space(str.charAt(i+1))) {
+                    return str.substring(0, i+2);
+                }
+            }
+            
+            // An HTML tag the signals the end -- one of:
+            // <p> </p> <h1> <h2> <h3> <h4>
+            // <h5> <h6> <hr> <pre> or </pre>
+            if (str.charAt(i) == '<') {
+                int j = i+1;
+                
+                // Find the closing '>'
+                while (j < N && str.charAt(j) != '>') j++;
+                
+                // If there's no closing '>' signal an error
+                if (j == N) {
+                    err.error("unterminated_html_tag", str);
+                    return str;
+                }
+                
+                // Inspect the inside of the tag
+                String innards = str.substring(i+1, j).trim().toLowerCase();
+                if (innards.equals("p")  || innards.equals("pre") ||
+                    innards.equals("h1") || innards.equals("h2")  ||
+                    innards.equals("h3") || innards.equals("h4")  ||
+                    innards.equals("h5") || innards.equals("h6")  ||
+                    innards.equals("hr")) {
+                    return str.substring(0, i+1);
+                }
+            }
+        }
+        return str;
+    }
+
+    /**
+     * Returns the tags found in <code>str</code>.
+     *
+     * @param doc Doc to give to the new tag.
+     * @param str String from which to create the tags.
+     * @param loc Locale to give to the new tag.
+     * @param err ErrPrinter to give to the new tag.
+     * @return    an array of Tag representing the
+     *            tags found in str.
+     */
+    public final static List findTags(Doc doc,
+                                      String str,
+                                      Locale loc,
+                                      ErrPrinter err) {
+                                      
+        //XXX This sucks!!! Will redo later.
+        boolean newline = true;
+        List result = new ArrayList();
+        if (str == null) return result;
+        final int N = str.length();
+        int lastTag = -1;
+        for (int i = 0; i < N; i++) {
+            if (newline(str.charAt(i))) {
+                newline = true;
+                // XXX need to evaluate - some tags can span newlines?
+//                if (lastTag != -1) {  // now requiring tags not to span newlines
+//                    result.add(parse(doc, str.substring(lastTag, i),
+//                                     loc, err));
+//                }
+//                lastTag = -1
+            } else if (space(str.charAt(i)) && newline) {
+            } else if (str.charAt(i) == '@' && newline) {
+                if (lastTag != -1) {
+                    result.add(parse(doc, str.substring(lastTag, i),
+                                     loc, err));
+                }
+                lastTag = i;
+            } else {
+                newline = false;
+            }
+        }
+        if (lastTag != -1) {
+            result.add(parse(doc, str.substring(lastTag),
+                             loc, err));
+        }
+        return result;
+    }
+
+    private final static Tag parse(Doc doc,
+                                   String str,
+                                   Locale loc,
+                                   ErrPrinter err) {
+        Tag result = null;
+        String[] split = split(str);
+        String name = split[0];
+        String rest = split[1];
+        if (name.equals("@see")) {
+            result = new SeeTagImpl(doc, name, rest, loc, err);
+        } else if (name.equals("@exception") || name.equals("@throws")) {
+            result = new ThrowsTagImpl(doc, name, rest, loc, err);
+        } else if (name.equals("@serialField")) {
+            result = new SerialFieldTagImpl(doc, name, rest, loc, err);
+        } else if (name.equals("@param")) {
+            result = new ParamTagImpl(doc, name, rest, loc, err);
+        } else {
+            result = new TagImpl(doc, name, rest, loc, err);
+        }
+        return result;
+    }
+
+    /**
+     * Returns the raw comment text found in <code>str</code>.
+     *
+     * @param str String containing comment from which
+     *            the raw comment is found.
+     * @return    String with the raw comment taken
+     *            from <code>str</code>.
+     */
+    public final static String rawCommentText(String str) {
+        if (str == null) return "";
+        if (str.length() < 3) return "";
+        String withstars = "";
+        int islash = str.indexOf('/');
+        if (islash == -1 || islash+2 >= str.length()) {
+            return "";
+        }
+        if (str.charAt(islash+1) != '*' ||
+            str.charAt(islash+2) != '*') {
+            return "";
+        }
+        int start = islash+2+1;
+        while (str.charAt(start) == '*' || space(str.charAt(start))) start++;
+        int end = str.length()-2;
+        while (str.charAt(end) == '*') end--;
+        if (start != -1 && end > start) {
+            withstars = str.substring(start, end+1);
+        }
+        //String result = "";
+        StringBuffer result = new StringBuffer(withstars.length());
+        for (StringTokenizer t = new StringTokenizer(withstars, "\n", true);
+             t.hasMoreTokens();) {
+            String line = t.nextToken();
+            if (line == null || line.length() == 0) continue;
+            int i;
+            for (i = 0; i < line.length(); i++) {
+                if (!(line.charAt(i) == '*' ||
+                      line.charAt(i) == ' ')) {
+                    break;
+                }
+            }
+            //result += line.substring(i);
+            result.append(line.substring(i));
+        }
+        //return result;
+        return result.toString();
+    }
+
+    /**
+     * Returns the comment text from the passed in
+     * raw comment text -- e.g. no tags at the end.
+     *
+     * @param rawCommentText raw comment text to search.
+     * @return               the comment text from 
+     *                       <code>rawCommentText</code>.
+     */
+    public final static String commentText(String rawCommentText) {
+        //String result = "";
+        if (rawCommentText == null) {
+            return "";
+        }
+        StringBuffer result = new StringBuffer(rawCommentText.length());
+    outer:
+        for (StringTokenizer t = new StringTokenizer(rawCommentText, "\n", true);
+             t.hasMoreTokens();) {
+            String line = t.nextToken();
+            if (line == null || line.length() == 0) continue;
+            int i;
+            for (i = 0; i < line.length(); i++) {
+                char c = line.charAt(i);
+                if (c == ' ' || c == '\t') {
+                } else if (c == '@') {
+                    break outer;
+                } else {
+                    //result += line;
+                    result.append(line);
+                    continue outer;
+                }
+            }
+        }
+        //return result;
+        return result.toString();
+    }
+
+    /**
+     * Compares using names.
+     *
+     * @param $ First Doc.
+     * @param _ Second Doc.
+     * @return  -1 if either are null, else
+     *          <code>$.name.compareTo(_.name</code>.
+     */
+    public final static int compareTo(Doc $, Doc _) {
+        return ($ == null || _ == null) ? -1 : $.name().compareTo(_.name());
+    }
+
+    /**
+     * Returns the signature, given <code>parameters</code>,
+     * without flattening.
+     *
+     * @param parameters an array of Parameter.
+     * @return           String representation of the parameters.
+     * @see              #signature(Parameter[],boolean)
+     */
+    public final static String signature(Parameter[] parameters) {
+        return signature(parameters, false);
+    }
+
+    /**
+     * Returns the signature, given <code>parameters</code>,
+     * with flattening.
+     *
+     * @param parameters an array of Parameter.
+     * @return           String representation of the parameters.
+     * @see              #signature(Parameter[],boolean)
+     */
+    public final static String flatSignature(Parameter[] parameters) {
+        return signature(parameters, true);
+    }
+
+    /**
+     * Returns the signature, given <code>parameters</code>
+     * and flattens if <code>flatten</code>.
+     *
+     * @param parameters an array of Parameter.
+     * @param flatten    <code>true</code> if the parameter names
+     *                   should be flattened.
+     * @return           String representation of the parameters.
+     */
+    public final static String signature(Parameter[] parameters,
+                                         boolean flatten) {
+        if (parameters == null || parameters.length == 0) {
+            return "()";
+        }
+        //String str = "(";
+        StringBuffer str = new StringBuffer((flatten ? 8 : 20) *
+                                            parameters.length);
+        str.append("(");
+        final int N = parameters.length;
+        for (int i = 0; i < N; i++) {
+            String typeName = parameters[i].typeName();
+            if (flatten) {
+                int idot = typeName.lastIndexOf('.');
+                if (idot != -1) {
+                    typeName = typeName.substring(idot+1);
+                }
+            }
+            //str += typeName + (i < N-1 ? "," : "");
+            str.append(typeName + (i < N-1 ? "," : ""));
+                
+        }
+        //str += ")";
+        str.append(")");
+        //return str;
+        return str.toString();
+    }
+
+    /**
+     * Returns <code>true</code> -- include all members for now.
+     *
+     * @param doc   member to consider.
+     * @param flags access flags.
+     */
+    public final static boolean isIncluded(MemberDoc doc, long flags) {
+        return true;
+    }
+
+    /**
+     * Returns <code>true</code> if <code>dec</code>
+     * isn't local or annonymous or <code>null</code>.
+     *
+     * @param dec TypeDec to consider.
+     * @return    <code>true</code> isn't dec is local or
+     *            annonymous or <code>null</code>.
+     */
+    public final static boolean isIncluded(TypeDec dec) {
+        if (dec == null) {
+            return false;
+        }
+        if (dec.isLocal() && dec.isAnonymous()) {
+            return false;
+        }
+        return true; //XXX to do
+    }
+
+    //XXX Debugging
+    public final static void dump(Object o, String prefix) {
+        System.err.println(">> Dumping:"+o);
+        java.lang.reflect.Method[] ms = o.getClass().getMethods();
+        List list = new ArrayList();
+        for (int i = 0; i < ms.length; i++) {
+            list.add(ms[i]);
+        }
+        Collections.sort(list, new Comparator() {
+                public int compare(Object o1, Object o2) {
+                    return str(o1).compareTo(str(o2));
+                }
+                public boolean equals(Object o1, Object o2) {
+                    return str(o1).equals(str(o2));
+                }
+                private String str(Object _) {
+                    return (_ != null && _ instanceof java.lang.reflect.Method)
+                        ? ((java.lang.reflect.Method)_).getName() : _+"";
+                }
+            });
+        for (Iterator i = list.iterator(); i.hasNext();) {
+            java.lang.reflect.Method m = (java.lang.reflect.Method)i.next();
+            if (m.getParameterTypes().length == 0 &&
+                m.getName().startsWith(prefix)) {
+                try {                    
+                    System.err.println("  "+m.getName()+":"+
+                                       m.invoke(o, new Object[0]));
+                } catch (Throwable _) {}
+            }
+        }
+    }
+    public final static void gets(Object o) {
+        dump(o, "get");
+    }
+    public final static void array(Object[] os) {
+        array(os, false);
+    }
+    public final static void array(Object[] os, boolean gets) {
+        if (os == null) {
+            System.err.println("NULL");
+            return;
+        }
+        System.err.println(os.getClass().getName()+":" + os.length);
+        for (int i = 0; i < os.length; i++) {
+            System.err.println(" [" + i +"]:" + os[i]);
+            if (gets) gets(os[i]);
+        }
+    }
+
+    /**
+     * Returns the HTML documentation found in <code>html</code>
+     * using <code>err</code> to report errors.
+     *
+     * @param html File in which to look.
+     * @param err  ErrPrinter to use to report errors.
+     * @return     HTML documentaiton found in <code>html</code>.
+     */
+    public static String documentation(File html, ErrPrinter err) {
+        String str = "";
+        InputStream in = null;
+        try {
+            in = new FileInputStream(html);
+        } catch (IOException ioe) {
+            err.ex(ioe, "ioexception_open", html.getAbsolutePath());
+            return "";
+        }
+        try {
+            byte[] bytes = new byte[in.available()];
+            in.read(bytes, 0, bytes.length);
+            in.close();
+            str = new String(bytes);
+        } catch (IOException ioe) {
+            err.ex(ioe, "ioexception_reading", html.getAbsolutePath());
+        }
+
+        int[] is = new int[]{-10,-1};
+        int i = 0;
+        final char[] chars = new char[]{'/','B','O','D','Y','>'};
+        for (int j = 1; j >= 0; j--) {
+        nextTag:
+            for (; i != -1; i = str.indexOf('<', i+1)) {
+            nextLt:
+                for (int s = i+1, k = j; s < str.length(); s++, k++) {
+                    char c = str.charAt(s);
+                    if (k == chars.length) {
+                        is[j] += s+2;
+                        break nextTag;
+                    }
+                    if (!(c == chars[k] || c == (chars[k] | 0x01000000))) {
+                        break nextLt;
+                    }
+                }
+            }
+        }
+        if (is[0] > -1 && is[1] > -1) {
+            str = str.substring(is[1], is[0]);
+        }
+        return str;
+    }
+
+    /**
+     * Returns the result of invoking the method <code>name</code>
+     * on <code>target</code> with parameters <code>params</code>
+     * declared in the <code>target</code>'s class using arguments
+     * <code>args</code>.
+     *
+     * @param target target Object.
+     * @param name   name of the method.
+     * @param params array of Class of parameters of the method.
+     * @param args   array of Object of arguments to the method.
+     * @return       the result of invoking the method.
+     * @see          #invoke(Class,Object,String,Class[],Object[])
+     */
+    public static Object invoke(Object target, String name,
+                                Class[] params, Object[] args) {
+        return invoke(target.getClass(), target, name, params, args);
+    }
+
+    /**
+     * Returns the result of invoking the method <code>name</code>
+     * on <code>target</code> with parameters <code>params</code>
+     * declared in the <code>type</code> using arguments
+     * <code>args</code>.
+     * This method handles any errors that arise in doing so.
+     *
+     * @param type   type in which the method is declared.
+     * @param target target Object -- null for static methods.
+     * @param name   name of the method.
+     * @param params array of Class of parameters of the method.
+     * @param args   array of Object of arguments to the method.
+     * @return       the result of invoking the method.
+     */
+    public static Object invoke(Class type, Object target, String name,
+                                Class[] params, Object[] args) {
+        try {
+            java.lang.reflect.Method method = type.getDeclaredMethod(name, params);
+            method.setAccessible(true);
+            return method.invoke(target, args);
+        } catch (Exception e) {
+            e.printStackTrace(); //TODO
+        }
+        return null;
+    }
+
+    /**
+     * Returns the value of access the field <code>name</code>
+     * declared in <code>type</code> on <code>target</code>.
+     * This method handles any errors that arise in doing so.
+     *
+     * @param type   type in which the field is declared.
+     * @param target target that is currently holding the field --
+     *               null for static fields.
+     * @param name   name of the field.
+     * @return       the result of accessing this field.
+     */
+    public static Object access(Class type, Object target, String name) {
+        try {
+            java.lang.reflect.Field field = type.getDeclaredField(name);
+            field.setAccessible(true);
+            return field.get(target);
+        } catch (Exception e) { //TODO
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * Returns the ExecutableMemberDoc from the array passed
+     * in whose parameters <i>weakly</i> match those of
+     * <code>params</code> and whose name matches exactly
+     * with <code>name</code>.
+     * This method <b>can</b> return <code>null</code>.
+     *
+     * @param emds   an array of ExecutableMemberDoc from which
+     *               the returned value comes.
+     * @param name   the name of the member to return.
+     * @param params an array of Parameter that represent
+     *               the parameters we're trying to match.
+     * @return       an ExecutableMemberDoc whose parameters
+     *               match the names and order found in
+     *               <code>params</code> and whose name
+     *               exactly equals <code>name</code>.
+     */
+    public final static ExecutableMemberDoc executableMemberDoc
+        (ExecutableMemberDoc[] emds,
+         String name,
+         Parameter[] params) {
+        ExecutableMemberDoc result = null;
+        next:
+        for (int i = 0; i < emds.length; i++) {
+            ExecutableMemberDoc emd = emds[i];
+            if (emd.name().equals(name) &&
+                params.length == emd.parameters().length) {
+                for (int j = 0; j < params.length; j++) {
+                    if (!params[j].typeName().equals
+                        (emd.parameters()[j].typeName())) {
+                        continue next;
+                    }
+                    result = emd;
+                    break next;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns the PointcutDoc from the array passed
+     * in whose parameters <i>weakly</i> match those of
+     * <code>formals</code> and whose name matches exactly
+     * with <code>id</code>.
+     * This method <b>can</b> return <code>null</code>.
+     *
+     * @param nameType the type in which we're searching.
+     * @param id       the name of the pointcut to return.
+     * @param formals  the Formals whose name and order
+     *                 must match to return a pointcut.
+     * @return         a PointcutDoc whose parameters
+     *                 match the names and order found in
+     *                 <code>formals</code> and whose name
+     *                 exactly equals <code>id</code>.
+     */
+    public final static PointcutDec pointcutDec(NameType nameType,
+                                                String id,
+                                                Formals formals) {
+        PointcutDec result = null;
+    next:
+        for (Iterator i = nameType.getPointcuts().iterator(); i.hasNext();) {
+            PointcutDec md = ((PointcutSO)i.next()).getPointcutDec();
+            if (md.getFormals().size() == formals.size() &&
+                id.equals(md.getId())) {
+                for (int j = 0; j < formals.size(); j++) {
+                    if (!md.getFormals().get(j).getType().getString().
+                        equals(formals.get(j).getType().getString())) {
+                        continue next;
+                    }
+                }
+                result = md;
+                break next;
+            }
+        }
+        return result;
+    }
+
+    
+
+    /**
+     * Returns the MethodDoc from the array passed
+     * in whose parameters <i>weakly</i> match those of
+     * <code>formals</code> and whose name matches exactly
+     * with <code>id</code>.
+     * This method <b>can</b> return <code>null</code>.
+     *
+     * @param nameType the type in which we're searching.
+     * @param id       the name of the method to return.
+     * @param formals  the Formals whose name and order
+     *                 must match to return a method.
+     * @return         a MethodDoc whose parameters
+     *                 match the names and order found in
+     *                 <code>formals</code> and whose name
+     *                 exactly equals <code>id</code>.
+     */
+    public final static MethodDec methodDec(NameType nameType,
+                                            String id,
+                                            Formals formals) {
+        MethodDec result = null;
+    next:
+        for (Iterator i = nameType.getMethods().iterator(); i.hasNext();) {
+            //MethodDec md = (MethodDec)i.next();
+            MethodDec md = ((Method)i.next()).getMethodDec();
+            if (md.getFormals().size() == formals.size() &&
+                id.equals(md.getId())) {
+                for (int j = 0; j < formals.size(); j++) {
+                    if (!md.getFormals().get(j).getType().getString().
+                        equals(formals.get(j).getType().getString())) {
+                        continue next;
+                    }
+                }
+                result = md;
+                break next;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns the PointcutDec named <code>name</code>,
+     * contained in <code>typeDec</code> with type <code>type</code>.
+     * <code>showError</code> is passed to subsequent methods
+     * to supress or warrant error printing.
+     * This may return null.
+     *
+     * @param type      Type in which this pointcut was declared.
+     * @param name      name of the pointcut.
+     * @param typeDec   TypeDec in which we're searching.
+     * @param showError <code>true</code> is an error should
+     *                  be printed upon not finding a pointcut.
+     * @return          the pointcut declared in <code>type</code>
+     *                  named <code>name</code>, found by searching
+     *                  from <code>typeDec</code>.  This may be
+     *                  null.
+     */
+    public static PointcutDec getPointcutDec(Type type,
+                                             String name,
+                                             TypeDec typeDec,
+                                             boolean showError) {
+        PointcutSO so = ((NameType)type).getPointcut(name, typeDec, showError);
+        PointcutDec dec = null;
+        if (so != null) {
+            dec = (PointcutDec)so.getCorrespondingDec();
+        }
+        return dec;
+    }
+    
+    /**
+     * Returns the FieldDec named <code>name</code>,
+     * contained in <code>typeDec</code> with type <code>type</code>.
+     * <code>showError</code> is passed to subsequent methods
+     * to supress or warrant error printing.
+     * This may return null.
+     *
+     * @param type      Type in which this field was declared.
+     * @param name      name of the field.
+     * @param typeDec   TypeDec in which we're searching.
+     * @param showError <code>true</code> is an error should
+     *                  be printed upon not finding a field.
+     * @return          the field declared in <code>type</code>
+     *                  named <code>name</code>, found by searching
+     *                  from <code>typeDec</code>.  This may be
+     *                  null.
+     */
+    public static FieldDec getFieldDec(Type type,
+                                       String name,
+                                       TypeDec typeDec,
+                                       boolean showError) {
+        Field so = ((NameType)type).getField(name, typeDec, showError);
+        FieldDec dec = null;
+        if (so != null) {
+            dec = (FieldDec)so.getCorrespondingDec();
+        }
+        return dec;
+    }
+
+    /**
+     * Returns the MethodDec named <code>name</code>, with
+     * formals <code>params</code>,
+     * contained in <code>typeDec</code> with type <code>type</code>.
+     * <code>showError</code> is passed to subsequent methods
+     * to supress or warrant error printing.
+     * This may return null.
+     *
+     * @param type      Type in which this method was declared.
+     * @param name      name of the method.
+     * @param typeDec   TypeDec in which we're searching.
+     * @param params    the method's formal parameters.
+     * @param showError <code>true</code> is an error should
+     *                  be printed upon not finding a method.
+     * @return          the method declared in <code>type</code>
+     *                  named <code>name</code>, found by searching
+     *                  from <code>typeDec</code>.  This may be
+     *                  null.
+     */
+    public static MethodDec getMethodDec(Type type,
+                                         String name,
+                                         TypeDec typeDec,
+                                         Exprs params,
+                                         boolean showError) {
+        Method so = ((NameType)type).getMethod(name, typeDec, params, showError);
+        MethodDec dec = null;
+        if (so != null) {
+            dec = so.getMethodDec();
+        }
+        return dec;
+    }
+    
+    /**
+     * Returns the ConstructorDec named <code>name</code>, with
+     * formals <code>params</code>,
+     * contained in <code>typeDec</code> with type <code>type</code>.
+     * <code>showError</code> is passed to subsequent constructors
+     * to supress or warrant error printing.
+     * This may return null.
+     *
+     * @param type      Type in which this constructor was declared.
+     * @param name      name of the constructor.
+     * @param typeDec   TypeDec in which we're searching.
+     * @param params    the constructor's formal parameters.
+     * @param showError <code>true</code> is an error should
+     *                  be printed upon not finding a constructor.
+     * @return          the constructor declared in <code>type</code>
+     *                  named <code>name</code>, found by searching
+     *                  from <code>typeDec</code>.  This may be
+     *                  null.
+     */
+    public static ConstructorDec getConstructorDec(Type type,
+                                                   TypeDec typeDec,
+                                                   Exprs params,
+                                                   boolean showError) {
+        Constructor so = ((NameType)type).getConstructor(typeDec,
+                                                         params, showError);
+        ConstructorDec dec = null;
+        if (so != null) {
+            dec = (ConstructorDec)so.getCorrespondingDec();
+        }
+        return dec;
+    }    
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/resources/ajdoc.properties b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/resources/ajdoc.properties
new file mode 100644 (file)
index 0000000..e1c0a4b
--- /dev/null
@@ -0,0 +1,77 @@
+usage_help=usage\: {0} [options] [packagenames] [sourcefiles] [classnames] [@files]\n-overview <file>          Read overview documentation from HTML file\n-public                   Show only public classes and members\n-protected                Show protected/public classes and members (default)\n-package                  Show package/protected/public classes and members\n-private                  Show all classes and members\n-help                     Display command line options\n-doclet <class>           Generate output via alternate doclet (unsupported)\n-docletpath <path>        Specify where to find doclet class files (unsupported)\n-sourcepath <pathlist>    Specify where to find source files\n-classpath <pathlist>     Specify where to find user class files\n-bootclasspath <pathlist> Override location of class files loaded\n                          by the bootstrap class loader \n-source 1.4               Provide source compatibility with Java 1.4 \n-extdirs <dirlist>        Override location of installed extensions\n-verbose                  Output messages about what AJDoc is doing\n-locale <name>            Locale to be used, e.g. en_US or en_US_WIN\n-encoding <name>          Source file encoding name\n-standard                 Use com.sun.tools.doclets.standard.Standard doclet\n-log                      Log each pass of document generation\n-argfile <file>           The file contains a line-delimited list of files\n                          inserted into the argument list\n-compiler <class>         Generate RootDoc to doclet via alternate compiler (unsupported)
+\n-J<flag>                  Pass <flag> directly to the runtime system\n
+
+internal_error=Internal error\: {0}
+file_not_found_exception:Cannot read file\: {0}.
+io_exception:IOException\: {0}.
+argument_already_seen=The {0} option may be specified no more than once.
+invalid_flag=invalid flag\: {0}.
+requires_argument=option {0} requires {1} argument(s).
+cant_create_root_doc=Cannot create RootDoc from class {0}.
+cant_create_root_doc_ex=Cannot create RootDoc from class {0}\: {1}.
+incorrect_root_doc_class=The class {0} must implement the interface org.aspectj.tools.javadoc.RootDocMaker, not {1}.
+root_doc_maker_is_null=Could not create RootDocMaker from class {0}.
+done_in=[done in {0} ms]
+internal_error_exception_thrown=Internal error\: In class {0}, method {1} has thrown an exception: {2}.
+method_not_accessible=In class {0}, method {1} not accessible.
+class_not_found=Cannot find {0} class {1}.
+invoke_exception_thrown=Could not invoke method {0} in class {1}.
+must_return=In class {0}, method {1} must return {2}, not {3}.
+doclet_method_not_found=Doclet class {0} does not contain a {1} method.
+doclet_method_not_accessible=In doclet class {0}, method {1} not accessible.
+doclet_method_must_be_static=In doclet class {0}, method {1} must be static.
+out_of_memory=java.lang.OutOfMemoryError\: Please increase memory.\nFor example, on the Sun Classic or HotSpot VMs, add the option -J-Xmx\nsuch as -J-Xmx32m.
+exception_thrown=In {0} class {1}, method {2} has thrown an exception\: {3}
+No_packages_or_classes_specified=No packages or classes specified.
+cant_create_doclet:Cannot create Doclet from class {0}
+
+method_not_found={0} class {1} does not contain a {2} method.
+method_not_accessible=In {0} class {1}, method {2} not accessible.
+must_have_default_ctor=Class {0} must contain a default, no-arguments constructor.
+class_cast_exception:Return type of method {0} in class {1} must be {2}, not {3}
+cant_construct_object=Cannot construct object of type {0}
+unsupported_version=The version {0} is currently not supported by {1}.
+
+see_tag_prematurely_done=Prematurely done reading - not finished\: {0}
+see_tag_unterminated_url=Unterminated see tag URL\: {0}
+see_tag_unterminated_string=Unterminated see tag string\: {0}
+see_tag_invalid_package_or_class=Invalid package or class in see tag\:{0}\: {1}
+see_tag_invalid_field_name=Invalid field name in see tag\:{0}\: {1}
+see_tag_invalid_param_start=Invalid parameter start in see tag\:{0}\: {1}
+see_tag_premature_param_end=Premature end of parameters in see tag\:{0}\: {1}
+see_tag_invalid_id=Invalid identifier in see tag\:{0}\: {1}
+see_tag_invalid_parameter_type=Invalid parameter type in see tag {0}\: {1}
+see_tag_invalid_parameter_type=Invalid parameter type in see tag {0}\: {1}
+see_tag_invalid_parameter_type_lbrace=Invalid parameter type in see tag, looking for left brace {0}\: {1}
+see_tag_invalid_parameter_type_ident=Invalid parameter type in see tag, looking for identifier {0}\: {1}
+see_tag_unterminated_array_type=Unterminated array type in see tag\: {0}
+see_tag_invalid_parameter_name=Invalid parameter name in see tag\: {0}
+see_tag_invalid_parameters=Invalid paramters in see tag\: {0}
+see_tag_expecting_typename_or_whitespace:Expecting type name or white space in see tag\: {0}
+see_tag_expecting_field_name:Expecting field name after # in see tag\: {0}
+see_tag_dot_sharp_or_id:Expecting '\#', ., or identifier in see set\: {0}
+tag_invalid_link_tag=Invalid link tag\: {0}
+tag_unterminated_link_tag=Unterminated link tag\: {0}
+serialField_tag_invalid_field_name_start=Invalid start of a field name in serialField tag\: '{0}'
+serialField_tag_invalid_field_name_part=Invalid part of a field name in serialField tag\: '{0}'
+serialField_tag_invalid_type_name_start=Invalid start of a type name in serialField tag\: '{0}'
+serialField_tag_invalid_type_name_part=Invalid part of a type name in serialField tag\: '{0}'
+unterminated_html_tag=Unterminated HTML tag\: {0}
+Loading_source_file=Loading source file {0}...
+Loading_source_file_for_class=Loading source file for class {0}...
+Loading_source_files_for_package=Loading source files for package {0}...
+ioexception_open=Trouble openning file {0}
+ioexception_close=Trouble closing file {0}
+ioexception_reading=Trouble reading from file {0}
+cant_resolve_file=Cannot resolve file {0}
+file_doesnt_exist=The file {0} does not exist
+invalid_package_name:Invalid package name: {0}
+internal_msg=Please copy the following text into an email message and send it,\n\
+along with any additional information you can add to:            \n\
+                                                                 \n\
+       support@aspectj.org                                       \n\
+
+starting_internal_compile=Starting compile...
+initializing_world=Initializing world...
+creating_root=Creating root...
+generating_docs=Generating documentation...
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/rootmakers/Javadoc.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/rootmakers/Javadoc.java
new file mode 100644 (file)
index 0000000..75d3519
--- /dev/null
@@ -0,0 +1,151 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc.rootmakers;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.aspectj.tools.ajdoc.ErrPrinter;
+
+/**
+ * An abstract class for a javadoc rootmaker.
+ * Provides some error handling and misc. functionality.
+ *
+ * @author Jeff Palm
+ */
+public abstract class Javadoc {
+
+    /** Subclasses may want this ;). */
+    protected ErrPrinter err;
+
+    /** Default ctor. */
+    public Javadoc() {}
+    
+
+    /**
+     * Returns the result of invoking <code>method</code>,
+     * on target <code>owner</code>, with arguments <code>args</code>.
+     * This method handles errors that arise.
+     *
+     * @param method method to invoke.
+     * @param owner  target of the invocation.
+     * @param args   arguments to pass the method.
+     * @return       result of invoking the method on
+     *               the passed in owner with the passed in
+     *               parameters.
+     */
+    protected final Object invoke(Method method, Object owner, Object[] args) {
+        if (method == null || owner == null) return null;
+        String classname = owner.getClass().getName();
+        String methodName = method.getName();
+        try {
+            Thread.currentThread().setContextClassLoader
+                (owner.getClass().getClassLoader());
+            return method.invoke(owner, args);
+        } catch (InvocationTargetException e) {
+            err.invocationTargetException(e, classname, methodName);
+        } catch (IllegalAccessException e) {
+            err.ex(e, "method_not_accessible", classname, methodName);
+        } catch (Exception e) {
+            err.ex(e, "exception_thrown", "List",
+                   classname, methodName, e != null ? e.getMessage() : e+"");
+        }
+        return null;
+    }
+
+    /**
+     * Returns the <code>Class</code> with name <code>classname</code>.
+     * This may return null if <code>Class.forName</code> returns null,
+     * but otherwise, this method handles resulting errors.
+     *
+     * @param classname name of the class to get.
+     * @return          Class named <code>clasname</code>.
+     */
+    protected final Class type(String classname) {
+        try {
+            return Class.forName(classname);
+        } catch (ClassNotFoundException e) {
+            err.ex(e, "class_not_found", "Hashtable", classname);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the method named <code>name</code>, whose parameters
+     * are declared <code>params</code>, and which is declared
+     * in <code>type</code>.
+     *
+     * @param name   name of the method.
+     * @param params type of the parameters.
+     * @param type   type in which the resulting method is declared.
+     * @return       the method named <code>name</code>, whose parameters
+     *               are declared <code>params</code>, and which is declared
+     *               in <code>type</code>.  This may be null.
+     */
+    protected final Method method(String name, Class[] params, Class type) {
+        if (type == null) return null;
+        try {
+            return type.getMethod(name, params);
+        } catch (NoSuchMethodException e) {
+            err.ex(e, "method_not_found", type.getClass().getName(), name);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the Object resulting from default construction
+     * of a class named <code>classname</code>.  This method
+     * handles all errors that arise.
+     *
+     * @param classname class name of the resulting Object.
+     * @return          new instance made from the default
+     *                  construction of a class named
+     *                  <code>classname</code>.  This may be null.
+     * @see             #newInstance(Class)
+     */
+    protected final Object newInstance(String classname) {
+        return newInstance(type(classname));
+    }
+    
+    /**
+     * Returns the Object resulting from default construction
+     * of a class <code>type</code>.  This method
+     * handles all errors that arise.
+     *
+     * @param type Class of the resulting Object.
+     * @return     new instance made from the default
+     *             construction of a class named
+     *             <code>classname</code>.  This may be null.
+     */
+    protected final Object newInstance(Class type) {
+        if (type == null) return null;
+        try {
+            return type.newInstance();
+        } catch (InstantiationException e) {
+            err.ex(e, "must_have_default_ctor", type.getClass().getName());
+            return null;
+        } catch (IllegalAccessException e) {
+            err.ex(e, "method_not_accessible", type.getClass().getName(), "new()");
+            return null;
+        }
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/rootmakers/Javadoc13.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/rootmakers/Javadoc13.java
new file mode 100644 (file)
index 0000000..a8a3cdf
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc.rootmakers;
+
+import com.sun.javadoc.RootDoc;
+import com.sun.javadoc.DocErrorReporter;
+import java.lang.reflect.Method;
+import java.util.List;
+import org.aspectj.tools.ajdoc.AccessChecker;
+import org.aspectj.tools.ajdoc.RootDocMaker;
+import org.aspectj.tools.ajdoc.CannotMakeRootDocException;
+
+/**
+ * Makes a RootDoc using javadoc from SDK 1.3 as an example.
+ *
+ * @author Jeff Palm
+ */
+public class Javadoc13 extends Javadoc implements RootDocMaker {
+
+    public Javadoc13() {}    
+    public RootDoc makeRootDoc(String sourcepath,
+                               String classpath,
+                               String bootclasspath,
+                               String extdirs,
+                               long flags,
+                               String encoding,
+                               String locale,
+                               String source,
+                               List classesAndPackages,
+                               List options,
+                               DocErrorReporter messager,
+                               String programName,
+                               AccessChecker filter)
+        throws CannotMakeRootDocException {
+        // todo: options ignored in 13?
+        Class envClass = type("com.sun.tools.javadoc.Env");
+        if (envClass == null) return null;
+        Method create = method("create", new Class[]{String.class,
+                                                     String.class,
+                                                     String.class,
+                                                     String.class,
+                                                     int.class,
+                                                     String.class},
+                               envClass);
+        if (create == null) return null;
+        Object env = invoke(create, null, new Object[]{sourcepath,
+                                                       classpath,
+                                                       bootclasspath,
+                                                       extdirs,
+                                                       new Integer((int)flags),
+                                                       encoding});
+        if (env == null) return null;
+        
+
+        return null;
+    }
+
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/rootmakers/Javadoc14.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/ajdoc/rootmakers/Javadoc14.java
new file mode 100644 (file)
index 0000000..3846c8a
--- /dev/null
@@ -0,0 +1,273 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.ajdoc.rootmakers;
+
+//import com.sun.javadoc.RootDoc;
+//import com.sun.javadoc.DocErrorReporter;
+//
+//import java.lang.reflect.InvocationTargetException;
+//import java.lang.reflect.Constructor;
+//import java.lang.reflect.Method;
+//import java.util.Iterator;
+//import java.util.List;
+//
+//import org.aspectj.tools.ajdoc.CannotMakeRootDocException;
+//import org.aspectj.tools.ajdoc.ErrPrinter;
+//import org.aspectj.tools.ajdoc.RootDocMaker;
+//import org.aspectj.tools.ajdoc.AccessChecker;
+
+//XXX
+//import com.sun.tools.javac.v8.util.Hashtable;
+
+/**
+ * Makes a RootDoc using javadoc from SDK 1.4 as an example.
+ *
+ * @author Jeff Palm
+ */
+//public class Javadoc14 extends Javadoc implements RootDocMaker {
+//
+//    public Javadoc14() {}
+//
+//    public RootDoc makeRootDoc(String sourcepath,
+//                               String classpath,
+//                               String bootclasspath,
+//                               String extdirs,
+//                               long flags,
+//                               String encoding,
+//                               String locale,
+//                               String source,
+//                               List classesAndPackages,
+//                               List options,
+//                               DocErrorReporter docErrorReporter,
+//                               String programName,
+//                               AccessChecker filter)
+//        throws CannotMakeRootDocException {
+//        this.err = (ErrPrinter)docErrorReporter;
+//        Class hashtableClass = null;
+//        String classname = "com.sun.tools.javac.v8.util.Hashtable";
+//        try {
+//            hashtableClass = Class.forName(classname);
+//        } catch (ClassNotFoundException e) {
+//            err.ex(e, "class_not_found", "Hashtable", classname);
+//            return null;
+//        }
+//        Object hashtable = null;
+//        try {
+//            hashtable = hashtableClass.newInstance();
+//            Method put = hashtableClass.getMethod("put",
+//                                                  new Class[]{Object.class,
+//                                                              Object.class});
+//            if (sourcepath != null) {
+//                put.invoke(hashtable, new Object[]{"-sourcepath",
+//                                                   sourcepath});
+//            }
+//            if (classpath != null) {
+//                put.invoke(hashtable, new Object[]{"-classpath",
+//                                                   classpath});
+//            }
+//            if (bootclasspath != null) {
+//                put.invoke(hashtable, new Object[]{"-bootclasspath",
+//                                                   bootclasspath});
+//            }
+//            if (extdirs != null) {
+//                put.invoke(hashtable, new Object[]{"-extdirs",
+//                                                   extdirs});
+//            }
+//            if (encoding != null) {
+//                put.invoke(hashtable, new Object[]{"-encoding",
+//                                                   encoding});
+//            }
+//            if (true || (flags & 0x1) != 0) {
+//                put.invoke(hashtable, new Object[]{"-verbose",
+//                                                   ""});
+//            }
+//            if (source != null) {
+//                put.invoke(hashtable, new Object[]{"-source",
+//                                                   source});
+//            }
+//            if (filter != null) {
+//                put.invoke(hashtable, new Object[]{"-" + filter.getOption(),
+//                                                   ""});
+//            }
+//            Hashtable h = (Hashtable)hashtable;
+//            
+//        } catch (NoSuchMethodException e) {
+//            err.ex(e, "method_not_found", classname, "put");
+//            return null;
+//        } catch (InvocationTargetException e) {
+//            err.invocationTargetException(e, classname, "put");
+//            return null;
+//        } catch (InstantiationException e) {
+//            err.ex(e, "must_have_default_ctor", classname);
+//            return null;
+//        } catch (IllegalAccessException e) {
+//            err.ex(e, "method_not_accessible", classname, "new()");
+//            return null;
+//        }
+//        Class messagerClass = null;
+//        classname = "com.sun.tools.javadoc.Messager";
+//        try {
+//            messagerClass = Class.forName(classname);
+//        } catch (ClassNotFoundException e) {
+//            err.ex(e, "class_not_found", "Messager", classname);
+//            return null;
+//        }
+//        Object messager = null;
+//        try {
+//            Constructor ctor =
+//                messagerClass.getConstructor(new Class[]{String.class});
+//            messager = ctor.newInstance(new Object[]{programName});
+//        } catch (InstantiationException e) {
+//            err.ex(e, "cant_construct_object", classname);
+//            return null;            
+//        } catch (NoSuchMethodException e) {
+//            err.ex(e, "method_not_found", classname, "new(String)");
+//            return null;
+//        } catch (IllegalAccessException e) {
+//            err.ex(e, "method_not_accessible", classname, "new(String)");
+//            return null;
+//        } catch (InvocationTargetException e) {
+//            err.invocationTargetException(e, classname, "new(String)");
+//            return null;
+//        }
+//        Class javadocToolClass = null;
+//        classname = "com.sun.tools.javadoc.JavadocTool";
+//        try {
+//            javadocToolClass = Class.forName(classname);
+//        } catch (ClassNotFoundException e) {
+//            err.ex(e, "class_not_found", "JavadocTool", classname);
+//            return null;
+//        }
+//        Object javadocTool = null;
+//        try {
+//            Method make = javadocToolClass.getMethod("make",
+//                                                     new Class[]{messagerClass,
+//                                                                 hashtableClass});
+//            javadocTool = make.invoke(null, new Object[]{messager,
+//                                                         hashtable});
+//        } catch (NoSuchMethodException e) {
+//            err.ex(e, "method_not_found", classname, "make");
+//            return null;
+//        } catch (InvocationTargetException e) {
+//            err.invocationTargetException(e, classname, "make");
+//            return null;
+//        } catch (IllegalAccessException e) {
+//            err.ex(e, "method_not_accessible", classname, "make");
+//            return null;
+//        } catch (Exception e) {
+//            err.ex(e, "exception_thrown", "JavadocTool",
+//                      classname, "make", e != null ? e.getMessage() : e+"");
+//            return null;
+//        }
+//        Class modifierFilterClass = null;
+//        classname = "com.sun.tools.javadoc.ModifierFilter";
+//        try {
+//            modifierFilterClass = Class.forName(classname);
+//        } catch (ClassNotFoundException e) {
+//            err.ex(e, "class_not_found", "ModifierFilter", classname);
+//            return null;
+//        }
+//        Object modifierFilter = null;
+//        classname = "com.sun.tools.javadoc.ModifierFilter";
+//        try {
+//            Constructor ctor =
+//                modifierFilterClass.getConstructor(new Class[]{long.class});
+//            modifierFilter = ctor.newInstance(new Object[]{new Long(flags)});
+//        } catch (InstantiationException e) {
+//            err.ex(e, "cant_construct_object", classname);
+//            return null;            
+//        } catch (NoSuchMethodException e) {
+//            err.ex(e, "method_not_found", classname, "new()");
+//            return null;
+//        } catch (IllegalAccessException e) {
+//            err.ex(e, "method_not_accessible", classname, "new()");
+//            return null;
+//        } catch (InvocationTargetException e) {
+//            err.invocationTargetException(e, classname, "new()");
+//            return null;
+//        }
+//        Class listClass = null;
+//        classname = "com.sun.tools.javac.v8.util.List";
+//        try {
+//            listClass = Class.forName(classname);
+//        } catch (ClassNotFoundException e) {
+//            err.ex(e, "class_not_found", "List", classname);
+//            return null;
+//        }
+//        RootDoc rootDoc = null;
+//        classname = "com.sun.tools.javadoc.JavadocTool";
+//        try {
+//            Method getRootDocImpl =
+//                javadocToolClass.getMethod("getRootDocImpl",
+//                                           new Class[]{String.class,
+//                                                       modifierFilterClass,
+//                                                       listClass,
+//                                                       listClass});
+//            Object classesOrPackageList = list(classesAndPackages, listClass);
+//            Object optionsList = list(options, listClass);
+//
+//            rootDoc =
+//                (RootDoc)getRootDocImpl.invoke(javadocTool,
+//                                               new Object[]{locale,
+//                                                            modifierFilter,
+//                                                            classesOrPackageList,
+//                                                            optionsList});
+//        } catch (NoSuchMethodException e) {
+//            err.ex(e, "method_not_found", classname, "getRootDocImpl");
+//            return null;
+//        } catch (InvocationTargetException e) {
+//            err.invocationTargetException(e, classname, "getRootDocImpl");
+//            return null;
+//        } catch (IllegalAccessException e) {
+//            err.ex(e, "method_not_accessible", classname, "getRootDocImpl");
+//            return null;
+//        } catch (ClassCastException e) {
+//            err.ex(e, "class_cast_exception", "getRootDocImpl", classname,
+//                      "com.sun.javadoc.RootDoc",
+//                      rootDoc == null ? "" : rootDoc.getClass().getName());
+//            return null;
+//        }
+//        return rootDoc;
+//    }
+//
+//
+//    private final Object list(List list, Class listClass) {
+//        if (listClass == null) return null;
+//        Object newlist = newInstance(listClass);
+//        if (newlist == null) return null;
+//        if (list == null) return newlist;
+//        Class listBufferClass = type("com.sun.tools.javac.v8.util.ListBuffer");
+//        if (listBufferClass == null) return newlist;
+//        Object listBuffer = newInstance(listBufferClass);
+//        if (listBuffer == null) return newlist;
+//        Method append = method("append", new Class[]{Object.class},listBufferClass);
+//        if (append == null) return newlist;
+//        for (Iterator i = list.iterator(); i.hasNext();) {
+//            invoke(append, listBuffer, new Object[]{i.next()});
+//        }
+//
+//        Method toList = method("toList", new Class[]{}, listBufferClass);
+//        if (toList == null) return newlist;
+//        newlist = invoke(toList, listBuffer, new Object[]{});
+//        return newlist;
+//    }
+//}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractIndexWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractIndexWriter.java
new file mode 100644 (file)
index 0000000..4adc294
--- /dev/null
@@ -0,0 +1,85 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.IntroducedDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.tools.doclets.IndexBuilder;
+
+import java.io.IOException;
+
+public class AbstractIndexWriter
+    extends com.sun.tools.doclets.standard.AbstractIndexWriter
+{
+
+    protected AbstractIndexWriter(String path,
+                                  String filename, 
+                                  String relativePath,
+                                  IndexBuilder indexbuilder) 
+                                  throws IOException {
+        super(path, filename, relativePath, indexbuilder);
+    }
+
+    protected AbstractIndexWriter(String filename,
+                                  IndexBuilder indexbuilder) 
+                                  throws IOException {
+        super(filename, indexbuilder);
+    }
+
+    protected void printClassInfo(ClassDoc cd) {
+        if (cd instanceof AspectDoc) {
+            print("aspect ");
+            printPreQualifiedClassLink(cd);
+            print('.');
+        } else {
+            super.printClassInfo(cd);
+        }
+    }
+
+    protected void printMemberDesc(MemberDoc member) {
+        String classdesc =  Statics.type(member.containingClass()) + " " +
+            getPreQualifiedClassLink(member.containingClass());
+        if (member instanceof org.aspectj.ajdoc.MemberDoc) {
+            org.aspectj.ajdoc.MemberDoc md = (org.aspectj.ajdoc.MemberDoc)member;
+            if (md.isAdvice()) {
+                printText("doclet.Advice_in", classdesc);
+            } else if (md.isPointcut()) {
+                printText("doclet.Pointcut_in", classdesc);
+            }
+        } else {
+            super.printMemberDesc(member);
+        }
+        if (member instanceof org.aspectj.ajdoc.MemberDoc) {
+            IntroducedDoc intro =
+                ((org.aspectj.ajdoc.MemberDoc)member).introduced();
+            if (intro != null) {
+                print(' ');
+                printText("doclet.introduced_by",
+                          Statics.type(intro.containingClass()) + " " +
+                          getPreQualifiedClassLink(intro.containingClass()));
+            }
+        }
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractStandard.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractStandard.java
new file mode 100644 (file)
index 0000000..e490eab
--- /dev/null
@@ -0,0 +1,477 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AspectDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.DocErrorReporter;
+import com.sun.javadoc.PackageDoc;
+import com.sun.javadoc.RootDoc;
+import com.sun.tools.doclets.ClassTree;
+import com.sun.tools.doclets.DocletAbortException;
+import com.sun.tools.doclets.HtmlDocWriter;
+import com.sun.tools.doclets.IndexBuilder;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+
+/**
+ * An abstract allowing one to customize the writers
+ * used in ajdoc.  Subclasses should define the three
+ * generate methods to specify the documentation made.
+ *
+ * @see #preGenerationClasses()
+ * @see #postGenerationClasses()
+ * @see #checkClasses()
+ * @author Jeff Palm
+ */
+public abstract class AbstractStandard 
+    extends com.sun.tools.doclets.standard.Standard {
+
+    // todo wes removed restriction, but implemented Standard as singleton via proxy
+    private static int refCount = 0;
+    {
+        if (refCount > 0) {
+            System.err.println("Warning: " + refCount + " AbstractStandard already ");
+        }
+        refCount++;
+    }
+
+    /**
+     * The ClassTree that is available to subclasses and it gaurateed
+     * to be created before pre-generating classes.
+     */
+    protected ClassTree classtree;
+    
+    protected static boolean start(AbstractStandard as,
+                                   RootDoc root) throws IOException {
+        try {
+            as.getConfiguration().setOptions(root);
+            as.startGeneration(root);
+        } catch (DocletAbortException exc) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns the types of {@link Pass}es that will
+     * run before generating classes.
+     *
+     * @return an array of Class, where each entry
+     *         is a subclass of {@link Pass}, ordered
+     *         to run directly before generating the
+     *         classes.
+     */
+    protected abstract Class[] preGenerationClasses();
+
+    /**
+     * Returns the types of {@link Pass}es that will
+     * run after generating classes.
+     *
+     * @return an array of Class, where each entry
+     *         is a subclass of {@link Pass}, ordered
+     *         to run directly after generating the
+     *         classes.
+     */
+    protected abstract Class[] postGenerationClasses();
+
+    /**
+     * Returns the types of {@link CheckPass}es that will
+     * run to check the classes.
+     *
+     * @return an array of Class, where each entry
+     *         is a subclass of {@link CheckPass}, ordered
+     *         to run in order to check the classes passed
+     *         into the class generation phase.
+     */
+    protected abstract Class[] checkClasses();
+
+    /**
+     * Return the configuration used by a subclass.  This
+     * allows the subclass to specify it's own kind.
+     *
+     * @return a customized configuration.
+     */
+    public abstract ConfigurationStandard getConfiguration();
+
+    protected ConfigurationStandard makeConfiguration() {
+        return new ConfigurationStandard();
+    }
+
+
+    /**
+     * Returns the configuration, and ensures that
+     * HtmlDocWriter.configuration is of the type used by
+     * this class.
+     *
+     * @return the current instanceof ConfigurationStandard being
+     *         used and creates one if needed.  This will <b>not</b>
+     *         be null.
+     */
+    // todo these are the heinous globals that impose one process per classloader
+    public static com.sun.tools.doclets.standard.ConfigurationStandard
+        configuration() {
+        if (HtmlDocWriter.configuration == null ||
+            !(HtmlDocWriter.configuration instanceof ConfigurationStandard)) {
+            HtmlDocWriter.configuration = new ConfigurationStandard();
+            //TODO: change to makeConfiguration()
+        }
+        return (ConfigurationStandard)HtmlDocWriter.configuration;
+    }
+
+    /**
+     * Creates and returns an IndexBuilder that includes aspects.
+     *
+     * @param root        RootDoc to pass the new IndexBuilder.
+     * @param classesOnly <code>true</code> if only classes
+     *                    should be included.
+     * @return            an IndexBuilder that includes aspects.
+     */
+    protected IndexBuilder indexBuilder(RootDoc root, boolean classesOnly) {
+        class MyIndexBuilder extends IndexBuilder {
+            public MyIndexBuilder(RootDoc r, boolean n) {
+                super(r, n);
+            }
+            public MyIndexBuilder(RootDoc r, boolean n, boolean b) {
+                super(r, n, b);
+            }
+            protected void putMembersInIndexMap(ClassDoc classdoc) {
+                super.putMembersInIndexMap(classdoc);
+                if (classdoc instanceof org.aspectj.ajdoc.ClassDoc) {
+                    org.aspectj.ajdoc.ClassDoc cd =
+                        (org.aspectj.ajdoc.ClassDoc)classdoc;
+                    adjustIndexMap(cd.pointcuts());
+                    if (cd instanceof AspectDoc) {
+                        adjustIndexMap(((AspectDoc)cd).advice());
+                    }
+                }
+            }
+        }
+        return new MyIndexBuilder(root, configuration().nodeprecated, classesOnly);
+    }
+
+
+    /**
+     * Does the work in generating the documentation.
+     * First, call all the passes return from {@link #generateCheckPasses}
+     * them perform some copying.  Second build the classtree, run the
+     * pre-classgeneration passes, generate the packages, generate the
+     * classes, then call all the postGenerationClasses.
+     *
+     * @param root the root of the documentation.
+     */
+    protected void startGeneration(RootDoc root) throws DocletAbortException {
+
+        if (!generateCheckPasses(getConfiguration(), root)) return;
+
+        performCopy(getConfiguration().destdirname,
+                    getConfiguration().helpfile);
+        performCopy(getConfiguration().destdirname,
+                    getConfiguration().stylesheetfile);
+
+        classtree = new ClassTree(root, getConfiguration().nodeprecated);
+
+        generatePrePasses(getConfiguration(), root);
+
+        generatePackageCycle(getConfiguration().packages,
+                             getConfiguration().createtree,
+                             getConfiguration().nodeprecated);
+         generateClassFiles(root, classtree);
+        generatePostPasses(getConfiguration(), root);
+    }
+
+    /**
+     * A class representing a single pass in the generation cycles.  It
+     * does some of the dirty work for you.
+     */
+    public static abstract class Pass {
+
+        /** The root available to this pass. */
+        protected RootDoc root;
+
+        /** The configuration available to this pass. */
+        protected ConfigurationStandard cs;
+
+        /** The doclet available to this pass. */
+        protected AbstractStandard std;
+        
+        public Pass() {}
+
+        /**
+         * Returns the title of the pass for logging.
+         *
+         * @return the unique title of this pass.  This can
+         *         be <code>null</code> to disable display.
+         */
+        public abstract String title();
+
+        /**
+         * Do the generation work.  All instance variables
+         * are guaranteed to be set.
+         */
+        protected abstract void gen() throws DocletAbortException;
+
+        /**
+         * Do the actual generation if {@link #cond} returns
+         * <code>true</code>.  Do some other logging, too.
+         *
+         * @param std  the AbstractStandard to use.
+         * @param cs   the ConfigurationStandard to use.
+         * @param root the RootDoc to use.
+         */
+        public final void generate(AbstractStandard std,
+                                   ConfigurationStandard cs,
+                                   RootDoc root)
+            throws DocletAbortException {
+            this.std = std;
+            this.cs = cs;
+            this.root = root;
+            if (cond()) {
+                String title = title();
+                long start = System.currentTimeMillis();
+                if (cs.log && title != null) {
+                    cs.standardmessage.notice("doclet.pass_msg", title);
+                }
+                gen();
+                if (cs.log && title != null) {
+                    long stop = System.currentTimeMillis();
+                    cs.standardmessage.notice("doclet.done_msg",
+                                              title, (stop-start)+"");
+                }
+            }
+        }
+
+        /**
+         * Returns whether the generation should proceed.  Override
+         * this method for conditional passes.
+         *
+         * @return <code>true</code> is this pass shoulud proceed.
+         */
+        protected boolean cond() {
+            return true;
+        }
+    }
+
+    /**
+     * A convenience class for doing checks.
+     */
+    public abstract static class Check extends Pass {
+
+        /**
+         * Returns the error message if check fails.
+         *
+         * @return error message if check fails.
+         */
+        protected abstract String message();
+
+        /**
+         * Returns whether check has failed or not.
+         *
+         * @return <code>true</code> is check fails.
+         */
+        protected abstract boolean cond();
+
+        /**
+         * Prints message, because we've failed and throws
+         * a DocletAbortException to notify the doclet
+         * that we've failed.
+         */
+        protected void gen() throws DocletAbortException {
+            cs.standardmessage.error(message());
+            throw new DocletAbortException();
+        }
+
+        /**
+         * Returns null, because we don't want to be displayed.
+         *
+         * @return <code>null</code>.
+         */
+        public String title() { return null; }
+    }
+
+    /**
+     * Generates the passes to run before generating the classes.
+     */
+    private final void generatePrePasses(ConfigurationStandard cs,
+                                         RootDoc root)
+        throws DocletAbortException {
+        generatePasses(cs, root, preGenerationClasses());
+    }
+
+    /**
+     * Generates the passes to run after generating the classes.
+     */
+    private final void generatePostPasses(ConfigurationStandard cs,
+                                          RootDoc root)
+        throws DocletAbortException {
+        generatePasses(cs, root, postGenerationClasses());
+    }
+
+    /**
+     * Generates the passes that run before doing anything.  These
+     * passes check that it's OK to do anything.
+     */
+    private final boolean generateCheckPasses(ConfigurationStandard cs,
+                                              RootDoc root)
+        throws DocletAbortException {
+        try {
+            generatePasses(cs, root, checkClasses());
+        } catch (DocletAbortException e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Generates passes from <code>classes</code>.  For each
+     * class found in <code>classes</code> a constructor taking zero
+     * or one-argument is called.  Then the generate method is
+     * called on that Pass passing it <code>this</code>, the
+     * configuration, and root.
+     *
+     * @param cs      configuration to use.
+     * @param root    root we're documenting.
+     * @param classes list of subtypes of {@link Pass} that
+     *                will be run.
+     */
+    private final void generatePasses(ConfigurationStandard cs,
+                                      RootDoc root,
+                                      Class[] classes)
+        throws DocletAbortException {
+        if (classes == null) return;
+        nextClass:
+        for (int i = 0; i < classes.length; i++) {
+            try {
+                Constructor[] ctrs = classes[i].getConstructors();
+            nextCtr:
+                for (int j = 0; j < ctrs.length; j++) {
+                    Pass pass = null;
+                    if (ctrs[j].getParameterTypes().length == 0) {
+                        pass = (Pass)ctrs[j].newInstance(new Object[]{});
+                    } else if (ctrs[j].getParameterTypes().length == 1) {
+                        pass = (Pass)ctrs[j].newInstance(new Object[]{this});
+                    }
+                    if (pass != null) {
+                        pass.generate(this,cs,root);
+                        continue nextClass;
+                    }
+                }
+                throw new Exception("Can't create pass for class " + classes[i]);
+            } catch (Exception e) {
+                e.printStackTrace();
+                Standard.configuration().standardmessage.
+                    error("doclet.exception", e+"");
+                throw new DocletAbortException();
+            }
+        }
+    }
+
+
+    /**
+     * Generates the packages.
+     */
+    protected void generatePackageCycle(PackageDoc[] pkgs,
+                                        boolean createtree,
+                                        boolean nodeprecated)
+        throws DocletAbortException {
+        Arrays.sort(pkgs);
+        for (int i = 0; i < pkgs.length; i++) {
+            PackageDoc prev = i == 0 ? null : pkgs[i-1];
+            PackageDoc curr = pkgs[i];
+            PackageDoc next = i == pkgs.length-1 ? null : pkgs[i+1];
+            generatePackages(prev, curr, next,
+                             createtree, nodeprecated);
+        }
+    }
+
+    /**
+     * Generates a package doc for the three PackageDocs passed.
+     */
+    protected void generatePackages(PackageDoc prev,
+                                    PackageDoc curr,
+                                    PackageDoc next,
+                                    boolean createtree,
+                                    boolean nodeprecated)
+        throws DocletAbortException {
+        PackageWriter.generate(curr, prev, next);
+        if (createtree) {
+            PackageTreeWriter.generate(curr, prev,
+                                       next, nodeprecated);
+        }
+        PackageFrameWriter.generate(curr);
+    }
+
+    /**
+     * Generates all the classes.
+     */
+    protected void generateClassCycle(ClassDoc[] cs,
+                                      ClassTree classtree,
+                                      boolean nopackage)
+        throws DocletAbortException {
+        Arrays.sort(cs);
+        for(int i = 0; i < cs.length; i++) {
+            if (configuration().nodeprecated && 
+                cs[i].tags("deprecated").length > 0) {
+                continue;
+            }
+            ClassDoc prev = i == 0 ? null : cs[i-1];
+            ClassDoc curr = cs[i];
+            ClassDoc next = i == cs.length-1 ? null : cs[i+1];
+            generateClasses(prev, curr, next,
+                            classtree, nopackage);
+        }
+    }
+
+    /**
+     * Generates class docs for the three ClassDocs passed.
+     */
+    protected void generateClasses(ClassDoc  prev,
+                                   ClassDoc  curr,
+                                   ClassDoc  next,
+                                   ClassTree classtree,
+                                   boolean nopackage)
+        throws DocletAbortException {
+        ClassWriter.generate(curr, prev, next,
+                             classtree, nopackage);
+    }
+
+    /**
+     * Returns the delegation to {@link #configuration()}.
+     */
+    public static int optionLength(String option) {
+        return configuration().optionLength(option);
+    }
+
+    /**
+     * Returns the delegation to {@link #configuration()}.
+     */
+    public static boolean validOptions(String options[][], 
+                                       DocErrorReporter reporter) 
+        throws IOException {
+        return configuration().validOptions(options, reporter);
+    }
+} 
+        
+
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractSubWriter.java
new file mode 100644 (file)
index 0000000..dbb0d96
--- /dev/null
@@ -0,0 +1,393 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.IntroducedDoc;
+import org.aspectj.tools.ajdoc.Access;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ProgramElementDoc;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+
+public class AbstractSubWriter
+    extends com.sun.tools.doclets.standard.AbstractSubWriter
+    implements AbstractSubWriterAJ
+{
+
+    public AbstractSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+         ClassDoc classdoc)
+    {
+        super(writer, classdoc);
+    }
+
+    public AbstractSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+
+    public final void printSummaryMember(ClassDoc cd, ProgramElementDoc member) {
+        writer.printSummaryLinkType(this, member);
+        printSummaryLink(cd, member);
+        printSummaryLinkComment(member);
+    }
+    
+    protected final void printCrosscuts(ProgramElementDoc member) {
+        if (hasCrosscuts(classdoc, member)) {
+            writer.dl();
+            writer.dd();
+            printCrosscuts(classdoc, member);
+            writer.ddEnd();
+            writer.dlEnd();
+        }
+    }
+    
+    protected /*abstract*/ Class delegateClass() { throw new RuntimeException(""); }
+    /*final*/ private com.sun.tools.doclets.standard.AbstractSubWriter del;
+    { setDelegator(); }
+    protected final void setDelegator() {
+        com.sun.tools.doclets.standard.AbstractSubWriter mw = null;
+        try {
+            List list = new ArrayList();
+            if (writer != null) list.add(writer);
+            if (classdoc != null) list.add(classdoc);
+            setDelegator(mw = findDelegate
+                         (list.toArray
+                          (new Object[list.size()])));
+        } finally {
+            del = mw;
+        }
+    }
+    public final com.sun.tools.doclets.standard.AbstractSubWriter del() {
+        return del;
+    }
+    private final void setDelegator(Object o) {
+        if (o == null) return;
+        try {
+            Method[] ms = o.getClass().getMethods();
+            for (int i = 0; i < ms.length; i++) {
+                if (ms[i].getName().equals("setDelegator")) {
+                    ms[i].invoke(o, new Object[]{this});
+                }
+            }
+        } catch (Exception e) {
+            Standard.configuration().standardmessage.
+                error("doclet.exception_encountered", e+"");
+        }
+    }
+    private final com.sun.tools.doclets.standard.AbstractSubWriter
+        findDelegate(Object[] params) {
+        if (delegateClass() == null) {
+            return this;
+        }
+        try {
+            Constructor[] cs = delegateClass().getConstructors();
+            for (int i = 0; i < cs.length; i++) {
+                if (cs[i].getParameterTypes().length == params.length) {
+                    return (com.sun.tools.doclets.standard.AbstractSubWriter)
+                        cs[i].newInstance(params);
+                }
+            }
+        } catch (Exception e) {
+            Standard.configuration().standardmessage.
+                error("doclet.exception_encountered", e+"");
+        }
+        return null;
+    }
+
+    public int getMemberKind() {
+        return -1;
+    }
+    public void printSummaryLabel(ClassDoc cd) {
+        if (keyName() != null) {
+            summaryLabel(keyName());
+        } else {
+            del.printSummaryLabel(cd);
+        }
+    }
+    public void printSummaryAnchor(ClassDoc cd) {
+        if (keyName() != null) {
+            summaryAnchor(keyName());
+        } else {
+            del.printSummaryAnchor(cd);
+        }
+    }
+    public void printInheritedSummaryAnchor(ClassDoc cd) {
+        del.printInheritedSummaryAnchor(cd);
+    }
+    protected void printSummaryType(ProgramElementDoc member) {
+        Access.printSummaryType(this, member);
+    }
+    protected void printSummaryLink(ClassDoc cd,
+                                    ProgramElementDoc member) {
+        Access.printSummaryLink(this, cd, member);
+    }
+    protected void printInheritedSummaryLink(ClassDoc cd, 
+                                             ProgramElementDoc member) {
+        Access.printInheritedSummaryLink(this, cd, member);
+    }
+    protected void printHeader(ClassDoc cd) {
+        if (keyName() != null) {
+            header(keyName());
+        } else {
+            Access.printHeader(this, cd);
+        }
+    }
+    protected void printBodyHtmlEnd(ClassDoc cd) {
+        Access.printBodyHtmlEnd(this, cd);
+    }
+    protected final void printMember(ProgramElementDoc elem) {
+        nonfinalPrintMember(elem);
+        printCrosscuts(elem);
+    }
+    protected void nonfinalPrintMember(ProgramElementDoc elem) {
+        Access.printMember(this, elem);
+    }
+    protected void printDeprecatedLink(ProgramElementDoc member) {
+        Access.printDeprecatedLink(this, member);
+    }
+    protected void printNavSummaryLink(ClassDoc cd, boolean link) {
+        if (keyName() != null) {
+            navSummaryLink(cd, keyName(), link);
+        } else {
+            Access.printNavSummaryLink(this, cd, link);
+        }
+    }
+    protected void printNavDetailLink(boolean link) {
+        if (keyName() != null) {
+            navDetailLink(keyName(), link);
+        } else {
+            Access.printNavDetailLink(this, link);
+        }
+    }
+
+    protected /*abstract*/ String propertyName() { return keyName(); }
+    protected /*abstract*/ String keyName() { return null; }
+    protected final String lowercase() {
+        String str = propertyName();
+        return str == null || str.length() == 0 ? "" :
+            Character.toLowerCase(str.charAt(0)) +
+            str.substring(1);
+    }
+    public void printInheritedSummaryLabel(ClassDoc cd) {
+        summaryLabel("Inherited_From", cd);
+    }
+    public void printIntroducedSummaryLabel(ClassDoc cd) {
+        summaryLabel("Introduced_From", cd);
+    }
+    public void printIntroducedSummaryAnchor(ClassDoc cd) {
+        summaryAnchor("introduced_from_class", cd);
+    }
+    protected final void summaryLabel(String keyName) {
+        writer.boldText("doclet." + keyName + "_Summary");
+    }
+    protected final void summaryAnchor(String keyName) {
+        writer.anchor(keyName.toLowerCase() + "_summary");
+    }
+    protected final void summaryLabel(String type, ClassDoc cd) {
+        writer.bold();
+        writer.printText("doclet." + propertyName() + "s_" + type,
+                         Statics.type(cd),
+                         writer.getPreQualifiedClassLink(cd));
+        writer.boldEnd();
+    }
+    protected final void summaryAnchor(String type, ClassDoc cd) {
+        writer.anchor(lowercase() + "s_" + type + "_" + cd.qualifiedName());
+    }
+    protected final String navKey(String keyName) {
+        return "doclet.nav" + keyName;
+    }
+    protected final String navKey() {
+        return navKey(keyName());
+    }
+    protected final void navLink(ClassDoc cd, String keyName,
+                                 boolean link, String kind) {
+        if (link) {
+            writer.printHyperLink
+                ("",
+                 cd == null ?
+                 keyName.toLowerCase() + "_" + kind :
+                 keyName.toLowerCase() + "s_inherited_from_class_" +
+                 cd.qualifiedName(),
+                 writer.getText(navKey(keyName)));
+        } else {
+            writer.printText(navKey(keyName));
+        }
+    }
+    protected final void navSummaryLink(ClassDoc cd, String keyName, boolean link) {
+        navLink(cd, keyName, link, "summary");
+    }
+    protected final void navDetailLink(String keyName, boolean link) {
+        navLink(null, keyName, link, "detail");
+    }
+    protected final void header(String keyName) {
+        writer.anchor(keyName.toLowerCase() + "_detail");
+        writer.printTableHeadingBackground
+            (writer.getText("doclet." + keyName + "_Detail"));
+    }
+    
+    public void printCrosscuts(ClassDoc cd, ProgramElementDoc member) {}
+    public void printSummaryCrosscuts(ClassDoc cd, ProgramElementDoc member) {}
+    public boolean hasCrosscuts(ClassDoc cd,ProgramElementDoc member) {
+        return false;
+    }
+
+    protected void printHead(String name) {
+        writer.h3();
+        writer.print(name);
+        writer.h3End();
+    }
+
+    protected List nointros(List members) {
+        List list = new ArrayList();
+        for (Iterator i = members.iterator(); i.hasNext();) {
+            Object o = i.next();
+            if (o instanceof org.aspectj.ajdoc.MemberDoc) {
+                IntroducedDoc intro =
+                    ((org.aspectj.ajdoc.MemberDoc)o).introduced();
+                if (intro == null || intro.containingClass().equals(classdoc)) {
+                    list.add(o);
+                }
+            } else {
+                list.add(o);
+            }
+        }
+        return list;
+    }
+
+    public void printMembersSummary() {
+        nointros = true;
+        super.printMembersSummary();
+        nointros = false;
+    }
+
+    protected final void printSummaryLinkComment(ProgramElementDoc member) {
+        writer.codeEnd();
+        writer.println();
+        writer.br();
+        Access.printCommentDef(this, member);
+        boolean newline = member.tags("deprecated").length +
+            member.firstSentenceTags().length > 0;
+        if (classdoc != null || true) { // ?? always
+            if (hasCrosscuts(classdoc, member)) {
+                if (newline) {
+                    writer.br();
+                    writer.printNbsps();
+                }
+                printSummaryCrosscuts(classdoc, member);
+            }
+        }
+        writer.summaryRowEnd();
+        writer.trEnd();        
+    }
+
+    public void printIntroducedSummaryHeader(ClassDoc cd) {
+            printIntroducedSummaryAnchor(cd);
+            writer.tableIndexSummary();
+            writer.tableInheritedHeaderStart("#EEEEFF");
+            printIntroducedSummaryLabel(cd);
+            writer.tableInheritedHeaderEnd();
+            writer.trBgcolorStyle("white", "TableRowColor");
+            writer.summaryRow(0);
+            writer.code();
+    }
+    
+    public void printIntroducedSummaryFooter(ClassDoc cd) {
+            writer.codeEnd();
+            writer.summaryRowEnd();
+            writer.trEnd(); 
+            writer.tableEnd();
+            writer.space();
+    }
+    
+    public void printIntroducedSummaryMember(ClassDoc cd,
+                                             ProgramElementDoc member) {
+        printIntroducedSummaryLink(cd, member);
+    }
+    
+    public void printIntroducedSummaryLink(ClassDoc cd,
+                                           ProgramElementDoc member) {}
+    public void printIntroducedMembersSummary() {
+        Map typesToMembers = new HashMap();
+        for (Iterator i = members(classdoc).iterator(); i.hasNext();) {
+            Object o = i.next();
+            if (!(o instanceof org.aspectj.ajdoc.MemberDoc)) continue;
+            org.aspectj.ajdoc.MemberDoc md = (org.aspectj.ajdoc.MemberDoc)o;
+            if (md.introduced() != null) {
+                ClassDoc cd = md.introduced().containingClass();
+                List members = (List)typesToMembers.get(cd);
+                if (members == null) members = new ArrayList();
+                members.add(md);
+                typesToMembers.put(cd, members);
+            }
+        }
+        for (Iterator i = typesToMembers.keySet().iterator(); i.hasNext();) {
+            ClassDoc cd = (ClassDoc)i.next();
+            printIntroducedSummaryHeader(cd);
+            List members = (List)typesToMembers.get(cd);
+            Collections.sort(members);
+            for (Iterator j = members.iterator(); j.hasNext();) {
+                printIntroducedSummaryMember(cd, (ProgramElementDoc)j.next());
+                if (j.hasNext()) print(", ");
+            }
+            printIntroducedSummaryFooter(cd);
+        }
+    }
+
+
+    private boolean nointros = false;
+    public void printMembers() {
+        nointros = true;
+        super.printMembers();
+        nointros = false;
+    }
+
+    public void navSummaryLink() {
+        nointros = true;
+        super.navSummaryLink();
+        nointros = false;
+    }
+        
+    protected void navDetailLink() {
+        printNavDetailLink(members(classdoc).size() > 0 ? true : false);
+    }
+    
+    public final List members(ClassDoc cd) {
+        return nointros ? nointros(getMembers(cd)) : getMembers(cd);
+    }
+    
+    protected List getMembers(ClassDoc cd) {
+        return super.members(cd);
+    }
+}  
+    
+    
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractSubWriterAJ.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractSubWriterAJ.java
new file mode 100644 (file)
index 0000000..75d114e
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ProgramElementDoc;
+
+public interface AbstractSubWriterAJ {
+    public void printCrosscuts(ClassDoc cd, ProgramElementDoc member);
+    public void printSummaryCrosscuts(ClassDoc cd, ProgramElementDoc member);
+    public boolean hasCrosscuts(ClassDoc cd, ProgramElementDoc member);
+    public void printIntroducedSummaryAnchor(ClassDoc cd); 
+    public void printIntroducedSummaryLabel(ClassDoc cd); 
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractTreeWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AbstractTreeWriter.java
new file mode 100644 (file)
index 0000000..504eb44
--- /dev/null
@@ -0,0 +1,104 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AspectDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.PackageDoc;
+import com.sun.tools.doclets.ClassTree;
+import com.sun.tools.doclets.DocletAbortException;
+
+import java.io.IOException;
+import java.util.List;
+
+public class AbstractTreeWriter 
+    extends com.sun.tools.doclets.standard.AbstractTreeWriter
+{
+
+    protected boolean seenAspect = false;
+    protected boolean aspectMode = false;
+    
+    protected AbstractTreeWriter(String filename, ClassTree classtree) 
+        throws IOException, DocletAbortException {
+        super(filename, classtree);
+    }
+    
+    protected AbstractTreeWriter(String path, String filename, 
+                                 ClassTree classtree, PackageDoc pkg) 
+        throws IOException, DocletAbortException {
+        super(path, filename, classtree, pkg);
+    }
+   
+    protected void generateLevelInfo(ClassDoc parent, List list) {
+        if (list.size() > 0) {
+            ul();
+            for (int i = 0; i < list.size(); i++) {
+                ClassDoc local = (ClassDoc)list.get(i);
+                boolean isAspect = local instanceof org.aspectj.ajdoc.AspectDoc;
+                if (aspectMode) {
+                    if (!local.qualifiedTypeName().equals("java.lang.Object")
+                        && !isAspect) {
+                        continue;
+                    }
+                } else if (isAspect) {
+                    continue;
+                }
+                printPartialInfo(local);
+                printExtendsImplements(parent, local);
+                generateLevelInfo(local, classtree.subs(local));
+            }
+            ulEnd();
+        }
+    }
+
+    protected void printExtendsImplements(ClassDoc parent, ClassDoc cd) {
+        super.printExtendsImplements(parent, cd);
+        if (cd instanceof AspectDoc) {
+            printDominationInfo(((AspectDoc)cd).dominatees(), "dominates");
+            printDominationInfo(((AspectDoc)cd).dominators(), "dominated by");
+        }
+    }
+
+    protected void printDominationInfo(AspectDoc[] aspects,
+                                       String whosOnTop) {
+        if (aspects != null && aspects.length > 0) {
+            print(" (" + whosOnTop + " ");
+            for (int i = 0; i < aspects.length; i++) {
+                if (i > 0) print(", ");
+                printPreQualifiedClassLink(aspects[i]);
+            }
+            print(")");
+        }
+    }
+
+
+    protected void generateTree(List list, String heading) {
+        super.generateTree(list, heading);
+        if (heading.equals("doclet.Class_Hierarchy")) {
+            aspectMode = true;
+            generateTree(list, "doclet.Aspect_Hierarchy");
+            aspectMode = false;
+        }
+    }           
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AdviceSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/AdviceSubWriter.java
new file mode 100644 (file)
index 0000000..02b56dd
--- /dev/null
@@ -0,0 +1,273 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AdviceDoc;
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.tools.ajdoc.Access;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ExecutableMemberDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.javadoc.ProgramElementDoc;
+import com.sun.javadoc.Tag;
+import com.sun.javadoc.Type;
+import com.sun.tools.doclets.Util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+public class AdviceSubWriter extends ExecutableMemberSubWriter {
+
+    protected Class delegateClass() {
+        return MethodSubWriter.class;
+    }
+
+    public AdviceSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+         AspectDoc aspectdoc)
+    {
+        super(writer, aspectdoc);
+    }
+
+    public AdviceSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+
+    protected final String keyName() { return "Advice"; }
+   
+    protected String where(ProgramElementDoc member) {
+        return getWhere(classdoc, member);
+    }
+    
+    public static String getWhere(ClassDoc cd, ProgramElementDoc member) {
+        return getName(cd, (AdviceDoc)member).replace(' ','_').replace('#','-');
+    }
+
+    protected void printSummaryType(ProgramElementDoc member) {
+        AdviceDoc advice = (AdviceDoc)member;
+        printModifiers(advice);
+    }
+
+    protected void printReturnTag(Tag[] returnsTag) {
+        if (returnsTag.length > 0) {
+            writer.dt();
+            writer.boldText("doclet.Returns");
+            writer.dd();
+            writer.printInlineComment(returnsTag[0]);
+        }
+    }
+
+    protected void printTagsInfoHeader() {
+        writer.dd();
+        writer.dl();
+    }
+
+    protected void printTagsInfoFooter() {
+        writer.dlEnd();
+        writer.ddEnd();
+    }
+
+    protected void printSignature(ExecutableMemberDoc member) {
+        AdviceDoc advice = (AdviceDoc)member;
+        writer.displayLength = 0;
+        writer.pre();
+        printReturnType(advice);
+        bold(advice.name());
+        printParameters(advice);
+        if (advice.isThrowing()) {
+            writer.print(" throwing ");
+            printExtraType(advice.extraType());
+        }
+        if (advice.isReturning()) {
+            writer.print(" returning ");
+            printExtraType(advice.extraType());
+        }
+        writer.preEnd();
+    }
+
+    protected void printExtraType(Type type) {
+        print(' ');
+        print('(');
+        if (type != null) {
+            printTypeLink(type);
+        }
+        print(')');
+    }
+
+    public static String getName(ClassDoc cd, AdviceDoc advice) {
+        String name = advice.name();
+        int num = 1;
+        for (Iterator i = staticMembers(cd).iterator(); i.hasNext();) {
+            AdviceDoc ad = (AdviceDoc)i.next();
+            if (ad.equals(advice)) {
+                break;
+            }
+            if (ad.name().equals(name)) {
+                num++;
+            }
+        }
+        return name + " #" + num;
+    }
+
+    protected String name(ProgramElementDoc member) {
+        return getName(classdoc, (AdviceDoc)member);
+    }
+
+    protected void printParameters(ExecutableMemberDoc member) {
+        //AdviceDoc advice = (AdviceDoc)member;
+        Access.printParameters
+            ((com.sun.tools.doclets.standard.ExecutableMemberSubWriter)
+             ((AbstractSubWriter)del()).del(),
+             member);
+    }
+
+    protected void printReturnType(AdviceDoc advice) {
+        Type type = advice.returnType();
+        if (type != null) {
+            printTypeLink(type);
+            print(' ');
+        }
+    }
+
+    public void nonfinalPrintMember(ProgramElementDoc elem) {
+        AdviceDoc advice = (AdviceDoc)elem;
+        writer.anchor(where(advice));
+        printHead(advice);
+        printSignature(advice);
+        printFullComment(advice);
+    }
+
+    protected void printSummaryLink(ClassDoc cd, ProgramElementDoc member) {
+        ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
+        String name = emd.name();
+        writer.bold();
+        writer.printClassLink(cd, where(emd), name, false);
+        writer.boldEnd();
+        writer.displayLength = name.length();
+        printParameters(emd);
+    }
+
+    protected void printHead(MemberDoc member) {
+        printHead(name(member));
+    }
+
+    protected static List staticMembers(ClassDoc classdoc) {
+        if (!(classdoc instanceof AspectDoc)) return Collections.EMPTY_LIST;
+        AdviceDoc[] advice = ((AspectDoc)classdoc).advice();
+        return advice == null ? Collections.EMPTY_LIST : Util.asList(advice);
+    }
+    
+    protected List getMembers(ClassDoc classdoc) {
+        return staticMembers(classdoc);
+    }
+
+    public void printCrosscuts(ClassDoc cd, ProgramElementDoc member) {
+        if (!(cd instanceof AspectDoc)) return;
+        //AspectDoc ad = (AspectDoc)cd;
+        AdviceDoc advice = (AdviceDoc)member;
+        ExecutableMemberDoc[] crosscuts = advice.crosscuts();
+        if (null != crosscuts && crosscuts.length > 0) {
+            writer.dt();
+            writer.boldText("doclet.Crosscuts");
+            Set set = new HashSet();
+            for (int i = 0; i < crosscuts.length; i++) {
+                set.add(crosscuts[i]);
+            }
+            List list = new ArrayList(set);
+            Collections.sort(list);
+            for (Iterator i = list.iterator(); i.hasNext();) {
+                ExecutableMemberDoc emd = (ExecutableMemberDoc)i.next();
+                if (null != emd) {
+                    writer.dd();
+                    writer.code();
+                    String where = emd instanceof AdviceDoc
+                        ?          where(emd)
+                        :    super.where(emd);
+                    writer.printClassLink(emd.containingClass(),
+                                          where, label(emd));
+                    print(" in ");
+                    writer.printClassLink(emd.containingClass());
+                    writer.codeEnd();
+                    print('.');
+                }
+            }
+        }
+    }
+
+    public void printSummaryCrosscuts(ClassDoc cd,
+                                         ProgramElementDoc member) {
+
+        class CCs extends TreeMap {
+            void add(ExecutableMemberDoc cc) {
+                if (null != cc) { 
+                    Object o = get(cc.containingClass());
+                    if (o == null) {
+                        o = cc;
+                    } else if (o instanceof ExecutableMemberDoc) {
+                        o = new Integer(2);
+                    } else {
+                        o = new Integer(((Integer)o).intValue()+1);
+                    }
+                    put(cc.containingClass(), o);
+                }
+            }
+        }
+        
+        ExecutableMemberDoc[] crosscuts = ((AdviceDoc)member).crosscuts();
+        if (crosscuts.length > 0) {
+            writer.boldText("doclet.Advises");
+            CCs ccs = new CCs();
+            for (int i = 0; i < crosscuts.length; i++) {
+                ccs.add(crosscuts[i]);
+            }
+            for (Iterator i = ccs.keySet().iterator(); i.hasNext();) {
+                print(' ');
+                ClassDoc target = (ClassDoc)i.next();
+                Object o = ccs.get(target);
+                String link;
+                String name = target.name();
+                if (o instanceof AdviceDoc) {
+                    link = where((AdviceDoc)o);
+                } else if (o instanceof ExecutableMemberDoc) {
+                    link = super.where((ExecutableMemberDoc)o);
+                } else {
+                    link = "method_detail";
+                    name += "(" + o + ")";
+                }
+                writer.printClassLink(target, link, name);
+                if (i.hasNext()) print(",");
+            }
+        }
+    }
+
+    public boolean hasCrosscuts(ClassDoc classDoc, ProgramElementDoc member) {
+        return true;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassSubWriter.java
new file mode 100644 (file)
index 0000000..1587efe
--- /dev/null
@@ -0,0 +1,109 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AspectDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ProgramElementDoc;
+import com.sun.javadoc.Type;
+import com.sun.tools.doclets.VisibleMemberMap;
+
+public class ClassSubWriter extends AbstractSubWriter {
+
+    public static class Del extends com.sun.tools.doclets.standard.ClassSubWriter {
+        protected ClassSubWriter mw;
+        public Del(com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+                   ClassDoc classdoc)
+        {
+            super(writer, classdoc);
+        }
+        public Del(com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+        {
+            super(writer);
+        }
+        public void printMembersSummary() {
+            mw.printMembersSummary();
+            mw.printIntroducedMembersSummary();
+            if (writer instanceof ClassWriter) {
+                ((ClassWriter)writer).printAspectJSummary();
+            }
+        }
+        public void printMembers() {
+            mw.printMembers();
+        }
+        protected void navSummaryLink() {
+            mw.navSummaryLink();
+            if (writer instanceof ClassWriter) {
+                ((ClassWriter)writer).navstate++;
+            }
+        }
+        protected void navDetailLink() {
+            mw.navDetailLink();
+        }
+        public void setDelegator(ClassSubWriter mw) { this.mw = mw; }
+    }
+
+    protected Class delegateClass() {
+        return Del.class;
+    }
+
+    public ClassSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+         ClassDoc classdoc)
+    {
+        super(writer, classdoc);
+    }
+    
+    public ClassSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+    
+    public int getMemberKind() {
+        //XXX hack!!!
+        return VisibleMemberMap.INNERCLASSES;
+    }
+    
+    protected void printSummaryType(ProgramElementDoc member) {
+        ClassDoc cd = (ClassDoc)member;
+        printModifierAndType(cd, null);
+    }
+
+    protected void printModifierAndType(ProgramElementDoc member,
+                                        Type type) {
+        writer.printTypeSummaryHeader();
+        printModifier(member);
+        if (type == null) {
+            print(member instanceof AspectDoc ?
+                  "aspect" : member.isClass() ?
+                  "class" :
+                  "interface");
+        } else {
+            printTypeLink(type); 
+        }
+        writer.printTypeSummaryFooter();
+    }
+}  
+    
+    
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassUseMapper.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassUseMapper.java
new file mode 100644 (file)
index 0000000..8c1a1ab
--- /dev/null
@@ -0,0 +1,294 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AdviceDoc;
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.IntroducedDoc;
+import org.aspectj.ajdoc.IntroducedSuperDoc;
+import org.aspectj.ajdoc.IntroductionDoc;
+import org.aspectj.ajdoc.PointcutDoc;
+import org.aspectj.tools.ajdoc.Util;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ExecutableMemberDoc;
+import com.sun.javadoc.FieldDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.javadoc.PackageDoc;
+import com.sun.javadoc.Parameter;
+import com.sun.javadoc.ProgramElementDoc;
+import com.sun.javadoc.RootDoc;
+import com.sun.javadoc.Type;
+import com.sun.tools.doclets.ClassTree;
+import com.sun.tools.doclets.DocletAbortException;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provides support for aspects.
+ *
+ * @author Jeff Palm
+ */
+public class ClassUseMapper {
+
+
+    /**
+     * Maps a ClassDoc to advice that return its type.
+     */
+    public final Map classToAdviceReturn = new HashMap();
+    
+    /**
+     * Maps a ClassDoc to advice that have its type
+     * are arguments.
+     */
+    public final Map classToAdviceArgs = new HashMap();
+    
+    /**
+     * Maps a ClassDoc to pointcuts that return its type.
+     */
+    public final Map classToPointcutReturn = new HashMap();
+    
+    /**
+     * Maps a ClassDoc to pointcuts that have its type
+     * as arguments.
+     */
+    public final Map classToPointcutArgs = new HashMap();
+    
+    /**
+     * Maps a ClassDoc to field introductions that
+     * are its type.
+     */
+    public final Map classToFieldIntroductions = new HashMap();
+
+    /**
+     * Maps a ClassDoc to class introductions that
+     * are its type.
+     */
+    public final Map classToClassIntroductions = new HashMap();
+    
+    /**
+     * Maps a ClassDoc to interface introductions that
+     * are its type.
+     */
+    public final Map classToInterfaceIntroductions = new HashMap();
+    
+    /**
+     * Maps a ClassDoc to aspects that advise it.
+     */
+    public final Map classToAdvisors = new HashMap();
+    
+    /**
+     * Maps a ClassDoc to aspects that it dominates.
+     */
+    public final Map classToDominatees = new HashMap();
+    
+    /**
+     * Maps a ClassDoc to aspects that dominate it..
+     */
+    public final Map classToDominators = new HashMap();
+    
+
+    public static void generate(RootDoc root, ClassTree classtree)
+        throws DocletAbortException {
+        try {
+            
+            ClassUseMapper mapper = new ClassUseMapper(root, classtree);
+
+            ClassDoc[] classes = root.classes();
+            for (int i = 0; i < classes.length; i++) {
+                ClassUseWriter.generate(mapper, classes[i]);
+            }
+            PackageDoc[] pkgs = Standard.configuration().packages;
+            for (int i = 0; i < pkgs.length; i++) {
+                com.sun.tools.doclets.standard.PackageUseWriter.
+                    generate(mapper.mapper, pkgs[i]);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            Standard.configuration().standardmessage.
+                error("doclet.exception", e+"",
+                      "creating class use tree");
+            throw new DocletAbortException();
+        }
+    }
+
+    protected final com.sun.tools.doclets.standard.ClassUseMapper mapper;
+    
+    public ClassUseMapper(RootDoc root, ClassTree classtree)
+        throws Exception {
+        Constructor constr =
+            com.sun.tools.doclets.standard.ClassUseMapper.class.
+            getDeclaredConstructor(new Class[] {
+                com.sun.javadoc.RootDoc.class,
+                com.sun.tools.doclets.ClassTree.class,
+            });
+        constr.setAccessible(true);
+        mapper = (com.sun.tools.doclets.standard.ClassUseMapper)constr.
+            newInstance(new Object[]{root, classtree});
+
+        classToPackageSave = new HashMap();
+        for (Iterator i = mapper.classToPackage.keySet().iterator(); i.hasNext();) {
+            Object key = i.next();
+            classToPackageSave.put(key, new HashSet((Collection)
+                                                    mapper.classToPackage.
+                                                    get(key)));
+        }
+        
+        finish(root, classtree);
+    }
+
+    protected Object saved;
+    protected final Map classToPackageSave;
+    protected final com.sun.tools.doclets.standard.ClassUseMapper mapper
+        (ClassDoc classdoc)
+    {
+        Object noaspects = classToPackageSave.get(classdoc);
+        saved = mapper.classToPackage.get(classdoc);
+        mapper.classToPackage.put(classdoc, noaspects);
+        return mapper;
+    }
+
+    protected void restore(ClassDoc classdoc) {
+        mapper.classToPackage.put(classdoc, saved);
+    }
+   
+    protected void finish(RootDoc root, ClassTree classtree) {
+       
+        ClassDoc[] classes = root.classes();
+        for (int i = 0; i < classes.length; i++) {
+            ClassDoc cd = classes[i];
+            if (cd instanceof org.aspectj.ajdoc.ClassDoc) {
+                org.aspectj.ajdoc.ClassDoc acd = (org.aspectj.ajdoc.ClassDoc)cd;
+                PointcutDoc[] pcs = acd.pointcuts();
+                for (int j = 0; j < pcs.length; j++) {
+                    PointcutDoc pd = pcs[j];
+                    mapExecutable(pd);
+                    Type result = pd.resultType();
+                    if (result != null) {
+                        ClassDoc tcd = result.asClassDoc();
+                        if (tcd != null) {
+                            add(classToPointcutReturn, tcd, pd);
+                        }
+                    }
+                }
+            }
+            
+            if (cd instanceof AspectDoc) {
+                AspectDoc ad = (AspectDoc)cd;
+                AdviceDoc[] adocs = ad.advice();
+                for (int j = 0; j < adocs.length; j++) {
+                    AdviceDoc adoc = adocs[j];
+                    mapExecutable(adoc);
+                    Type result = adoc.returnType();
+                    if (result != null) {
+                        ClassDoc tcd = result.asClassDoc();
+                        if (tcd != null) {
+                            add(classToAdviceReturn, tcd, adoc);
+                        }
+                    }
+                    ExecutableMemberDoc[] emds = adoc.crosscuts();
+                    if (null != emds) {
+                        for (int k = 0; k < emds.length; k++) {
+                            ExecutableMemberDoc emd = emds[k];
+                            if (null != emd) {
+                                ClassDoc tcd = emd.containingClass();
+                                ClassDoc fcd = adoc.containingClass();
+                                //TODO: This probably sucks!!!
+                                if (!refList(classToAdvisors, tcd).contains(fcd)) {
+                                    add(classToAdvisors, tcd, fcd);
+                                }
+                            }
+                        }
+                    }
+                }
+
+                IntroductionDoc[] ids = ad.introductions();
+                for (int j = 0; j < ids.length; j++) {
+                    IntroductionDoc id = ids[j];
+                    if (id instanceof IntroducedDoc) {
+                        IntroducedDoc idd = (IntroducedDoc)id;
+                        MemberDoc mem = idd.member();
+                        if (mem.isField()) {
+                            FieldDoc fd = (FieldDoc)mem;
+                            ClassDoc tcd = fd.type().asClassDoc();
+                            add(classToFieldIntroductions, tcd, fd);
+                        }
+                    } else if (id instanceof IntroducedSuperDoc) {
+                        IntroducedSuperDoc idd = (IntroducedSuperDoc)id;
+                        boolean isImplements = idd.isImplements();
+                        Type[] types = idd.types();
+                        for (int k = 0; k < types.length; k++) {
+                            ClassDoc tcd = types[k].asClassDoc();
+                            add(isImplements ?
+                                classToInterfaceIntroductions :
+                                classToClassIntroductions, tcd,  idd);
+                        }
+                    }
+                }
+                AspectDoc[] dominatees = ad.dominatees();
+                for (int j = 0; j < dominatees.length; j++) {
+                    add(classToDominatees, ad, dominatees[j]);
+                }
+                AspectDoc[] dominators = ad.dominators();
+                for (int j = 0; j < dominators.length; j++) {
+                    add(classToDominators, ad, dominators[j]);
+                }
+            }
+        }
+    }
+    
+    protected void mapExecutable(ExecutableMemberDoc em) {
+        Parameter[] params = em.parameters();
+        List classargs = new ArrayList();
+        Map argsmap = ((org.aspectj.ajdoc.MemberDoc)em).isAdvice() ?
+            classToAdviceArgs : classToPointcutArgs ;
+        for (int i = 0; i < params.length; i++) {
+            ClassDoc pcd = params[i].type().asClassDoc();
+            if (pcd != null && !classargs.contains(pcd)) {
+                add(argsmap, pcd, em);
+                classargs.add(pcd);
+            }
+        }
+    }
+    
+    protected List refList(Map map, ClassDoc cd) {
+        return (List)Util.invoke(mapper, "refList",
+                                 new Class[]{java.util.Map.class,
+                                             com.sun.javadoc.ClassDoc.class},
+                                 new Object[]{map, cd});
+    }
+
+    protected void add(Map map, ClassDoc cd, ProgramElementDoc ref) {
+        Util.invoke(mapper, "add",
+                    new Class[]{java.util.Map.class,
+                                com.sun.javadoc.ClassDoc.class,
+                                com.sun.javadoc.ProgramElementDoc.class},
+                    new Object[]{map, cd, ref});
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassUseWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassUseWriter.java
new file mode 100644 (file)
index 0000000..97ab802
--- /dev/null
@@ -0,0 +1,272 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.tools.ajdoc.Access;
+import org.aspectj.tools.ajdoc.Util;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.PackageDoc;
+import com.sun.tools.doclets.DirectoryManager;
+import com.sun.tools.doclets.DocletAbortException;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Provides support for aspects.
+ *
+ * @author Jeff Palm
+ */
+public class ClassUseWriter
+    extends com.sun.tools.doclets.standard.ClassUseWriter
+{
+
+    /**
+     * The target ClassDoc.
+     */
+    protected final ClassDoc classdoc;
+
+    /**
+     * Maps PackageDocs to advice arguments.
+     */
+    protected final Map pkgToAdviceArgs;
+
+    /**
+     * Maps PackageDocs to advice return types.
+     */
+    protected final Map pkgToAdviceReturn;
+    
+    /**
+     * Maps PackageDocs to pointcut arguments.
+     */
+    protected final Map pkgToPointcutArgs;
+
+    /**
+     * Maps PackageDocs to pointcut return types.
+     */
+    protected final Map pkgToPointcutReturn;
+
+    /**
+     * Maps PackageDocs to field introductions.
+     */
+    protected final Map pkgToFieldIntroductions;
+
+    /**
+     * Maps PackageDocs to class introductions.
+     */
+    protected final Map pkgToClassIntroductions;
+    
+    /**
+     * Maps PackageDocs to interface introductions.
+     */
+    protected final Map pkgToInterfaceIntroductions;
+
+    /**
+     * Maps PackageDocs to class advisors.
+     */
+    protected final Map pkgToClassAdvisors;
+
+    /**
+     * Maps PackageDocs to aspects that dominate
+     * aspects in that package.
+     */
+    protected final Map pkgToAspectDominatees;
+
+    /**
+     * Maps PackageDocs to aspects that are dominated
+     * by aspects in that package.
+     */
+    protected final Map pkgToAspectDominators;
+
+    /**
+     * The MethodSubWriter to use.
+     */
+    protected final MethodSubWriter methodSubWriter
+        = new MethodSubWriter(this);
+    
+    /**
+     * The ConstructorSubWriter to use.
+     */
+    protected final ConstructorSubWriter constrSubWriter
+        = new ConstructorSubWriter(this);
+    
+    /**
+     * The FieldSubWriter to use.
+     */
+    protected final FieldSubWriter fieldSubWriter
+        = new FieldSubWriter(this);
+    
+    /**
+     * The ClassSubWriter to use.
+     */
+    protected final ClassSubWriter classSubWriter
+        = new ClassSubWriter(this);
+        
+    /**
+     * The PointcutSubWriter to use.
+     */
+    protected final PointcutSubWriter pointcutSubWriter
+        = new PointcutSubWriter(this);
+    
+    /**
+     * The SuperIntroductionSubWriter to use.
+     */
+    protected final SuperIntroductionSubWriter superIntroductionSubWriter
+        = new SuperIntroductionSubWriter(this);
+    
+    /**
+     * The FieldIntroductionSubWriter to use.
+     */
+    protected final FieldIntroductionSubWriter fieldIntroductionSubWriter
+        = new FieldIntroductionSubWriter(this);
+    
+    /**
+     * The ConstructorIntroductionSubWriter to use.
+     */
+    protected final ConstructorIntroductionSubWriter constrIntroductionSubWriter
+        = new ConstructorIntroductionSubWriter(this);
+    
+    /**
+     * The MethodIntroductionSubWriter to use.
+     */
+    protected final MethodIntroductionSubWriter methodIntroductionSubWriter
+        = new MethodIntroductionSubWriter(this);
+    
+    /**
+     * The AdviceSubWriter to use.
+     */
+    protected final AdviceSubWriter adviceSubWriter
+        = new AdviceSubWriter(this);
+    
+
+
+    public ClassUseWriter(ClassUseMapper mapper,
+                          String path, 
+                          String filename,
+                          String relpath,
+                          ClassDoc classdoc) 
+        throws IOException, DocletAbortException {
+
+        super(mapper.mapper(classdoc), path,
+              filename, relpath, classdoc);
+
+        mapper.restore(classdoc);
+
+        this.classdoc = Access.classdoc(this);
+
+        this.pkgToAdviceReturn =
+            _pkgDivide(mapper.classToAdviceReturn);
+        this.pkgToAdviceArgs =
+            _pkgDivide(mapper.classToAdviceArgs);
+        this.pkgToPointcutReturn =
+            _pkgDivide(mapper.classToPointcutReturn);
+        this.pkgToPointcutArgs =
+            _pkgDivide(mapper.classToPointcutArgs);
+        this.pkgToFieldIntroductions =
+            _pkgDivide(mapper.classToFieldIntroductions);
+        this.pkgToClassIntroductions =
+            _pkgDivide(mapper.classToClassIntroductions);
+        this.pkgToInterfaceIntroductions =
+            _pkgDivide(mapper.classToInterfaceIntroductions);
+        this.pkgToClassAdvisors =
+            _pkgDivide(mapper.classToAdvisors);
+        this.pkgToAspectDominatees =
+            _pkgDivide(mapper.classToDominatees);
+        this.pkgToAspectDominators =
+            _pkgDivide(mapper.classToDominators);
+    }
+
+    protected com.sun.tools.doclets.standard.ClassUseWriter
+        writer;
+    private Map _pkgDivide(Map classMap) {
+        return (Map)Util.invoke
+            (com.sun.tools.doclets.standard.ClassUseWriter.class,
+             this, "pkgDivide",
+             new Class[]{java.util.Map.class},
+             new Object[]{classMap});
+    }
+       
+    public static void generate(ClassUseMapper mapper, 
+                                ClassDoc classdoc) 
+        throws DocletAbortException {
+        ClassUseWriter cw = null;
+        String path = DirectoryManager.getDirectoryPath(classdoc.
+                                                        containingPackage());
+        if (path.length() > 0) {
+            path += File.separator;
+        }
+        path += "class-use";
+        String filename = classdoc.name() + ".html";
+        String pkgname = classdoc.containingPackage().name();
+        pkgname += (pkgname.length() > 0 ? "." : "") + "class-use";
+        String relpath = DirectoryManager.getRelativePath(pkgname); 
+        try {
+            (cw = new ClassUseWriter(mapper, path, filename, 
+                                     relpath, classdoc)).
+                generateClassUseFile();
+        } catch (IOException e) {
+            Standard.configuration().standardmessage.
+                error("doclet.exception_encountered", e+"", filename);
+            throw new DocletAbortException();
+        } finally {
+            if (cw != null) cw.close();
+        }
+    }
+
+    protected void generateClassUse(PackageDoc pkg) throws IOException {
+        super.generateClassUse(pkg);
+        String classlink = getClassLink(classdoc);
+        String pkglink = getPackageLink(pkg);
+
+        printUseInfo(adviceSubWriter, pkgToAdviceReturn,
+                     pkg, "AdviceReturn", classlink, pkglink);
+        printUseInfo(adviceSubWriter, pkgToAdviceArgs,
+                     pkg, "AdviceArgs", classlink, pkglink);
+        printUseInfo(pointcutSubWriter, pkgToPointcutReturn,
+                     pkg, "PointcutReturn", classlink, pkglink);
+        printUseInfo(pointcutSubWriter, pkgToPointcutArgs,
+                     pkg, "PointcutArgs", classlink, pkglink);
+        printUseInfo(fieldIntroductionSubWriter, pkgToFieldIntroductions,
+                     pkg, "FieldIntroductions", classlink, pkglink);
+        printUseInfo(superIntroductionSubWriter, pkgToClassIntroductions,
+                     pkg, "ClassIntroductions", classlink, pkglink);
+        printUseInfo(superIntroductionSubWriter, pkgToInterfaceIntroductions,
+                     pkg, "InterfaceIntroductions", classlink, pkglink);
+        printUseInfo(classSubWriter, pkgToClassAdvisors,
+                     pkg, "ClassAdvisors", classlink, pkglink);
+
+        printUseInfo(classSubWriter, pkgToAspectDominatees,
+                     pkg, "AspectDominatees", classlink, pkglink);
+        printUseInfo(classSubWriter, pkgToAspectDominators,
+                     pkg, "AspectDominators", classlink, pkglink);
+    }
+
+    protected final void printUseInfo(AbstractSubWriter mw, Map map,
+                                      PackageDoc pkg, String kind,
+                                      String classlink, String pkglink) {
+        Access.printUseInfo(mw, map.get(pkg),
+                            getText("doclet.ClassUse_" + kind,
+                                    classlink,pkglink));
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ClassWriter.java
new file mode 100644 (file)
index 0000000..7ae6435
--- /dev/null
@@ -0,0 +1,554 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AdviceDoc;
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.IntroducedDoc;
+import org.aspectj.ajdoc.IntroducedSuperDoc;
+import org.aspectj.ajdoc.IntroductionDoc;
+import org.aspectj.ajdoc.OfClauseDoc;
+import org.aspectj.ajdoc.OfEachObjectDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ExecutableMemberDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.tools.doclets.ClassTree;
+import com.sun.tools.doclets.DirectoryManager;
+import com.sun.tools.doclets.DocletAbortException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class ClassWriter extends com.sun.tools.doclets.standard.ClassWriter {
+
+    /**
+     * The MethodSubWriter that prints out the methods
+     * of <code>classdoc</code>.
+     */
+    protected MethodSubWriter ourMethodSubWriter;
+    
+    /**
+     * The ConstructorSubWriter that prints out the constructors
+     * of <code>classdoc</code>.
+     */
+    protected ConstructorSubWriter ourConstrSubWriter;
+    
+    /**
+     * The FieldSubWriter that prints out the fields
+     * of <code>classdoc</code>.
+     */
+    protected FieldSubWriter ourFieldSubWriter;
+    
+    /**
+     * The ClassSubWriter that prints out the classs
+     * of <code>classdoc</code>.
+     */
+    protected ClassSubWriter ourInnerSubWriter;
+    
+    /**
+     * The PointcutSubWriter that prints out the pointcuts
+     * of <code>classdoc</code>.
+     */
+    protected PointcutSubWriter pointcutSubWriter = null;
+    
+    /**
+     * The SuperIntroductionSubWriter that prints out the superintroductions
+     * of <code>classdoc</code>.
+     */
+    protected SuperIntroductionSubWriter superIntroductionSubWriter = null;
+    
+    /**
+     * The FieldIntroductionSubWriter that prints out the fieldintroductions
+     * of <code>classdoc</code>.
+     */
+    protected FieldIntroductionSubWriter fieldIntroductionSubWriter = null;
+    
+    /**
+     * The ConstructorIntroductionSubWriter that prints out the constructorintroductions
+     * of <code>classdoc</code>.
+     */
+    protected ConstructorIntroductionSubWriter constrIntroductionSubWriter = null;
+    
+    /**
+     * The MethodIntroductionSubWriter that prints out the methodintroductions
+     * of <code>classdoc</code>.
+     */
+    protected MethodIntroductionSubWriter methodIntroductionSubWriter = null;
+    
+    /**
+     * The AdviceSubWriter that prints out the advices
+     * of <code>classdoc</code>.
+     */
+    protected AdviceSubWriter adviceSubWriter = null;
+    
+
+    /**
+     * Construct a ClassWriter from the passed in arguments.  This
+     * will instantiate the subwriters to be used.
+     *
+     * @param path      the path directory of the html file to generate.
+     * @param filename  the html file to generate.
+     * @param classdoc  the ClassDoc for which this file will
+     *                  be generated.
+     * @param prev      the ClassDoc preceding <code>classdoc</code>
+     *                  in order of generation.
+     * @param next      the ClassDoc following <code>classdoc</code>
+     *                  in order of generation.
+     * @param classtree the ClassTree to use.
+     * @param nopackage whether this <code>classdoc</code>'s package
+     *                  is specified to be documented.
+     */
+    public ClassWriter(String path,
+                       String filename,
+                       ClassDoc classdoc,
+                       ClassDoc prev,
+                       ClassDoc next,
+                       ClassTree classtree,
+                       boolean nopackage)
+        throws IOException, DocletAbortException {
+
+        super(path, filename,  classdoc, prev,
+              next, classtree, nopackage);
+
+        // Construct the subwriters just for ClassDocs
+        // We want our superclass to delegate to our subwriters delegate,
+        // but we want to call our subwriters.  So we set our superclasses
+        // subwriters to our subwriters delegates.
+        ourMethodSubWriter = new MethodSubWriter(this, classdoc);
+        methodSubWriter = (com.sun.tools.doclets.standard.MethodSubWriter)
+            ourMethodSubWriter.del();
+        constrSubWriter = (com.sun.tools.doclets.standard.ConstructorSubWriter)
+            (ourConstrSubWriter = new ConstructorSubWriter(this, classdoc)).del();
+        fieldSubWriter = (com.sun.tools.doclets.standard.FieldSubWriter)
+            (ourFieldSubWriter = new FieldSubWriter(this, classdoc)).del();
+        innerSubWriter = (com.sun.tools.doclets.standard.ClassSubWriter)
+            (ourInnerSubWriter = new ClassSubWriter(this, classdoc)).del();
+
+        if (classdoc instanceof org.aspectj.ajdoc.ClassDoc) {
+            pointcutSubWriter =
+                new PointcutSubWriter(this, (org.aspectj.ajdoc.ClassDoc)classdoc);
+        }
+
+        // If we've been passed an AspectDoc, create the AspectJ-specfic
+        // subwriters
+        if (classdoc instanceof AspectDoc) {
+            AspectDoc ad = (AspectDoc)classdoc;
+            superIntroductionSubWriter  = new SuperIntroductionSubWriter(this, ad);
+            fieldIntroductionSubWriter  = new FieldIntroductionSubWriter(this, ad);
+            constrIntroductionSubWriter = new ConstructorIntroductionSubWriter(this, ad);
+            methodIntroductionSubWriter = new MethodIntroductionSubWriter(this, ad);
+            adviceSubWriter             = new AdviceSubWriter(this, ad);
+        }
+    }
+
+    public static void generate(ClassDoc classdoc,
+                                ClassDoc prev, 
+                                ClassDoc next,
+                                ClassTree classtree, 
+                                boolean nopackage)
+        throws DocletAbortException {
+        ClassWriter cw = null;
+        String path = DirectoryManager.getDirectoryPath
+            (classdoc.containingPackage());
+        String filename = classdoc.name() + ".html";
+        try {
+            (cw = new ClassWriter(path, filename, classdoc, 
+                                  prev, next, classtree, nopackage)).
+                generateClassFile();
+        } catch (IOException e) {
+            Standard.configuration().standardmessage.
+                error("doclet.exception_encountered", e+"", filename);
+            throw new DocletAbortException();
+        } finally {
+            if (cw != null) cw.close();
+        }
+    }
+
+    /**
+     * Prints the header of the class -- which is one
+     * of <code>class</code>, <code>interface</code> or
+     * <code>aspect</code> with the name <code>title</code>.
+     *
+     * @param title the name of the class.
+     */
+    public void printHeader(String title) {
+        int ispace = title.indexOf(' ');
+        if (ispace != -1) {
+            title = Statics.type(classdoc) + title.substring(ispace);
+        }
+        super.printHeader(title);
+    }
+
+    /*
+     * This is set up to intercept calls to print out
+     * the correct type of classdoc before we automatically
+     * print 'class' or 'interface'.
+     */
+
+    private boolean h2warn = false;
+
+    /**
+     * If we've started to print a h2 heading, we're
+     * printing the name of the class so get ready to
+     * to intercept the call.
+     */
+    public void h2() {
+        h2warn = true;
+        super.h2();
+    }
+
+    /**
+     * After printing the class declaration with the h2 heading
+     * turn off the h2 warning.
+     */
+    public void h2End() {
+        h2warn = false;
+        super.h2End();
+    }
+
+    /**
+     * This is where we intercept the call to print so
+     * we can print the correct type.
+     */
+    public void print(String str) {
+        if (h2warn) {
+            int ispace = str.indexOf(' ');
+            if (ispace != -1 && str.charAt(0) == 'C') {
+                str = Statics.type(classdoc) + str.substring(ispace);
+            }
+        }
+        super.print(str);
+    }
+
+    /**
+     * Print the members summary for our AspectJ subwriters.
+     */
+    protected void printAspectJSummary() {
+        printMembersSummary(superIntroductionSubWriter);
+        printMembersSummary(fieldIntroductionSubWriter);
+        printMembersSummary(constrIntroductionSubWriter);
+        printMembersSummary(methodIntroductionSubWriter);
+        printMembersSummary(pointcutSubWriter);
+        printMembersSummary(adviceSubWriter);
+    }
+
+    /**
+     * Formats the output correctly for a member summary.
+     *
+     * @param mw the AbstractSubWriter to use.
+     */
+    protected final void printMembersSummary(AbstractSubWriter mw) {
+        if (mw != null) {
+            println();
+            println("<!-- === " + getText(mw.navKey()) + " SUMMARY === -->");
+            println();
+            mw.printMembersSummary();
+        }
+    }
+
+    /**
+     * Print the members detail for our AspectJ subwriters.
+     */
+    protected void printAspectJDetail() {
+        printMembersDetail(superIntroductionSubWriter);
+        printMembersDetail(fieldIntroductionSubWriter);
+        printMembersDetail(constrIntroductionSubWriter);
+        printMembersDetail(methodIntroductionSubWriter);
+        printMembersDetail(pointcutSubWriter);
+        printMembersDetail(adviceSubWriter);
+    }
+
+    /**
+     * Formats the output correctly for a member detail.
+     *
+     * @param mw the AbstractSubWriter to use.
+     */
+    protected final void printMembersDetail(AbstractSubWriter mw) {
+        if (mw != null) {
+            println("<!-- ===" + getText(mw.navKey()) + " DETAIL === -->");
+            println();
+            mw.printMembers();
+            println();
+        }
+    }
+
+    //TODO: Just need to make sure 'aspect; shows up and
+    //TODO  not 'class'
+    protected void printClassDescription() {
+        boolean isInterface = classdoc.isInterface();
+        boolean isAspect = classdoc instanceof AspectDoc;
+        dl();
+        dt();
+
+        print(classdoc.modifiers() + " ");  
+
+        if (!isInterface) {
+            print(isAspect ? "aspect " : "class ");
+        }
+        bold(classdoc.name());
+
+        if (!isInterface) {
+            ClassDoc superclass = classdoc.superclass();
+            if (superclass != null) {
+                dt();
+                print("extends ");
+                printClassLink(superclass);
+                printIntroducedSuper(superclass);
+            }
+        }
+
+        ClassDoc[] implIntfacs = classdoc.interfaces();
+        if (implIntfacs != null && implIntfacs.length > 0) {
+            dt();
+            print(isInterface? "extends " : "implements ");
+            for (int i = 0; i < implIntfacs.length; i++) {
+                if (i > 0) print(", ");
+                printClassLink(implIntfacs[i]);
+                printIntroducedSuper(implIntfacs[i]);
+            }
+        }
+        if (isAspect) {
+            AspectDoc ad = (AspectDoc)classdoc;
+            OfClauseDoc ofClause = ad.ofClause();
+            if (ofClause != null) {
+                dt();
+                if (ofClause.kind() == OfClauseDoc.Kind.EACH_CFLOW) {
+                    print("percflow(..)");
+                } else if (ofClause.kind() == OfClauseDoc.Kind.EACH_JVM) {
+                    print("issingleton()");
+                } else if (ofClause.kind() == OfClauseDoc.Kind.EACH_OBJECT) {
+                    print("pertarget(");
+                    printClassLinks(((OfEachObjectDoc)ofClause).instances());
+                    print(")");
+                }
+            }
+            AspectDoc[] dominatees = ad.dominatees();
+            if (dominatees != null && dominatees.length > 0) {
+                dt();
+                print("dominates ");
+                printClassLinks(dominatees);
+            }
+            AspectDoc[] dominators = ad.dominators();
+            if (dominators != null && dominators.length > 0) {
+                dt();
+                print("dominated by ");
+                printClassLinks(dominators);
+            }
+        }
+        dlEnd();
+    }
+
+    /**
+     * Prints a list of class links separated by commas.
+     *
+     * @param cds array of ClassDoc to be printed.
+     */
+    protected void printClassLinks(ClassDoc[] cds) {
+        if (cds == null || cds.length < 1) return;
+        for (int i = 0; i < cds.length; i++) {
+            if (i > 0) print(", ");
+            if (cds[i] != null) {
+                printClassLink(cds[i]);
+            }
+        }
+    }
+
+    /**
+     * Prints information about <code>classdoc</code>'s type introduction
+     * if <code>cd</code>'s type was introduced onto <code>classdoc</code>.
+     *
+     * @param cd the ClassDoc being printed.
+     */
+    protected void printIntroducedSuper(ClassDoc cd) {
+        IntroducedSuperDoc[] intros =
+            ((org.aspectj.ajdoc.ClassDoc)classdoc).introducers();
+        if (null != intros) {
+            for (int i = 0; i < intros.length; i++) {
+                IntroducedSuperDoc intro = intros[i];
+                org.aspectj.ajdoc.Type[] types = intro.types();
+                for (int j = 0; j < types.length; j++) {
+                    if (types[j].equals(cd)) {
+                        print(' ');
+                        printText("doclet.by_parens",
+                                  getClassLink
+                                  (intro.containingClass(),
+                                   superIntroductionSubWriter.link(intro),
+                                   "introduced"),
+                                  getClassLink(intro.containingClass()));
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Print the navSummaryLink for all the AspectJ subwriters.
+     */
+    protected void navAspectJSummaryLinks() {
+        navSummaryLink(superIntroductionSubWriter);
+        navSummaryLink(fieldIntroductionSubWriter);
+        navSummaryLink(constrIntroductionSubWriter);
+        navSummaryLink(methodIntroductionSubWriter);
+        navSummaryLink(pointcutSubWriter);
+        navSummaryLink(adviceSubWriter);
+    }
+
+    /**
+     * Prints the navSummaryLink correctly.
+     *
+     * @param mw AbstractSubWriter to invoke.
+     */
+    protected final void navSummaryLink(AbstractSubWriter mw) {
+        if (mw != null) {
+            mw.navSummaryLink();
+            _navGap();
+        }
+    }
+
+    /**
+     * Print the navDetailLink for all the AspectJ subwriters.
+     */
+    protected void navAspectJDetailLinks() {
+        navDetailLink(superIntroductionSubWriter);
+        navDetailLink(fieldIntroductionSubWriter);
+        navDetailLink(constrIntroductionSubWriter);
+        navDetailLink(methodIntroductionSubWriter);
+        navDetailLink(pointcutSubWriter);
+        navDetailLink(adviceSubWriter);
+    }
+
+    /**
+     * Prints the navDetailLink correctly.
+     *
+     * @param mw AbstractSubWriter to invoke.
+     */
+    protected final void navDetailLink(AbstractSubWriter mw) {
+        if (mw != null) {
+            mw.navDetailLink();
+            _navGap();
+        }
+    }
+
+    /*
+     * A hack... I'll explain later, if you need to change
+     * this mail jeffrey_palm@hotmail.com.
+     */
+
+    protected final void _navGap() { super.navGap(); }
+
+    protected int navstate = 0;
+    protected void navGap() {
+        _navGap();
+        if (navstate == 1) {
+            navAspectJSummaryLinks();
+            navstate++;
+        } else if (navstate == 3) {
+            navAspectJDetailLinks();
+            navstate++;
+        }
+    }
+
+    protected void printEnclosingClassInfo() {
+        super.printEnclosingClassInfo();
+        printAdvisorInfo();
+        printAdviseeInfo();
+    }
+
+    protected void printAdviseeInfo() {
+        if (!(classdoc instanceof AspectDoc)) return;
+        AspectDoc ad = (AspectDoc)classdoc;
+        Set set = new TreeSet();
+        AdviceDoc[] as = ad.advice();
+        if (as != null) {
+            for (int i = 0; i < as.length; i++) {
+                ExecutableMemberDoc[] crosscuts = as[i].crosscuts();
+                if (null != crosscuts) {
+                    for (int j = 0; j < crosscuts.length; j++) {
+                        if (null != crosscuts[j]) {
+                            set.add(crosscuts[j].containingClass());
+                        }
+                    }
+                }
+            }
+        }
+        IntroductionDoc[] is = ad.introductions();
+        if (null != is) {
+            for (int i = 0 ; i < is.length; i++) {
+                ClassDoc[] targets = is[i].targets();
+                for (int j = 0; j < targets.length; j++) {
+                    set.add(targets[j]);
+                }
+            }
+            printInfo(set, "doclet.All_Advisees");
+        }
+    }
+
+    protected void printAdvisorInfo() {
+        Set set = new TreeSet();
+        set.addAll(advisors(classdoc.fields()));
+        set.addAll(advisors(classdoc.methods()));
+        set.addAll(advisors(classdoc.constructors()));
+        printInfo(set, "doclet.All_Advisors");
+    }
+
+    protected void printInfo(Collection classdocs, String str) {
+        if ((null != classdocs) && (classdocs.size() > 0)) {
+            printInfoHeader();
+            boldText(str);
+            dd();
+            for (Iterator i = classdocs.iterator(); i.hasNext();) {
+                printClassLink((ClassDoc)i.next());
+                if (i.hasNext()) print(", ");
+            }
+            ddEnd();
+            dlEnd();
+        }
+    }
+
+    protected final Collection advisors(final MemberDoc[] ms) {
+        List list = new ArrayList();
+        if (null != ms) {
+            for (int i = 0 ; i < ms.length; i++) {
+                IntroducedDoc id =
+                    ((org.aspectj.ajdoc.MemberDoc)ms[i]).introduced();
+                if (id != null) list.add(id.containingClass());
+                if (ms[i] instanceof org.aspectj.ajdoc.ExecutableMemberDoc) {
+                    AdviceDoc[] as =
+                        ((org.aspectj.ajdoc.ExecutableMemberDoc)ms[i]).advice();
+                    for (int j = 0; j < as.length; j++) {
+                        list.add(as[j].containingClass());
+                    }
+                }
+            }
+        }
+        return list;
+    }
+}
+
+
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ConfigurationStandard.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ConfigurationStandard.java
new file mode 100644 (file)
index 0000000..8de96b8
--- /dev/null
@@ -0,0 +1,120 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+
+package org.aspectj.tools.doclets.standard;
+
+import com.sun.javadoc.RootDoc;
+import com.sun.tools.doclets.MessageRetriever;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+
+/**
+ * A customized configuration.
+ *
+ * @author Jeff Palm
+ */
+public class ConfigurationStandard
+    extends com.sun.tools.doclets.standard.ConfigurationStandard
+{
+    
+    /** It true we don't print crosscut information. */
+    public boolean nocrosscuts = false;
+
+    /** If true we don't print crosscut summary information. */
+    public boolean nosummarycrosscuts = false;
+
+    /** If true we log each pass in the doclet. */
+    public boolean log = false;
+    
+    public ConfigurationStandard() {
+//        standardmessage = new MessageRetriever
+//            ("org.aspectj.tools.doclets.standard.resources.standard");
+
+        String loc = "org.aspectj.tools.doclets.standard.resources.standard";
+        final ClassLoader loader = getClass().getClassLoader();
+        // XXX move persistant resource loader to util
+        ResourceBundle bundle = null;
+        for (int i = 0; ((null == bundle) && (i < 4)); i++) {
+                       
+            try {
+                switch (i) {
+                    case 0: 
+                        bundle = ResourceBundle.getBundle(loc);
+                        standardmessage = new MessageRetriever(bundle);
+                    break;
+                    case 1: 
+                        Locale locale = Locale.getDefault();            
+                        bundle = ResourceBundle.getBundle(loc, locale, loader);
+                        standardmessage = new MessageRetriever(bundle);
+                    break;
+                    case 2: 
+                        standardmessage = new MessageRetriever(loc);
+                    break;
+                    case 3:
+                        URL pURL = loader.getResource(loc + ".properties");
+                        bundle = new PropertyResourceBundle(pURL.openStream());
+                        standardmessage = new MessageRetriever(loc);
+                    break;
+                }
+                break; // from for loop
+            } catch (MissingResourceException e) { } // error below
+            catch (IOException ie) { } // error below
+        }
+        if (null == bundle) {
+            throw new Error("unable to load resource: " +   loc);
+        }
+    }
+    
+    //TODO: Document the new options in help
+
+    public void setSpecificDocletOptions(RootDoc root) {
+        String[][] options = root.options();
+        for (int i = 0; i < options.length; ++i) {
+            String opt = options[i][0].toLowerCase();
+            if (opt.equals("-nocrosscuts")) {
+                nocrosscuts = true;
+                nosummarycrosscuts = true;
+            } else if (opt.equals("-nosummarycrosscuts")) {
+                nosummarycrosscuts = true;
+            } else if (opt.equals("-log")) {
+                log = true;
+            }
+        }
+        super.setSpecificDocletOptions(root);
+    }
+
+    public int specificDocletOptionLength(String opt) {
+        if (opt.equals("-nocrosscuts") ||
+            opt.equals("-nosummarycrosscuts") ||
+            opt.equals("-log")) {
+            return 1;
+        }
+        return super.specificDocletOptionLength(opt);
+    }
+}
+        
+
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ConstructorIntroductionSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ConstructorIntroductionSubWriter.java
new file mode 100644 (file)
index 0000000..ad16055
--- /dev/null
@@ -0,0 +1,126 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.IntroducedDoc;
+import org.aspectj.ajdoc.IntroductionDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.javadoc.ProgramElementDoc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+public class ConstructorIntroductionSubWriter extends ConstructorSubWriter {
+    
+    public ConstructorIntroductionSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+         AspectDoc ad)
+    {
+        super(writer, ad);
+    }
+
+    public ConstructorIntroductionSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+
+    protected final String keyName() { return "Constructor_Introduction"; }
+
+    protected List getMembers(ClassDoc cd) {
+        if (!(cd instanceof AspectDoc)) return super.getMembers(cd);
+        IntroductionDoc[] introductions = ((AspectDoc)cd).introductions();
+        List list = new ArrayList();
+        if (introductions == null) return list;
+        for (int i = 0; i < introductions.length; i++) {
+            IntroductionDoc id = introductions[i];
+            if (!(id instanceof IntroducedDoc)) continue;
+            MemberDoc member = ((IntroducedDoc)id).member();
+            if (member.isConstructor()) {
+                //ConstructorDec constructor = (ConstructorDec)member;
+                //TODO: constructor.bindSignatures(((ClassDec)cd).getTypeScope());
+                list.add(member); //constructor);
+            }
+        }
+        return list;
+    }
+
+    public void printCrosscuts(ClassDoc cd, ProgramElementDoc member) {
+        org.aspectj.ajdoc.ConstructorDoc constr =
+            (org.aspectj.ajdoc.ConstructorDoc)member;
+        IntroducedDoc intro = constr.introduced();
+        //String name = where(constr);
+        ClassDoc[] targets = intro.targets();
+        if (targets.length > 0) {
+            writer.dt();
+            writer.boldText("doclet.Introduced_on");
+            writer.dd();
+            writer.code();
+            for (int i = 0; i < targets.length; i++) {
+                if (i > 0) writer.print(", ");
+                ClassDoc target = targets[i];
+                writer.printClassLink(target,
+                                      "constructors_introduced_from_class_" +
+                                      cd.qualifiedName(),
+                                      target.name());
+            }
+            writer.codeEnd();
+            writer.ddEnd();      // XXX added for balance
+        }
+    }
+
+    public void printSummaryCrosscuts(ClassDoc cd,
+                                         ProgramElementDoc member) {
+        Set set = new HashSet();
+        org.aspectj.ajdoc.MemberDoc md = (org.aspectj.ajdoc.MemberDoc)member;
+        IntroducedDoc intro = md.introduced();
+        ClassDoc[] targets = intro.targets();
+        for (int i = 0; i < targets.length; i++) {
+            set.add(targets[i]);
+        }
+        if (targets.length > 0) {
+            writer.boldText("doclet.Advises");
+            List list = new ArrayList(set);
+            Collections.sort(list);
+            for (Iterator i = list.iterator(); i.hasNext();) {
+                print(' ');
+                ClassDoc target = (ClassDoc)i.next();
+                writer.printClassLink(target,
+                                      "constructors_introduced_from_class_"
+                                      + cd.qualifiedName(),
+                                      target.name());
+                if (i.hasNext()) print(",");
+            }
+        }
+    }
+
+    public boolean hasCrosscuts(ClassDoc classDoc, ProgramElementDoc member) {
+        return true;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ConstructorSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ConstructorSubWriter.java
new file mode 100644 (file)
index 0000000..bd8360b
--- /dev/null
@@ -0,0 +1,85 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ProgramElementDoc;
+import com.sun.tools.doclets.VisibleMemberMap;
+
+public class ConstructorSubWriter extends ExecutableMemberSubWriter {
+
+    public static class Del
+        extends com.sun.tools.doclets.standard.ConstructorSubWriter {
+        protected ConstructorSubWriter mw;
+        public Del(com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+                   ClassDoc classdoc) {
+            super(writer, classdoc);
+        }
+        public Del(com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+        {
+            super(writer);
+        }
+        public void printMembersSummary() {
+            mw.printMembersSummary();
+            mw.printIntroducedMembersSummary();
+        }
+        public void printMembers() {
+            mw.printMembers();
+        }
+        protected void navSummaryLink() {
+            mw.navSummaryLink();
+        }
+        protected void navDetailLink() {
+            mw.navDetailLink();
+        }
+        public void setDelegator(ConstructorSubWriter mw) { this.mw = mw; }
+        public void printSummaryMember(ClassDoc cd, ProgramElementDoc member) {
+            mw.printSummaryMember(cd, member);
+        }
+    }
+
+    protected Class delegateClass() {
+        return Del.class;
+    }
+
+    public ConstructorSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer, 
+         ClassDoc classdoc)
+    {
+        super(writer, classdoc);
+    }
+    
+    public ConstructorSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+    
+    public int getMemberKind() {
+        //XXX hack!!!
+        return VisibleMemberMap.CONSTRUCTORS;
+    }
+
+    protected String propertyName() { return "Constructor"; }
+}  
+    
+    
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/DeprecatedAPIListBuilder.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/DeprecatedAPIListBuilder.java
new file mode 100644 (file)
index 0000000..bc90a0f
--- /dev/null
@@ -0,0 +1,120 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.IntroducedDoc;
+import org.aspectj.ajdoc.IntroductionDoc;
+import org.aspectj.tools.ajdoc.Util;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.javadoc.RootDoc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class DeprecatedAPIListBuilder
+    extends com.sun.tools.doclets.standard.DeprecatedAPIListBuilder
+{
+    
+    private List deprecatedadvice = new ArrayList();
+    private List deprecatedpointcuts = new ArrayList();
+    private List deprecatedfieldintroductions = new ArrayList();
+    private List deprecatedmethodintroductions = new ArrayList();
+    private List deprecatedconstructorintroductions = new ArrayList();
+    private List deprecatedsuperintroductions = new ArrayList();
+    
+    public DeprecatedAPIListBuilder(RootDoc root) {
+        super(root);
+        buildDeprecatedAPIInfo(root);
+    }
+
+    protected void buildDeprecatedAPIInfo(RootDoc root) {
+        ClassDoc[] cs = root.classes();
+        for (int i = 0; i < cs.length; i++) {
+            org.aspectj.ajdoc.ClassDoc c = (org.aspectj.ajdoc.ClassDoc)cs[i];
+            _composeDeprecatedList(deprecatedpointcuts, c.pointcuts());
+            if (c instanceof AspectDoc) {
+                AspectDoc ad = (AspectDoc)c;
+                _composeDeprecatedList(deprecatedadvice, ad.advice());
+                IntroductionDoc[] intros = ad.introductions();
+                for (int j = 0; j < intros.length; j++) {
+                    if (intros[j] instanceof IntroducedDoc) {
+                        MemberDoc md = ((IntroducedDoc)intros[j]).member();
+                        if (md == null) continue;
+                        if (md.isField()) {
+                            _composeDeprecatedList(deprecatedfieldintroductions,
+                                                   intros[j]);
+                        } else if (md.isMethod()) {
+                            _composeDeprecatedList(deprecatedmethodintroductions,
+                                                   intros[j]);
+                        } else {
+                            _composeDeprecatedList(deprecatedconstructorintroductions,
+                                                   intros[j]);
+                        }
+                    } else {
+                        _composeDeprecatedList(deprecatedsuperintroductions,
+                                               intros[j]);
+                    }
+                }
+            }
+        }
+        Collections.sort(deprecatedadvice);
+        Collections.sort(deprecatedpointcuts);
+        Collections.sort(deprecatedfieldintroductions);
+        Collections.sort(deprecatedmethodintroductions);
+        Collections.sort(deprecatedconstructorintroductions);
+        Collections.sort(deprecatedsuperintroductions);
+    }
+
+    protected void _composeDeprecatedList(List list, MemberDoc member) {
+        _composeDeprecatedList(list, new MemberDoc[]{member});
+    }
+    protected void _composeDeprecatedList(List list, MemberDoc[] members) { 
+        Util.invoke(com.sun.tools.doclets.standard.DeprecatedAPIListBuilder.class,
+                    this, "composeDeprecatedList",
+                    new Class[]{java.util.List.class,
+                                com.sun.javadoc.MemberDoc[].class},
+                    new Object[]{list, members});
+    }
+
+    public List getDeprecatedAdivce() {
+        return deprecatedadvice;
+    }
+    public List getDeprecatedPointcuts() {
+        return deprecatedpointcuts;
+    }
+    public List getDeprecatedFieldIntroductions() {
+        return deprecatedfieldintroductions;
+    }
+    public List getDeprecatedMethodIntroductions() {
+        return deprecatedmethodintroductions;
+    }
+    public List getDeprecatedConstructorIntroductions() {
+        return deprecatedconstructorintroductions;
+    }
+    public List getDeprecatedSuperIntroductions() {
+        return deprecatedsuperintroductions;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/DeprecatedListWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/DeprecatedListWriter.java
new file mode 100644 (file)
index 0000000..8333b65
--- /dev/null
@@ -0,0 +1,94 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.tools.ajdoc.Access;
+
+import com.sun.javadoc.RootDoc;
+import com.sun.tools.doclets.DocletAbortException;
+
+import java.io.IOException;
+import java.util.List;
+
+public class DeprecatedListWriter
+    extends com.sun.tools.doclets.standard.DeprecatedListWriter
+{
+
+    protected DeprecatedAPIListBuilder builder;
+    
+    public DeprecatedListWriter(String filename,
+                                DeprecatedAPIListBuilder builder)
+        throws IOException {
+        super(filename);
+        this.builder = builder;
+    }
+
+    public static void generate(RootDoc root) throws DocletAbortException {
+        String filename = "deprecated-list.html";
+        DeprecatedListWriter dw = null;
+        try {
+            (dw = new DeprecatedListWriter(filename,
+                                           new DeprecatedAPIListBuilder(root))).
+                generateDeprecatedListFile();
+        } catch (IOException e) {
+            Standard.configuration().
+                standardmessage.error("doclet.exception_encountered",
+                                      e+"", filename);
+            throw new DocletAbortException();
+        } finally {
+            if (dw != null) dw.close();
+        }
+    }
+
+    protected void generateDeprecatedListFile() throws IOException {
+        generateDeprecatedListFile(builder);
+    }
+
+    protected void printDeprecatedFooter() {
+        printRestOfDeprecatedListFile();
+        super.printDeprecatedFooter();
+    }
+
+    protected void printRestOfDeprecatedListFile() {
+        deprecatedListFile(new AdviceSubWriter(this),
+                           builder.getDeprecatedAdivce());
+        deprecatedListFile(new PointcutSubWriter(this),
+                           builder.getDeprecatedPointcuts());
+        deprecatedListFile(new FieldIntroductionSubWriter(this),
+                           builder.getDeprecatedFieldIntroductions());
+        deprecatedListFile(new MethodIntroductionSubWriter(this),
+                           builder.getDeprecatedMethodIntroductions());
+        deprecatedListFile(new ConstructorIntroductionSubWriter(this),
+                           builder.getDeprecatedConstructorIntroductions());
+        deprecatedListFile(new SuperIntroductionSubWriter(this),
+                           builder.getDeprecatedSuperIntroductions());
+        
+                           
+    }
+
+    protected final void deprecatedListFile(AbstractSubWriter mw,
+                                      List list) {
+        Access.printDeprecatedAPI(mw, list,
+                                  "doclet.Deprecated_" +
+                                  mw.keyName() + "s");
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ExecutableMemberSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/ExecutableMemberSubWriter.java
new file mode 100644 (file)
index 0000000..12e5785
--- /dev/null
@@ -0,0 +1,139 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AdviceDoc;
+import org.aspectj.ajdoc.IntroducedDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ExecutableMemberDoc;
+import com.sun.javadoc.ProgramElementDoc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+public abstract class ExecutableMemberSubWriter extends AbstractSubWriter {
+    public ExecutableMemberSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer, 
+         ClassDoc classdoc)
+    {
+        super(writer, classdoc);
+    }
+    
+    public ExecutableMemberSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+
+    protected String where(ProgramElementDoc member) {
+        ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
+        return emd.name() + emd.signature();
+    }
+
+    protected String label(ExecutableMemberDoc emd) {
+        return emd.qualifiedName() + emd.flatSignature();
+    }
+
+    public void printIntroducedSummaryLink(ClassDoc cd, 
+                                           ProgramElementDoc member) {
+        ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
+       writer.printClassLink(cd, where(emd), emd.name(), false);
+    }
+
+    public void printCrosscuts(ClassDoc cd, ProgramElementDoc member) {
+        org.aspectj.ajdoc.ExecutableMemberDoc emd =
+            (org.aspectj.ajdoc.ExecutableMemberDoc)member;
+        
+        IntroducedDoc intro = emd.introduced();
+        if (intro != null) {
+            writer.dt();
+            writer.boldText("doclet.Introduced_from");
+            writer.dd();
+            org.aspectj.ajdoc.MemberDoc otherMember =
+                (org.aspectj.ajdoc.MemberDoc)intro.member();
+            String name = where(otherMember);
+            ClassDoc containing = intro.containingClass();
+            writer.printClassLink(containing, name,
+                                  containing.typeName(), false);
+        }
+        
+        AdviceDoc[] advice = emd.advice();
+        if (advice.length > 0) {
+            writer.boldText("doclet.Crosscut_by");
+            Set set = new HashSet();
+            for (int i = 0; i < advice.length; i++) {
+                set.add(advice[i]);
+            }
+            List list = new ArrayList(set);
+            Collections.sort(list);
+            for (Iterator i = list.iterator(); i.hasNext();) {
+                writer.dd();
+                writer.code();
+                AdviceDoc ad = (AdviceDoc)i.next();
+                writer.printClassLink(ad.containingClass(),
+                                      AdviceSubWriter.getWhere
+                                      (ad.containingClass(), ad),
+                                      label(ad));
+                print(" in ");
+                writer.printClassLink(ad.containingClass());
+                writer.codeEnd();
+                print('.');
+            }
+        }
+    }
+    
+    public void printSummaryCrosscuts(ClassDoc cd,
+                                      ProgramElementDoc member) {
+        Set cds = new HashSet();
+        org.aspectj.ajdoc.ExecutableMemberDoc emd =
+            (org.aspectj.ajdoc.ExecutableMemberDoc)member;
+        AdviceDoc[] advice = emd.advice();
+        for (int i = 0; i < advice.length; i++) {
+            cds.add(advice[i].containingClass());
+        }        
+        if (cds.size() > 0) {
+            writer.boldText("doclet.Advised_by");
+            List list = new ArrayList(cds);
+            Collections.sort(list);
+            for (Iterator i = list.iterator(); i.hasNext();) {
+                print(' ');
+                ClassDoc cdoc = (ClassDoc)i.next();
+                writer.printClassLink(cdoc, "advice_detail", cdoc.name());
+                if (i.hasNext()) print(",");
+            }
+        }
+    }
+
+    public boolean hasCrosscuts(ClassDoc classDoc,
+                                ProgramElementDoc member) {
+        org.aspectj.ajdoc.ExecutableMemberDoc emd =
+            (org.aspectj.ajdoc.ExecutableMemberDoc)member;
+        return emd.introduced() != null || emd.advice().length > 0;
+    }
+}  
+    
+    
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/FieldIntroductionSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/FieldIntroductionSubWriter.java
new file mode 100644 (file)
index 0000000..fd7519b
--- /dev/null
@@ -0,0 +1,131 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.IntroducedDoc;
+import org.aspectj.ajdoc.IntroductionDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.javadoc.ProgramElementDoc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+public class FieldIntroductionSubWriter extends FieldSubWriter {
+
+    public FieldIntroductionSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+         AspectDoc ad)
+    {
+        super(writer, ad);
+    }
+    
+    public FieldIntroductionSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+
+    protected final String keyName() { return "Field_Introduction"; }
+
+    public void printInheritedSummaryAnchor(ClassDoc cd) {}
+    public void printInheritedSummaryLabel(ClassDoc cd) {}
+    protected void printInheritedSummaryLink(ClassDoc cd, ProgramElementDoc ped) {}
+
+    protected List getMembers(ClassDoc cd) {
+        if (!(cd instanceof AspectDoc)) return super.getMembers(cd);
+        IntroductionDoc[] introductions = ((AspectDoc)cd).introductions();
+        List list = new ArrayList();
+        if (introductions == null) return list;
+        for (int i = 0; i < introductions.length; i++) {
+            IntroductionDoc id = introductions[i];
+            if (!(id instanceof IntroducedDoc)) continue;
+            MemberDoc member = ((IntroducedDoc)id).member();
+            if (member.isField()) {
+                //FieldDec field = (FieldDec)member;
+                //TODO: field.bindSignatures(((ClassDec)cd).getTypeScope());
+                list.add(member); //field);
+            }
+        }
+        return list;
+    }
+    
+    /** print links back to aspect in target class docs? 
+     * or forward from aspects to target class members? */
+    public void printCrosscuts(ClassDoc cd, ProgramElementDoc member) {
+        org.aspectj.ajdoc.FieldDoc field = (org.aspectj.ajdoc.FieldDoc)member;
+        IntroducedDoc intro = field.introduced();
+        //String name = field.name();
+        ClassDoc[] targets = intro.targets();
+        if (targets.length > 0) {
+            writer.dt(); // define term
+            writer.boldText("doclet.Introduced_on");
+            writer.dd();
+            writer.code();
+            for (int i = 0; i < targets.length; i++) {
+                if (i > 0) writer.print(", ");
+                ClassDoc target = targets[i];
+                writer.printClassLink(target,
+                                      "fields_introduced_from_class_" +
+                                      cd.qualifiedName(),
+                                      target.name());
+                     
+            }
+            writer.codeEnd();
+            writer.ddEnd();      // XXX added for balance
+        }
+    }
+
+    public void printSummaryCrosscuts(ClassDoc cd,
+                                      ProgramElementDoc member) {
+        Set set = new HashSet();
+        org.aspectj.ajdoc.MemberDoc md = (org.aspectj.ajdoc.MemberDoc)member;
+        IntroducedDoc intro = md.introduced();
+        ClassDoc[] targets = intro.targets();
+        for (int i = 0; i < targets.length; i++) {
+            set.add(targets[i]);
+        }
+        if (targets.length > 0) {
+            writer.boldText("doclet.Advises");
+            List list = new ArrayList(set);
+            Collections.sort(list);
+            for (Iterator i = list.iterator(); i.hasNext();) {
+                print(' ');
+                ClassDoc target = (ClassDoc)i.next();
+                writer.printClassLink(target,
+                                      "fields_introduced_from_class_"
+                                      + cd.qualifiedName(),
+                                      target.name());
+                if (i.hasNext()) print(",");
+            }
+        }
+    }
+
+    public boolean hasCrosscuts(ClassDoc classDoc, ProgramElementDoc member) {
+        return true;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/FieldSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/FieldSubWriter.java
new file mode 100644 (file)
index 0000000..cca7b65
--- /dev/null
@@ -0,0 +1,116 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.IntroducedDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ProgramElementDoc;
+import com.sun.tools.doclets.VisibleMemberMap;
+
+public class FieldSubWriter extends AbstractSubWriter {
+
+    public static class Del extends com.sun.tools.doclets.standard.FieldSubWriter {
+        protected FieldSubWriter mw;
+        public Del(com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+                   ClassDoc classdoc)
+        {
+            super(writer, classdoc);
+        }
+        public Del(com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+        {
+            super(writer);
+        }
+        public void printMembersSummary() {
+            mw.printMembersSummary();
+            mw.printIntroducedMembersSummary();
+        }
+        public void printMembers() {
+            if (writer instanceof ClassWriter) {
+                ((ClassWriter)writer).printAspectJDetail();
+            }
+            mw.printMembers();
+        }
+        protected void navSummaryLink() {
+            mw.navSummaryLink();
+        }
+        protected void navDetailLink() {
+            if (writer instanceof ClassWriter) {
+                ((ClassWriter)writer).navstate++;
+            }
+            mw.navDetailLink();
+        }
+        public void setDelegator(FieldSubWriter mw) { this.mw = mw; }
+        public void printSummaryMember(ClassDoc cd, ProgramElementDoc member) {
+            mw.printSummaryMember(cd, member);
+        }
+    }
+    
+    protected Class delegateClass() {
+        return Del.class;
+    }
+
+    public FieldSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+         ClassDoc classdoc)
+    {
+        super(writer, classdoc);
+    }
+    
+    public FieldSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+
+      public int getMemberKind() {
+          //XXX hack!!!
+          return VisibleMemberMap.FIELDS;
+      }
+
+    protected String propertyName() { return "Field"; }
+
+    public void printIntroducedSummaryLink(ClassDoc cd, 
+                                           ProgramElementDoc member) {
+        writer.printClassLink(cd, member.name(), member.name(), false);
+    }
+
+    public void printCrosscuts(ClassDoc cd, ProgramElementDoc member) {
+        org.aspectj.ajdoc.FieldDoc field = (org.aspectj.ajdoc.FieldDoc)member;
+        IntroducedDoc intro = field.introduced();
+        if (intro != null) {
+            writer.dt();
+            writer.boldText("doclet.Introduced_from");
+            writer.dd();
+            writer.printClassLink(intro.containingClass(),
+                                  Statics.where(intro.member()));
+        }
+    }
+
+    public void printSummaryCrosscuts(ClassDoc cd, ProgramElementDoc member) {}
+
+    public boolean hasCrosscuts(ClassDoc classDoc, ProgramElementDoc member) {
+        return true || ((org.aspectj.ajdoc.MemberDoc)member).introduced() != null;
+    }
+}  
+    
+    
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/MethodIntroductionSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/MethodIntroductionSubWriter.java
new file mode 100644 (file)
index 0000000..ba28e4f
--- /dev/null
@@ -0,0 +1,136 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.IntroducedDoc;
+import org.aspectj.ajdoc.IntroductionDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.javadoc.ProgramElementDoc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+public class MethodIntroductionSubWriter extends MethodSubWriter {
+
+    public MethodIntroductionSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+         AspectDoc ad)
+    {
+        super(writer, ad);
+    }
+    
+    public MethodIntroductionSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+
+    protected final String keyName() { return "Method_Introduction"; }
+
+    public void printInheritedSummaryAnchor(ClassDoc cd) {}   
+    public void printInheritedSummaryLabel(ClassDoc cd) {}
+    protected void printInheritedSummaryLink(ClassDoc cd, ProgramElementDoc ped) {}
+
+    protected List getMembers(ClassDoc cd) {
+        if (!(cd instanceof AspectDoc)) return super.getMembers(cd);
+        IntroductionDoc[] introductions = ((AspectDoc)cd).introductions();
+        List list = new ArrayList();
+        if (introductions == null) return list;
+        for (int i = 0; i < introductions.length; i++) {
+            IntroductionDoc id = introductions[i];
+            if (!(id instanceof IntroducedDoc)) continue;
+            MemberDoc member = ((IntroducedDoc)id).member();
+            if (member.isMethod()) {
+                //MethodDec method = (MethodDec)member;
+                //TODO: method.bindSignatures(((ClassDec)cd).getTypeScope());
+                list.add(member); //method);
+            }
+        }
+        return list;
+    }
+
+    /** print in the detail context at the bottom of the page
+     * the links out to affected classes/members for this method introduction 
+     * (in this aspect)
+     */
+    public void printCrosscuts(ClassDoc cd, ProgramElementDoc member) {
+        org.aspectj.ajdoc.MethodDoc method = (org.aspectj.ajdoc.MethodDoc)member;
+        IntroducedDoc intro = method.introduced();
+        ClassDoc[] targets = intro.targets();
+        if (targets.length > 0) {
+            writer.dt();
+            writer.boldText("doclet.Introduced_on");
+            writer.dd();
+            writer.code();
+            for (int i = 0; i < targets.length; i++) {
+                if (i > 0) writer.print(", ");
+                ClassDoc target = targets[i];
+                writer.printClassLink(target,
+                                      "methods_introduced_from_class_" +
+                                      cd.qualifiedName(),
+                                      target.name());
+            }
+            writer.codeEnd();
+            writer.ddEnd();      // XXX added for balance
+        }
+    }
+
+    /** print in the summary context at the top of the page
+     * the links out to affected classes/members for this method introduction 
+     * (in this aspect)
+     */
+    public void printSummaryCrosscuts(ClassDoc cd,
+                                         ProgramElementDoc member) {
+        Set set = new HashSet();
+        org.aspectj.ajdoc.MemberDoc md = (org.aspectj.ajdoc.MemberDoc)member;
+        IntroducedDoc intro = md.introduced();
+        ClassDoc[] targets = intro.targets();
+        for (int i = 0; i < targets.length; i++) {
+            set.add(targets[i]);
+        }
+        if (targets.length > 0) {
+            writer.boldText("doclet.Advises");
+            List list = new ArrayList(set);
+            Collections.sort(list);
+            for (Iterator i = list.iterator(); i.hasNext();) {
+                print(' ');
+                ClassDoc target = (ClassDoc)i.next();
+                
+                writer.printClassLink(target,
+                                      "methods_introduced_from_class_"
+                                      + cd.qualifiedName(),
+                                      target.name());
+                if (i.hasNext()) print(",");
+            }
+        }
+    }
+
+    public boolean hasCrosscuts(ClassDoc classDoc, ProgramElementDoc member) {
+        return true;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/MethodSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/MethodSubWriter.java
new file mode 100644 (file)
index 0000000..31473e0
--- /dev/null
@@ -0,0 +1,112 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AdviceDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ExecutableMemberDoc;
+import com.sun.javadoc.MethodDoc;
+import com.sun.javadoc.ProgramElementDoc;
+import com.sun.tools.doclets.VisibleMemberMap;
+
+public class MethodSubWriter extends ExecutableMemberSubWriter {
+
+    public static class Del
+        extends com.sun.tools.doclets.standard.MethodSubWriter {
+        protected MethodSubWriter mw;
+        public Del(com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+                   ClassDoc classdoc)
+        {
+            super(writer, classdoc);
+        }
+        public Del(com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+        {
+            super(writer);
+        }
+        public void printMembersSummary() {
+            mw.printMembersSummary();
+            mw.printIntroducedMembersSummary();
+        }
+        public void printMembers() {
+            mw.printMembers();
+        }
+        protected void navSummaryLink() {
+            mw.navSummaryLink();
+        }
+        protected void navDetailLink() {
+            mw.navDetailLink();
+        }
+        public void setDelegator(MethodSubWriter mw) { this.mw = mw; }
+        public void printSummaryMember(ClassDoc cd, ProgramElementDoc member) {
+            mw.printSummaryMember(cd, member);
+        }
+    }
+
+    protected Class delegateClass() { return Del.class; }
+
+    public MethodSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+         ClassDoc classdoc)
+    {
+        super(writer, classdoc);
+    }
+
+    public MethodSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+
+    public int getMemberKind() {
+        //XXX hack!!!
+        return VisibleMemberMap.METHODS; 
+    }
+
+    //XXX
+    //hacks
+    protected void printSummaryType(ProgramElementDoc member) {
+        if (member instanceof MethodDoc) {
+            //TODO: Put in Access...
+            MethodDoc meth = (MethodDoc)member;
+            printModifierAndType(meth, meth.returnType());
+        } else if (member instanceof AdviceDoc) {
+            AdviceDoc advice = (AdviceDoc)member;
+            printModifierAndType(advice, advice.returnType());
+        }
+    }
+    protected void printSignature(ExecutableMemberDoc member) {
+        writer.displayLength = 0;
+        writer.pre();
+        printModifiers(member);
+        //printReturnType((MethodDoc)member);
+        bold(member.name());
+        //     printParameters(member);
+        //     printExceptions(member);
+        writer.preEnd();
+    }
+    //end-hacks
+
+    protected String propertyName() { return "Method"; }
+}
+
+
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PackageFrameWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PackageFrameWriter.java
new file mode 100644 (file)
index 0000000..c49cbc0
--- /dev/null
@@ -0,0 +1,75 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import com.sun.javadoc.PackageDoc;
+import com.sun.tools.doclets.DirectoryManager;
+import com.sun.tools.doclets.DocletAbortException;
+
+import java.io.IOException;
+
+public class PackageFrameWriter
+    extends com.sun.tools.doclets.standard.PackageFrameWriter
+{
+
+    protected final PackageDoc packagedoc;
+
+    public PackageFrameWriter(String path,
+                              String filename, 
+                              PackageDoc packagedoc) 
+        throws IOException, DocletAbortException {
+        super(path, filename, packagedoc);
+        this.packagedoc = packagedoc;
+    }
+
+    public static void generate(PackageDoc pkg) throws DocletAbortException {
+        PackageFrameWriter pw = null;
+        String path = DirectoryManager.getDirectoryPath(pkg);
+        String filename = "package-frame" + ".html";
+        try {
+            (pw = new PackageFrameWriter(path, filename, pkg)).
+                generatePackageFile();
+        } catch (IOException e) {
+            Standard.configuration().standardmessage.
+                    error("doclet.exception_encountered", 
+                           e+"", filename);
+            throw new DocletAbortException();
+        } finally {
+            if (pw != null) pw.close();
+        }
+    }
+
+    protected void generateClassListing() {
+        generateClassKindListing(packagedoc.interfaces(), 
+                                 getText("doclet.Interfaces"));
+        generateClassKindListing(Statics.classes(packagedoc.
+                                                 ordinaryClasses()),
+                                 getText("doclet.Classes"));
+        generateClassKindListing(((org.aspectj.ajdoc.PackageDoc)packagedoc).
+                                 aspects(),
+                                 getText("doclet.Aspects"));
+        generateClassKindListing(packagedoc.exceptions(),
+                                 getText("doclet.Exceptions"));
+        generateClassKindListing(packagedoc.errors(),
+                                 getText("doclet.Errors"));
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PackageTreeWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PackageTreeWriter.java
new file mode 100644 (file)
index 0000000..161608e
--- /dev/null
@@ -0,0 +1,97 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.PackageDoc;
+import com.sun.tools.doclets.ClassTree;
+import com.sun.tools.doclets.DirectoryManager;
+import com.sun.tools.doclets.DocletAbortException;
+
+import java.io.IOException;
+import java.util.List;
+
+public class PackageTreeWriter
+    extends com.sun.tools.doclets.standard.PackageTreeWriter
+{
+
+    protected class Del extends AbstractTreeWriter {
+        public Del(String s, ClassTree c)
+            throws IOException, DocletAbortException {
+            super(s, c);
+        }
+        public void print(String s) {
+            PackageTreeWriter.this.print(s);
+        }
+    }
+    final protected Del del;
+    {
+        Standard.quiet();
+        Del d = null;
+        try {
+            d = new Del(filename, classtree);
+        } catch (Exception e) {
+            Standard.configuration().standardmessage.
+                error("doclet.exception_encountered", 
+                      e+"", filename);
+        } finally {
+            del = d;
+            Standard.speak();
+        }
+    }
+    protected void generateLevelInfo(ClassDoc parent, List list) {
+        del.generateLevelInfo(parent, list);
+    }
+    protected void generateTree(List list, String heading) {
+        del.generateTree(list, heading);
+    }
+
+    public PackageTreeWriter(String path,
+                             String filename, 
+                             PackageDoc packagedoc, 
+                             PackageDoc prev,
+                             PackageDoc next,
+                             boolean noDeprecated) 
+                      throws IOException, DocletAbortException {
+        super(path, filename, packagedoc, prev, next, noDeprecated);
+    }
+
+    public static void generate(PackageDoc pkg, PackageDoc prev,
+                                PackageDoc next, boolean noDeprecated)
+                         throws DocletAbortException {
+        PackageTreeWriter pw = null;
+        String path = DirectoryManager.getDirectoryPath(pkg);
+        String filename = "package-tree.html";
+        try {
+            (pw = new PackageTreeWriter(path, filename, pkg, 
+                                        prev, next, noDeprecated)).
+                generatePackageTreeFile();
+        } catch (IOException e) {
+            Standard.configuration().standardmessage.
+                error("doclet.exception_encountered", 
+                      e+"", filename);
+            throw new DocletAbortException();
+        } finally {
+            if (pw != null) pw.close();
+        }
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PackageWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PackageWriter.java
new file mode 100644 (file)
index 0000000..8a6ed5e
--- /dev/null
@@ -0,0 +1,79 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import com.sun.javadoc.PackageDoc;
+import com.sun.tools.doclets.DirectoryManager;
+import com.sun.tools.doclets.DocletAbortException;
+
+import java.io.IOException;
+
+public class PackageWriter
+    extends com.sun.tools.doclets.standard.PackageWriter
+{
+
+    protected final PackageDoc packagedoc;
+
+    public PackageWriter(String path,
+                         String filename,
+                         PackageDoc packagedoc,
+                         PackageDoc prev,
+                         PackageDoc next) 
+        throws IOException, DocletAbortException {
+        super(path, filename, packagedoc, prev, next);
+        this.packagedoc = packagedoc;
+    }
+
+    public static void generate(PackageDoc pkg,
+                                PackageDoc prev,
+                                PackageDoc next) throws DocletAbortException {
+        PackageWriter pw;
+        String path = DirectoryManager.getDirectoryPath(pkg);
+        String filename = "package-summary.html";
+        try {
+            (pw = new PackageWriter(path, filename, pkg, prev, next)).
+                generatePackageFile();
+            pw.close();
+            pw.copyDocFiles(path);
+        } catch (IOException e) {
+            Standard.configuration().standardmessage.
+                error("doclet.exception_encountered", e+"", filename);
+            throw new DocletAbortException();
+        }
+    }
+
+    protected void generateClassListing() {
+        generateClassKindListing(packagedoc.interfaces(), 
+                                 getText("doclet.Interface_Summary"));
+        generateClassKindListing(Statics.classes(packagedoc.ordinaryClasses()),
+                                   getText("doclet.Class_Summary"));
+        generateClassKindListing(((org.aspectj.ajdoc.PackageDoc)packagedoc).aspects(),
+                                 getText("doclet.Aspect_Summary"));
+        generateClassKindListing(packagedoc.exceptions(),
+                                 getText("doclet.Exception_Summary"));
+        generateClassKindListing(packagedoc.errors(),
+                                 getText("doclet.Error_Summary"));
+    }
+}
+
+
+
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PointcutSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/PointcutSubWriter.java
new file mode 100644 (file)
index 0000000..518c9f2
--- /dev/null
@@ -0,0 +1,227 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+import org.aspectj.ajdoc.PointcutDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.javadoc.ParamTag;
+import com.sun.javadoc.Parameter;
+import com.sun.javadoc.ProgramElementDoc;
+import com.sun.javadoc.SeeTag;
+import com.sun.javadoc.Tag;
+import com.sun.javadoc.Type;
+import com.sun.tools.doclets.Util;
+
+import java.util.List;
+
+public class PointcutSubWriter extends AbstractSubWriter {
+
+    protected Class delegateClass() {
+        return null;
+    }
+
+    public PointcutSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+         ClassDoc classdoc)
+    {
+        super(writer, classdoc);
+    }
+
+    public PointcutSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+
+    protected final String keyName() { return "Pointcut"; }
+
+//      public void printInheritedSummaryAnchor(ClassDoc cd) {
+//          writer.anchor("pointcuts_inherited_from_class_" + cd.qualifiedName());
+//      }
+
+//      public void printInheritedSummaryLabel(ClassDoc cd) {
+//          String classlink = writer.getPreQualifiedClassLink(cd);
+//          writer.bold();
+//          writer.printText("doclet.Pointcuts_Inherited_From",
+//                           Statics.type(cd),
+//                           classlink);
+//          writer.boldEnd();
+//      }
+
+    void printSignature(MemberDoc member) {
+        PointcutDoc pcd = (PointcutDoc)member;
+        writer.displayLength = 0;
+       writer.pre();
+        printModifiers(pcd);
+        bold(pcd.name());
+        printParameters(pcd);
+        printResultType(pcd);
+       writer.preEnd();
+    }
+
+    void printResultType(PointcutDoc pcd) {
+        Type result = pcd.resultType();
+        if (result != null) {
+            writer.code();
+            print(" returns ");
+            printTypeLink(result);
+            writer.codeEnd();
+        }
+    }
+
+    protected void printSummaryLink(ClassDoc cd, ProgramElementDoc member) {
+        PointcutDoc pcd = (PointcutDoc)member;
+        String name = member.name();
+        writer.bold();
+        writer.printClassLink(cd, name + pcd.signature(), name, false);
+        writer.boldEnd();
+        writer.displayLength = name.length();
+        printParameters(pcd);
+        printResultType(pcd);
+
+    }
+    
+    protected void printInheritedSummaryLink(ClassDoc cd, 
+                                             ProgramElementDoc member) {
+        PointcutDoc pcd = (PointcutDoc)member;
+        String name = member.name();
+        writer.printClassLink(cd, name + pcd.signature(), name, false);
+    }
+
+    protected void printSummaryType(ProgramElementDoc member) {
+        PointcutDoc pcd = (PointcutDoc)member;
+        writer.printTypeSummaryHeader();
+        printModifier(pcd);
+        writer.printTypeSummaryFooter();
+        
+    }
+
+    protected void printBodyHtmlEnd(ClassDoc cd) {
+    }
+
+    protected void nonfinalPrintMember(ProgramElementDoc member) {
+        PointcutDoc pcd = (PointcutDoc)member;
+        writer.anchor(pcd.name() + pcd.signature());
+        printHead(pcd);
+        printSignature(pcd);
+        printFullComment(pcd);
+    }
+
+    protected void printDeprecatedLink(ProgramElementDoc member) {
+        writer.printClassLink(member.containingClass(),
+                              member.name(), 
+                              ((PointcutDoc)member).qualifiedName());
+    }
+
+    protected List getMembers(ClassDoc cd) {
+        return Util.asList(((org.aspectj.ajdoc.ClassDoc)cd).pointcuts());
+    }
+
+    protected void printParameters(PointcutDoc member) {
+        print('(');
+        Parameter[] params = member.parameters();
+        for (int i = 0; i < params.length; i++) {
+            printParam(params[i]);
+            if (i < params.length-1) {
+                writer.print(',');
+                writer.print(' ');
+            }
+        }
+        writer.print(')');
+    }
+
+    protected void printParam(Parameter param) {
+        printTypedName(param.type(), param.name());
+    }
+
+    protected void printParamTags(ParamTag[] params) {
+        if (params.length > 0) {
+            writer.dt();
+            writer.boldText("doclet.Parameters");
+            for (int i = 0; i < params.length; ++i) {
+                ParamTag pt = params[i];
+                writer.dd();
+                writer.code();
+                print(pt.parameterName());
+                writer.codeEnd();
+                print(" - ");
+                writer.printInlineComment(pt);
+            }
+        }
+    }
+
+    protected void printReturnTag(Tag[] returnsTag) {
+        if (returnsTag.length > 0) {
+            writer.dt();
+            writer.boldText("doclet.Returns");
+            writer.dd();
+            writer.printInlineComment(returnsTag[0]);
+        }
+    }
+    
+    protected void printOverridden(ClassDoc overridden, PointcutDoc pcd) {
+        if (overridden != null) {
+            String name = pcd.name();
+            writer.dt();
+            writer.boldText("doclet.Overrides");
+            writer.dd();
+            writer.printText("doclet.in_class",
+                             writer.codeText
+                             (writer.getClassLink(overridden, 
+                                                  name + pcd.signature(), 
+                                                  name, false)),
+                             writer.codeText
+                             (writer.getClassLink(overridden)));
+        }
+    }
+
+    protected void printTags(ProgramElementDoc member) {
+        PointcutDoc pcd = (PointcutDoc)member;
+        ParamTag[] params = pcd.paramTags();
+        Tag[] returnsTag = pcd.tags("return");
+        Tag[] sinces = pcd.tags("since");
+        SeeTag[] sees = pcd.seeTags();
+        ClassDoc[] intfacs = member.containingClass().interfaces();
+        ClassDoc overridden = pcd.overriddenClass();
+        if (intfacs.length > 0 || overridden != null) {
+            writer.dd();
+            writer.dl();
+            printOverridden(overridden, pcd);
+            writer.dlEnd();
+            writer.ddEnd();
+        }
+        if (params.length +
+            returnsTag.length +
+            sinces.length +
+            sees.length > 0) {
+            writer.dd();
+            writer.dl();
+            printParamTags(params);
+            printReturnTag(returnsTag);
+            writer.printSinceTag(pcd);
+            writer.printSeeTags(pcd);
+            writer.dlEnd();
+            writer.ddEnd();
+        }
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SingleIndexWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SingleIndexWriter.java
new file mode 100644 (file)
index 0000000..889cfbb
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import com.sun.javadoc.MemberDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.tools.doclets.DocletAbortException;
+import com.sun.tools.doclets.IndexBuilder;
+
+import java.io.IOException;
+
+public class SingleIndexWriter
+    extends com.sun.tools.doclets.standard.SingleIndexWriter
+{
+
+    protected class Del extends AbstractIndexWriter {
+        public Del(String s, IndexBuilder i) throws IOException {
+            super(s, i);
+        }
+        public void print(String s) {
+            SingleIndexWriter.this.print(s);
+        }
+    }
+    final protected Del del;
+    {
+        Standard.quiet();
+        Del d = null;
+        try {
+            d = new Del(filename, indexbuilder);
+        } catch (Exception e) {
+            Standard.configuration().standardmessage.
+                error("doclet.exception_encountered", 
+                      e+"", filename);
+        } finally {
+            del = d;
+            Standard.speak();
+        }
+    }
+    protected void printMemberDesc(MemberDoc member) {
+        del.printMemberDesc(member);
+    }
+    protected void printClassInfo(ClassDoc cd) {
+        del.printClassInfo(cd);
+    }
+
+    public SingleIndexWriter(String filename, 
+                             IndexBuilder indexbuilder) throws IOException {
+        super(filename, indexbuilder);
+    }
+
+    public static void generate(IndexBuilder indexbuilder) 
+                                throws DocletAbortException {
+        SingleIndexWriter sw = null;
+        String filename = "index-all.html";
+        try {
+            (sw = new SingleIndexWriter(filename, indexbuilder)).
+                generateIndexFile();
+        } catch (IOException e) {
+            Standard.configuration().standardmessage.error
+                ("doclet.exception_encountered",
+                 e+"", filename);
+            throw new DocletAbortException();
+        } finally {
+            if (sw != null) sw.close();
+        }
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SplitIndexWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SplitIndexWriter.java
new file mode 100644 (file)
index 0000000..ea6e112
--- /dev/null
@@ -0,0 +1,99 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.MemberDoc;
+import com.sun.tools.doclets.DirectoryManager;
+import com.sun.tools.doclets.DocletAbortException;
+import com.sun.tools.doclets.IndexBuilder;
+
+import java.io.IOException;
+
+public class SplitIndexWriter
+    extends com.sun.tools.doclets.standard.SplitIndexWriter
+{
+
+    protected class Del extends AbstractIndexWriter {
+        public Del(String s, IndexBuilder i) throws IOException {
+            super(s, i);
+        }
+        public void print(String s) {
+            SplitIndexWriter.this.print(s);
+        }
+    }
+    final protected Del del;
+    {
+        Standard.quiet();
+        Del d = null;
+        try {
+            d = new Del(filename, indexbuilder);
+        } catch (Exception e) {
+            Standard.configuration().standardmessage.
+                error("doclet.exception_encountered", 
+                      e+"", filename);
+        } finally {
+            del = d;
+            Standard.speak();
+        }
+    }
+    protected void printMemberDesc(MemberDoc member) {
+        del.printMemberDesc(member);
+    }
+    protected void printClassInfo(ClassDoc cd) {
+        del.printClassInfo(cd);
+    }
+
+    public SplitIndexWriter(String path, String filename, 
+                            String relpath, IndexBuilder indexbuilder,
+                            int prev, int next) throws IOException {
+        super(path, filename, relpath,
+              indexbuilder, prev, next);
+    }
+
+    public static void generate(IndexBuilder indexbuilder) 
+                                throws DocletAbortException {
+        SplitIndexWriter sw = null;
+        String filename = "";
+        String path = DirectoryManager.getPath("index-files");
+        String relpath = DirectoryManager.getRelativePath("index-files");
+        try {
+            for (int i = 0; i < indexbuilder.elements().length; i++) {
+                int j = i + 1;
+                int prev = (j == 1)? -1: i;
+                int next = (j == indexbuilder.elements().length)? -1: j + 1;
+                filename = "index-" + j +".html";
+                (sw = new SplitIndexWriter(path, filename, relpath,
+                                           indexbuilder, prev, next)).
+                    generateIndexFile((Character)
+                                      indexbuilder.elements()[i]);
+            }
+        } catch (IOException e) {
+            Standard.configuration().
+                standardmessage.error("doclet.exception_encountered",
+                                      e+"", filename);
+            throw new DocletAbortException();
+        } finally {
+            if (sw != null) sw.close();
+        }
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/Standard.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/Standard.java
new file mode 100644 (file)
index 0000000..916336e
--- /dev/null
@@ -0,0 +1,251 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.tools.ajdoc.Quietable;
+
+import com.sun.javadoc.RootDoc;
+import com.sun.tools.doclets.DocletAbortException;
+import com.sun.tools.doclets.standard.AllClassesFrameWriter;
+import com.sun.tools.doclets.standard.FrameOutputWriter;
+import com.sun.tools.doclets.standard.HelpWriter;
+import com.sun.tools.doclets.standard.PackageIndexFrameWriter;
+import com.sun.tools.doclets.standard.PackageIndexWriter;
+import com.sun.tools.doclets.standard.PackageListWriter;
+import com.sun.tools.doclets.standard.PackagesFileWriter;
+import com.sun.tools.doclets.standard.SerializedFormWriter;
+import com.sun.tools.doclets.standard.StylesheetWriter;
+
+import java.io.IOException;
+
+/**
+ * Main doclet for ajdoc.  It defines a number of
+ * passes to use in generating the documentation.
+ *
+ * @author Jeff Palm
+ */
+public class Standard extends AbstractStandard {
+    private static Standard SINGLETON; // todo: prefer early/final?
+    public static final Standard getSingleton() {
+        if (null == SINGLETON) {
+            SINGLETON = new Standard();
+        }
+        return SINGLETON;
+    }
+    private Standard() {}
+
+    public static boolean start(RootDoc root) throws IOException {
+        return start(getSingleton(), root);
+    }
+
+    public ConfigurationStandard getConfiguration() {
+        return (ConfigurationStandard)configuration();
+    }
+
+    public static void quiet() {
+        if (configuration().root instanceof Quietable) {
+            ((Quietable)configuration().root).quiet();
+        }
+    }
+    public static void speak() {
+        if (configuration().root instanceof Quietable) {
+            ((Quietable)configuration().root).speak();
+        }
+    }
+
+    public static class ClassUseMapperPass extends Pass {
+        protected boolean cond() {
+            return cs.classuse;
+        }
+        protected void gen() throws DocletAbortException {
+            ClassUseMapper.generate(root, std.classtree);
+        }
+        public String title() { return "class use mapper"; }
+    }
+
+    public static class TreeWriterPass extends Pass {
+        protected boolean cond() {
+            return cs.createtree;
+        }
+        protected void gen() throws DocletAbortException {
+            TreeWriter.generate(std.classtree);
+        }
+        public String title() { return "tree writer"; }
+    }
+
+    public static class SplitIndexWriterPass extends Pass {
+        protected boolean cond() {
+            return cs.createindex && cs.splitindex;
+        }
+        protected void gen() throws DocletAbortException {
+            SplitIndexWriter.generate(std.indexBuilder(root, false));
+        }
+        public String title() { return "split index"; }
+    }
+
+    public static class SingleIndexWriterPass extends Pass {
+        protected boolean cond() {
+            return cs.createindex && !cs.splitindex;
+        }
+        protected void gen() throws DocletAbortException {
+            SingleIndexWriter.generate(std.indexBuilder(root, false));
+        }
+        public String title() { return "single index"; }
+    }
+
+    public static class DeprecatedListWriterPass extends Pass {
+        protected boolean cond() {
+            return !cs.nodeprecatedlist && !cs.nodeprecated;
+        }
+        protected void gen() throws DocletAbortException {
+            DeprecatedListWriter.generate(root);
+        }
+        public String title() { return "deprecated list"; }
+    }
+
+    public static class AllClassesFrameWriterPass extends Pass {
+        protected void gen() throws DocletAbortException {
+            AllClassesFrameWriter.generate(std.indexBuilder(root, true));
+        }
+        public String title() { return "all classes frame"; }
+    }
+
+    public static class FrameOutputWriterPass extends Pass {
+        protected void gen() throws DocletAbortException {
+            FrameOutputWriter.generate();
+        }
+        public String title() { return "output frame"; }
+    }
+
+    public static class PackagesFileWriterPass extends Pass {
+        protected void gen() throws DocletAbortException {
+            PackagesFileWriter.generate();
+        }
+        public String title() { return "packages files"; }
+    }
+
+    public static class PackageIndexWriterPass extends Pass {
+        protected boolean cond(ConfigurationStandard cs) {
+            return cs.createoverview;
+        }
+        protected void gen() throws DocletAbortException {
+            PackageIndexWriter.generate(root);
+        }
+        public String title() { return "package index"; }
+    }
+    
+    public static class PackageIndexFrameWriterPass extends Pass {
+        protected boolean cond() {
+            return cs.packages.length > 1;
+        }
+        protected void gen() throws DocletAbortException {
+            PackageIndexFrameWriter.generate();
+        }
+        public String title() { return "package index frame"; }
+    }
+    
+    protected Class[] preGenerationClasses() {
+        return new Class[] {
+            ClassUseMapperPass.class,
+            TreeWriterPass.class,
+            SplitIndexWriterPass.class,
+            SingleIndexWriterPass.class,
+            DeprecatedListWriterPass.class,
+            AllClassesFrameWriterPass.class,
+            FrameOutputWriterPass.class,
+            PackagesFileWriterPass.class,
+            PackageIndexWriterPass.class,
+            PackageIndexFrameWriterPass.class,
+        };
+    }
+
+    public static class SerializedFormWriterPass extends Pass {
+        protected void gen() throws DocletAbortException {
+            SerializedFormWriter.generate(root);
+        }
+        public String title() { return "serialized form"; }
+    }
+
+    public static class PackageListWriterPass extends Pass {
+        protected void gen() throws DocletAbortException {
+            PackageListWriter.generate(root);
+        }
+        public String title() { return "package list"; }
+    }
+
+    public static class HelpWriterPass extends Pass {
+        protected boolean cond() {
+            return cs.helpfile.length() == 0 &&
+                !cs.nohelp;
+        }
+        protected void gen() throws DocletAbortException {
+            HelpWriter.generate();
+        }
+        public String title() { return "help"; }
+    }
+
+    public static class StylesheetWriterPass extends Pass {
+        protected boolean cond() {
+            return cs.stylesheetfile.length() == 0;
+        }
+        protected void gen() throws DocletAbortException {
+            StylesheetWriter.generate();
+        }
+        public String title() { return "style sheet"; }
+    }
+
+    
+    protected Class[] postGenerationClasses() {
+        return new Class[] {
+            SerializedFormWriterPass.class,
+            PackageListWriterPass.class,
+            HelpWriterPass.class,
+            StylesheetWriterPass.class,
+        };
+    }
+
+    public static class NoPublicClassesToDocumentCheck extends Check {
+        protected boolean cond() {
+            return root.classes().length == 0;
+        }
+        protected String message() {
+            return "doclet.No_Public_Classes_To_Document";
+        }
+    }
+    public static class NoNonDeprecatedClassToDocumentCheck extends Check {
+        protected boolean cond() {
+            return cs.topFile.length() == 0;
+        }
+        protected String message() {
+            return "doclet.No_Non_Deprecated_Classes_To_Document";
+        }
+    }
+
+    protected Class[] checkClasses() {
+        return new Class[] {
+            NoPublicClassesToDocumentCheck.class,
+            NoNonDeprecatedClassToDocumentCheck.class,
+        };
+    }
+} 
+        
+
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/Statics.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/Statics.java
new file mode 100644 (file)
index 0000000..55bcc80
--- /dev/null
@@ -0,0 +1,253 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AdviceDoc;
+import org.aspectj.ajdoc.AspectDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ProgramElementDoc;
+import com.sun.tools.doclets.Util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A splattering of misc. functionality.
+ *
+ * @author Jeff Palm
+ */
+public class Statics {
+
+    /**
+     * Returns a aspectj-world type String of <code>cd</code>.
+     *
+     * @return either aspect interface or class depending
+     *         on the type of <code>cd</code>.
+     */
+    public static String type(ClassDoc cd) {
+        return cd instanceof AspectDoc
+            ? "aspect" : cd.isInterface()
+            ? "interface" : "class";
+    }
+
+    /**
+     * Returns the link target for <code>member</code>.
+     *
+     * @param member the ProgramElementDoc in question.
+     * @return       the link target for <code>member</code>.
+     */
+    public static String where(ProgramElementDoc member) {
+        return member.name();
+    }
+
+    /**
+     * Returns the link label for <code>member</code>.
+     *
+     * @param member the ProgramElementDoc in question.
+     * @return       the link label for <code>member</code>.
+     */
+    public static String label(ProgramElementDoc member) {
+        return member.name();
+    }
+
+    /**
+     * Returns the link target for <code>member</code> from
+     * <code>cd</code>.
+     *
+     * @param cd     the class from which we're linking.
+     * @param member the ProgramElementDoc in question.
+     * @return       the link target for <code>member</code>.
+     */
+    public static String where(ClassDoc cd, ProgramElementDoc member) {
+        if (member instanceof AdviceDoc) {
+            return name(cd, (AdviceDoc)member).replace(' ','_').replace('#','-');
+        }
+        return member.name();
+    }
+
+    /**
+     * Returns the link label for <code>member</code> from
+     * <code>cd</code>.
+     *
+     * @param cd     the class from which we're linking.
+     * @param member the ProgramElementDoc in question.
+     * @return       the link target for <code>member</code>.
+     */
+    public static String label(ClassDoc cd, ProgramElementDoc member) {
+        return name(cd, member);
+    }
+
+    /**
+     * Returns the name for <code>member</code> from
+     * <code>cd</code>.  This is here because we don't
+     * want really print the name of advice.
+     *
+     * @param cd     the class from which we're printing.
+     * @param member the ProgramElementDoc in question.
+     * @return       the name for <code>member</code>.
+     */
+    public static String name(ClassDoc cd, ProgramElementDoc member) {
+        if (member instanceof AdviceDoc) {
+            return name(cd, (AdviceDoc)member);
+        }
+        return member.name();
+    }
+
+    /**
+     * Returns the String that should be printed for
+     * an advice's name.
+     *
+     * @param cd     the ClassDoc from where we're printing.
+     * @param advice the member in question.
+     * @return       correct printing name for <code>advice</code>.
+     */
+    public static String name(ClassDoc cd, AdviceDoc advice) {
+        String name = advice.name();
+        int num = 1;
+        for (Iterator i = advice(cd).iterator(); i.hasNext();) {
+            AdviceDoc ad = (AdviceDoc)i.next();
+            if (ad.equals(advice)) {
+                break;
+            }
+            if (ad.name().equals(name)) {
+                num++;
+            }
+        }
+        return name + " #" + num;
+    }
+
+    /**
+     * Returns the advice contained in <code>classdoc</code>.
+     *
+     * @param  cd ClassDoc in question.
+     * @return    a List with the {@link AdviceDoc}s
+     *            contained in <code>cd</code>.
+     */
+    public static List advice(ClassDoc classdoc) {
+        if (!(classdoc instanceof AspectDoc)) return Collections.EMPTY_LIST;
+        AdviceDoc[] advice = ((AspectDoc)classdoc).advice();
+        return advice == null ? Collections.EMPTY_LIST : Util.asList(advice);
+    }
+    
+    /**
+     * Returns an array of classes only.
+     *
+     * @param arr source array from where the ClassDocs in
+     *            the result will come.
+     * @return an array of ClassDoc containing only
+     *         classes, <b>no aspects</b>.
+     */
+    public static ClassDoc[] classes(ClassDoc[] arr) {
+        List list = new ArrayList();
+        for (int i = 0; i < arr.length; i++) {
+            if (!(arr[i] instanceof AspectDoc)) {
+                list.add(arr[i]);
+            }
+        }
+        return (ClassDoc[])list.toArray(new ClassDoc[list.size()]);
+    }
+
+    /**
+     * Returns a list of the classes found in the
+     * passed in list of types.
+     *
+     * @param types List of ClassDocs.
+     * @return      a List containing those ClassDocs in
+     *              <code>types</code> that <i>are not</i> aspects.
+     * @see         #types(List,boolean)
+     */
+    public static List classes(List types) {
+        return types(types, false);
+    }
+
+    /**
+     * Returns a list of the classes found in the
+     * passed in list of types.
+     *
+     * @param types List of ClassDocs.
+     * @return      a List containing those ClassDocs in
+     *              <code>types</code> that <i>are</i> aspects.
+     * @see         #types(List,boolean)
+     */
+    public static List aspects(List types) {
+        return types(types, true);
+    }
+
+    /**
+     * Returns a list of ClassDocs taken from <code>types</code>
+     * that are aspects iff <code>wantAspects</code>.
+     *
+     * @param types       source List of ClassDocs.
+     * @param wantAspects ClassDocs <i>c<i>in the resulting List will
+     *                    conform to the test:
+     *                    <code>c instanceof AspectDoc) == wantAspects<code>.
+     * @return            a List of ClassDocs all who conform to the test:
+     *                    <code>c instanceof AspectDoc) == wantAspects<code>.
+     */
+    public static List types(List types, boolean wantAspects) {
+        List list = new ArrayList();
+        for (Iterator i = types.iterator(); i.hasNext();) {
+            ClassDoc cd = (ClassDoc)i.next();
+            if ((cd instanceof AspectDoc) == wantAspects) {
+                list.add(cd);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Returns a prequalified class link to <code>cd</code> using
+     * the link target <code>where</code>.
+     *
+     * @param writer base writer to use.
+     * @param cd     class to where we're linking.
+     * @param where  link target.
+     * @return       prequalified class link using
+     *               <code>cd</code> and <code>where</code>.
+     */
+    public static String getPreQualifiedClassLink
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer, 
+         ClassDoc cd,
+         String where) {
+        return writer.getPkgName(cd) + writer.getClassLink(cd, where, cd.name());
+    }
+
+    /**
+     * Returns a prequalified class link to <code>cd</code> using
+     * the link target <code>where</code> returned by
+     * calling <code>getPreQualifiedClassLink</code>.
+     *
+     * @param writer base writer to use.
+     * @param cd     class to where we're linking.
+     * @param where  link target.
+     * @see          #getPreQualifiedClassLink
+     */
+    public static void printPreQualifiedClassLink
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer, 
+         ClassDoc cd,
+         String where) {
+        writer.print(getPreQualifiedClassLink(writer, cd, where));
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SubWriterHolderWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SubWriterHolderWriter.java
new file mode 100644 (file)
index 0000000..7325844
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ProgramElementDoc;
+import com.sun.tools.doclets.DocletAbortException;
+
+import java.io.IOException;
+
+public abstract class SubWriterHolderWriter
+    extends com.sun.tools.doclets.standard.SubWriterHolderWriter
+{
+    
+    public SubWriterHolderWriter(String filename) throws IOException {
+        super(filename);
+    }
+
+
+    public SubWriterHolderWriter(String path, String filename, String relpath) 
+                                 throws IOException, DocletAbortException {
+        super(path, filename, relpath);
+    }
+
+    public void printSummaryMember(AbstractSubWriter mw, ClassDoc cd, 
+                                   ProgramElementDoc member) {
+        super.printSummaryMember(mw, cd, member);
+        if (mw instanceof AbstractSubWriterAJ) {
+            AbstractSubWriterAJ aj = (AbstractSubWriterAJ)mw;
+            if (aj.hasCrosscuts(cd, member)) {
+                aj.printSummaryCrosscuts(cd, member);
+            }
+        }
+    }
+
+    public String getPreQualifiedClassLink(ClassDoc cd, String where) {
+        return getPkgName(cd) + getClassLink(cd, where, cd.name());
+    }
+    
+    public void printPreQualifiedClassLink(ClassDoc cd, String where) {
+        print(getPreQualifiedClassLink(cd, where));
+    }
+}
+
+
+
+
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SuperIntroductionSubWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/SuperIntroductionSubWriter.java
new file mode 100644 (file)
index 0000000..ade3dcc
--- /dev/null
@@ -0,0 +1,181 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import org.aspectj.ajdoc.AspectDoc;
+import org.aspectj.ajdoc.IntroducedSuperDoc;
+import org.aspectj.ajdoc.IntroductionDoc;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.ProgramElementDoc;
+import com.sun.javadoc.Type;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+public class SuperIntroductionSubWriter extends AbstractSubWriter {
+
+    protected Class delegateClass() {
+        return null; //XXX ????
+    }
+
+    public SuperIntroductionSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer,
+         AspectDoc ad)
+    {
+        super(writer, ad);
+    }
+    
+    public SuperIntroductionSubWriter
+        (com.sun.tools.doclets.standard.SubWriterHolderWriter writer)
+    {
+        super(writer);
+    }
+
+    protected final String keyName() { return "Super_Introduction"; }
+
+    public void printInheritedSummaryAnchor(ClassDoc cd) {}
+    public void printInheritedSummaryLabel(ClassDoc cd) {}
+    protected void printInheritedSummaryLink(ClassDoc cd, ProgramElementDoc ped) {}
+
+    protected void printSummaryLink(ClassDoc cd, ProgramElementDoc member) {
+        IntroducedSuperDoc intro = (IntroducedSuperDoc)member;
+        writer.codeEnd();
+        writer.printText("doclet.declare_parents");
+        print(' ');
+        Type[] targets = intro.targets();
+        for (int i = 0; i < targets.length; i++) {
+            if (i > 0) print(", ");
+            printTypeLink(targets[i]);
+        }
+        print(' ');
+        String str = intro.isImplements() ? "implements" : "extends";
+        writer.printClassLink(cd, link(intro), str, false);
+        print(' ');
+        Type[] types = intro.types();
+        for (int i = 0; i < types.length; i++) {
+            if (i > 0) print(", ");
+            printTypeLink(types[i]);
+        }
+
+    }
+
+    protected static String link(IntroducedSuperDoc intro) {
+        String str = intro.isImplements() ? "+implements" : "+extends";
+        Type[] types = intro.types();
+        str += "%";
+        for (int i = 0; i < types.length; i++) str += types[i].qualifiedTypeName();
+        str += "%";
+        ClassDoc[] targets = intro.targets();
+        for (int i = 0; i < targets.length; i++) str += targets[i].qualifiedTypeName();
+        return str;
+    }
+
+    protected void printSummaryType(ProgramElementDoc member) {}
+
+    protected void printBodyHtmlEnd(ClassDoc cd) {}
+
+    protected void nonfinalPrintMember(ProgramElementDoc member) {
+        IntroducedSuperDoc intro = (IntroducedSuperDoc)member;
+        writer.anchor(link(intro));
+        String head = intro.isImplements() ? "+implements " : "+extends ";
+        Type[] types = intro.types();
+        for (int i = 0; i < types.length; i++) {
+            head += (i > 0 ? ", " : "") + types[i].typeName();
+        }
+        printHead(head);
+        printFullComment(intro);
+    }
+
+    protected void printDeprecatedLink(ProgramElementDoc member) {
+        //TODO: ???
+    }
+
+    protected List getMembers(ClassDoc cd) {
+        if (!(cd instanceof AspectDoc)) return Collections.EMPTY_LIST;
+        IntroductionDoc[] introductions = ((AspectDoc)cd).introductions();
+        List list = new ArrayList();
+        if (introductions == null) return list;
+        for (int i = 0; i < introductions.length; i++) {
+            IntroductionDoc intro = introductions[i];
+            if (intro instanceof IntroducedSuperDoc) {
+                list.add(intro);
+            }
+        }
+        return list;
+    }
+
+    public void printCrosscuts(ClassDoc cd, ProgramElementDoc member) {
+        org.aspectj.ajdoc.IntroducedSuperDoc intro =
+            (org.aspectj.ajdoc.IntroducedSuperDoc)member;
+        ClassDoc[] targets = intro.targets();
+        if (targets.length > 0) {
+            writer.dt();
+            writer.boldText("doclet.Introduced_on");
+            writer.dd();
+            writer.code();
+            Set targetSet = new HashSet();
+            for (int i = 0; i < targets.length; i++) {
+                targetSet.add(targets[i]);
+            }
+            List targetList = new ArrayList(targetSet);
+            Collections.sort(targetList);
+            for (Iterator i = targetList.iterator(); i.hasNext();) {
+                ClassDoc target = (ClassDoc)i.next();
+                writer.printClassLink(target);
+                if (i.hasNext()) writer.print(", ");
+                
+            }
+            writer.codeEnd();
+        }
+    }
+
+    public void printSummaryCrosscuts(ClassDoc cd,
+                                      ProgramElementDoc member) {
+        Set set = new HashSet();
+        org.aspectj.ajdoc.IntroducedSuperDoc intro =
+            (org.aspectj.ajdoc.IntroducedSuperDoc)member;
+        ClassDoc[] targets = intro.targets();
+        for (int i = 0; i < targets.length; i++) {
+            set.add(targets[i]);
+        }
+        if (targets.length > 0) {
+            writer.boldText("doclet.Advises");
+            List list = new ArrayList(set);
+            Collections.sort(list);
+            for (Iterator i = list.iterator(); i.hasNext();) {
+                print(' ');
+                ClassDoc target = (ClassDoc)i.next();
+                writer.printClassLink(target);
+                if (i.hasNext()) print(",");
+            }
+        }
+    }
+
+    public boolean hasCrosscuts(ClassDoc cd, ProgramElementDoc member) {
+        return true;
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/TreeWriter.java b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/TreeWriter.java
new file mode 100644 (file)
index 0000000..4119176
--- /dev/null
@@ -0,0 +1,86 @@
+/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the debugger and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ */
+package org.aspectj.tools.doclets.standard;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.tools.doclets.ClassTree;
+import com.sun.tools.doclets.DocletAbortException;
+
+import java.io.IOException;
+import java.util.List;
+
+public class TreeWriter
+    extends com.sun.tools.doclets.standard.TreeWriter
+{
+    protected class Del extends AbstractTreeWriter {
+        public Del(String s, ClassTree c)
+            throws IOException, DocletAbortException {
+            super(s, c);
+        }
+        public void print(String s) {
+            TreeWriter.this.print(s);
+        }
+    }
+    final protected Del del;
+    {
+        Standard.quiet();
+        Del d = null;
+        try {
+            d = new Del(filename, classtree);
+        } catch (Exception e) {
+            Standard.configuration().standardmessage.
+                error("doclet.exception_encountered", 
+                      e+"", filename);
+        } finally {
+            del = d;
+            Standard.speak();
+        }
+    }
+    protected void generateLevelInfo(ClassDoc parent, List list) {
+        del.generateLevelInfo(parent, list);
+    }
+    protected void generateTree(List list, String heading) {
+        del.generateTree(list, heading);
+    }
+
+    public TreeWriter(String filename, ClassTree classtree)  
+        throws IOException, DocletAbortException {
+        super(filename, classtree);
+    }
+
+    public static void generate(ClassTree classtree) 
+                                throws DocletAbortException {
+        TreeWriter tw = null;
+        String filename = "overview-tree.html";
+        try {
+            (tw = new TreeWriter(filename, classtree)).
+                generateTreeFile();
+        } catch (IOException e) {
+            Standard.configuration().standardmessage.
+                error("doclet.exception_encountered",
+                      e+"", filename);
+            throw new DocletAbortException();
+        } finally {
+            if (tw != null) tw.close();
+        }
+    }
+}
diff --git a/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/resources/standard.properties b/aspectj-attic/ajdoc-src/org/aspectj/tools/doclets/standard/resources/standard.properties
new file mode 100644 (file)
index 0000000..cc0021e
--- /dev/null
@@ -0,0 +1,344 @@
+#
+doclet.exception_encountered= {0} encountered \n\
+\twhile attempting to create file: {1}
+doclet.perform_copy_exception_encountered= {0} encountered while \n\
+performing copy.
+doclet.exception={0} encountered \n\
+\twhile {1}.
+doclet.Contents=Contents
+doclet.Overview=Overview
+doclet.Window_Overview={0}: Overview
+doclet.Package=Package
+doclet.Window_Package={0}: Package {1}
+doclet.Window_ClassFile_label={0}: {1}
+doclet.Window_Packages_title={0}
+doclet.All_Packages=All Packages
+doclet.Tree=Tree
+doclet.Class_Hierarchy=Class Hierarchy
+doclet.Class_Aspect_Hierarchy=Class/Aspect Hierarchy
+doclet.Window_Class_Hierarchy={0}: Class/Aspect Hierarchy
+doclet.Window_Package_Class_Hierarchy={0}: {1} Class Hierarchy
+doclet.Interface_Hierarchy=Interface Hierarchy
+doclet.Aspect_Hierarchy=Aspect Hierarchy
+doclet.Prev=PREV
+doclet.Next=NEXT
+doclet.Prev_Class=PREV CLASS
+doclet.Next_Class=NEXT CLASS
+doclet.Prev_Package=PREV PACKAGE
+doclet.Next_Package=NEXT PACKAGE
+doclet.Prev_Letter=PREV LETTER
+doclet.Next_Letter=NEXT LETTER
+doclet.Show_Lists=SHOW LISTS
+doclet.Hide_Lists=HIDE LISTS
+doclet.Summary=SUMMARY: 
+doclet.Detail=DETAIL: 
+doclet.navInner=INNER
+doclet.navField=FIELD
+doclet.navField_Introduction=DECLARE FIELD
+doclet.navSuper_Introduction=DECLARE PARENTS
+doclet.navPointcut=POINTCUT
+doclet.navConstructor=CONSTRUCTOR
+doclet.navConstructor_Introduction=DECLARE CONSTRUCTOR
+doclet.navMethod=METHOD
+doclet.navMethod_Introduction=DECLARE METHOD
+doclet.navAdvice=ADVICE
+doclet.Index=Index
+doclet.Window_Single_Index={0}: Index
+doclet.Window_Split_Index={0}: {1}-Index
+doclet.Help=Help
+doclet.Interface=Interface
+doclet.Class=Class
+doclet.Aspect=Aspect
+doclet.interface=interface
+doclet.aspect=aspect
+doclet.class=class
+doclet.error=error
+doclet.exception=exception
+doclet.extends=extends
+doclet.dominates=dominates
+doclet.Package_private=(package private)
+doclet.implements=implements
+doclet.Since=Since: 
+doclet.Version=Version: 
+doclet.Author=Author: 
+doclet.See_Also=See Also: 
+doclet.introduced_by_parens=(declared in {0})
+doclet.by_parens= ({0} by {1})
+doclet.introduced_by=-- declared in {0}
+doclet.Introduced_on=Declared for:
+doclet.Introduced_from=Declared in:
+doclet.See=See: 
+doclet.File_not_found=File not found: {0}
+doclet.Package_Summary=Package Summary
+doclet.Interface_Summary=Interface Summary
+doclet.Exception_Summary=Exception Summary
+doclet.Error_Summary=Error Summary
+doclet.Class_Summary=Class Summary
+doclet.Aspect_Summary=Aspect Summary
+doclet.Inner_Class_Summary=Inner Class/Aspect Summary
+doclet.Field_Summary=Field Summary
+doclet.Field_Introduction_Summary=Summary of Fields Declared on Target Types
+doclet.Super_Introduction_Summary=Summary of Parent Types Declared on Target Types
+doclet.Pointcut_Summary=Pointcut Summary
+doclet.Constructor_Summary=Constructor Summary
+doclet.Constructor_Introduction_Summary=Summary of Constructors Declared on Target Types
+doclet.Method_Summary=Method Summary
+doclet.Method_Introduction_Summary=Summary of Methods Declared on Target Types
+doclet.Advice_Summary=Advice Summary
+doclet.Option_conflict=Option {0} conflicts with {1} 
+doclet.Option_reuse=Option reused: {0}
+doclet.MissingSerialTag=in class {0}, missing @serial tag for default serializable field: {1}.
+doclet.MissingSerialDataTag=in class {0}, missing @serialData tag in method {1}.
+doclet.Interfaces=Interfaces
+doclet.Exceptions=Exceptions
+doclet.Errors=Errors
+doclet.Classes=Classes
+doclet.Aspects=Aspects
+doclet.Packages=Packages
+doclet.All_Classes=All Classes/Aspects
+doclet.All_Superinterfaces=All Superinterfaces:
+doclet.All_Implemented_Interfaces=All Implemented Interfaces:
+doclet.Members=Members
+doclet.None=None
+doclet.CLASSES=CLASSES
+doclet.MEMBERS=MEMBERS
+doclet.NONE=NONE
+doclet.Inner_Classes_Inherited_From_Class=Inner classes/aspects inherited from class {0}
+doclet.Inner_Classes_Inherited_From=Inner classes/aspects inherited from {0} {1}
+doclet.Methods_Inherited_From_Class=Methods inherited from class {0}
+doclet.Methods_Inherited_From_Interface=Methods inherited from interface {0}
+doclet.Methods_Inherited_From=Methods inherited from {0} {1}
+doclet.Methods_Introduced_From=Methods declared in {0} {1}
+doclet.Constructors_Introduced_From=Constructors declared in {0} {1}
+doclet.Advice_Inherited_From_Aspect=Advice inherited from aspect {0}
+doclet.Advice_Inherited_From=Advice inherited from {0} {1}
+doclet.Fields_Inherited_From_Class=Fields inherited from class {0}
+doclet.Fields_Inherited_From_Interface=Fields inherited from interface {0}
+doclet.Fields_Inherited_From=Fields inherited from {0} {1}
+doclet.Fields_Introduced_From=Fields declared in {0} {1}
+doclet.Pointcuts_Inherited_From_Class=Pointcuts inherited from class {0}
+doclet.Pointcuts_Inherited_From_Interface=Pointcuts inherited from interface {0}
+doclet.Pointcuts_Inherited_From=Pointcuts inherited from {0} {1}
+doclet.Serializable=Serializable
+doclet.Externalizable=Externalizable
+doclet.Class_0_implements_serializable=Class {0} implements Serializable
+doclet.Serialized_Form=Serialized Form
+doclet.Serialized_Form_methods=Serialization Methods
+doclet.Serialized_Form_fields=Serialized Fields
+doclet.Serialized_Form_class=Serialization Overview
+doclet.Serializable_no_customization=No readObject or writeObject method declared.
+doclet.Super_Introduction_Detail=Parent Types Declared on Target Types
+doclet.Field_Detail=Field Detail
+doclet.Field_Introduction_Detail=Fields Declared on Target Types
+doclet.Pointcut_Detail=Pointcut Detail
+doclet.Method_Detail=Method Detail
+doclet.Method_Introduction_Detail=Methods Declared on Target Types
+doclet.Advice_Detail=Advice Detail
+doclet.Constructor_Detail=Constructor Detail
+doclet.Constructor_Introduction_Detail=Constructors Declared on Target Types
+doclet.Deprecated=Deprecated.
+doclet.Deprecated_class=This class is deprecated.
+doclet.navDeprecated=Deprecated
+doclet.Deprecated_List=Deprecated List
+doclet.Window_Deprecated_List={0}: Deprecated List
+doclet.Note_0_is_deprecated=Note: {0} is deprecated.
+doclet.Crosscuts=Affects:
+doclet.Crosscut_by=Affected by: 
+doclet.Advised_by=Affected by: 
+doclet.Advises=Affects:  
+doclet.Parameters=Parameters:
+doclet.Returns=Returns:
+doclet.SerialData=Serial Data:
+doclet.Throws=Throws:
+doclet.Overrides=Overrides:
+doclet.in_class={0} in class {1}
+doclet.Generating_0=Generating {0}...
+doclet.0_Fields_and_Methods=&quot;{0}&quot; Fields and Methods
+doclet.Index_of_Fields_and_Methods=Index of Fields and Methods
+doclet.Static_variable_in=Static variable in {0}
+doclet.Variable_in=Variable in {0}
+doclet.Constructor_for=Constructor for {0}
+doclet.Advice_in=Advice in {0}
+doclet.Pointcut_in=Pointcut in {0}
+doclet.Static_method_in=Static method in {0}
+doclet.Method_in=Method in {0}
+doclet.throws=throws
+doclet.package=package
+doclet.destination_directory_not_found_0=destination directory not found: {0} 
+doclet.MalformedURL=Malformed URL: {0}
+doclet.File_error=Error reading file: {0}
+doclet.URL_error=Error fetching URL: {0}
+doclet.Method_Summary=Method Summary
+doclet.No_Package_Comment_File=For Package {0} Package.Comment file not found
+doclet.No_Source_For_Class=Source information for class {0} not available.
+doclet.see.class_or_package_not_found=Tag {0}: Class or Package not found: {1}
+doclet.see.malformed_tag=Tag {0}: Malformed: {1}
+doclet.Inherited_API_Summary=Inherited API Summary
+doclet.Deprecated_API=Deprecated API
+doclet.Deprecated_Classes=Deprecated Classes
+doclet.Deprecated_Interfaces=Deprecated Interfaces
+doclet.Deprecated_Exceptions=Deprecated Exceptions
+doclet.Deprecated_Errors=Deprecated Errors
+doclet.Deprecated_Fields=Deprecated Fields
+doclet.Deprecated_Constructors=Deprecated Constructors
+doclet.Deprecated_Advices=Deprecated Advice
+doclet.Deprecated_Pointcuts=Deprecated Pointcuts
+doclet.Deprecated_Field_Introductions=Deprecated Fields Declared on Target Types
+doclet.Deprecated_Method_Introductions=Deprecated Methods Declared on Target Types
+doclet.Deprecated_Constructor_Introductions=Deprecated Constructors Declared on Target Types
+doclet.Deprecated_Super_Introductions=Deprecated Parent Types Declared on Target Types
+doclet.Deprecated_Methods=Deprecated Methods
+doclet.Frame_Output=Frame Output
+doclet.Docs_generated_by_Javadoc=Documentation generated by Javadoc.
+doclet.Generated_Docs_Untitled=Generated Documentation (Untitled)
+doclet.Blank=Blank
+doclet.Other_Packages=Other Packages
+doclet.Package_Description=Package {0} Description
+doclet.Description=Description
+doclet.Specified_By=Specified by: 
+doclet.in_interface={0} in interface {1}
+doclet.Subclasses=Direct Known Subclasses or Subaspects:
+doclet.Subinterfaces=All Known Subinterfaces:
+doclet.Implementing_Classes=All Known Implementing Classes:
+doclet.also=also
+doclet.Option=Option
+doclet.Or=Or
+doclet.Frames=Frames
+doclet.FRAMES=FRAMES
+doclet.NO_FRAMES=NO FRAMES
+doclet.Package_Hierarchies=Package Hierarchies: 
+doclet.Hierarchy_For_Package=Hierarchy For Package {0}
+doclet.Source_Code=Source Code:
+doclet.Help=Help
+doclet.Hierarchy_For_All_Packages=Hierarchy For All Packages
+doclet.Cannot_handle_no_packages=Cannot handle no packages.
+doclet.Frame_Alert=Frame Alert
+doclet.Overview-Member-Frame=Overview Member Frame
+doclet.Frame_Warning_Message=This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+doclet.Non_Frame_Version=Non-frame version.
+doclet.Frame_Version=Frame version
+doclet.Link_To=Link to 
+doclet.Following_From_Class=Following copied from class: {0}
+doclet.Following_From_Interface=Following copied from interface: {0}
+doclet.Description_From_Interface=Description copied from interface: {0}
+doclet.Description_From_Class=Description copied from class: {0}
+doclet.Copying_File_0_To_Dir_1=Copying file {0} to directory {1}...
+doclet.Copying_File_0_To_File_1=Copying file {0} to file {1}...
+doclet.Standard_doclet_invoked=Standard doclet invoked...
+doclet.No_Public_Classes_To_Document=No public or protected classes found to document.
+doclet.No_Non_Deprecated_Classes_To_Document=No non-deprecated classes found to document.
+doclet.Interfaces_Italic=Interfaces (italic)
+doclet.Enclosing_Class=Enclosing class: 
+doclet.All_Advisors:Known Advisors:
+doclet.All_Advisees:Known Advisees:
+doclet.Enclosing_=Enclosing {0}: 
+doclet.Help_title=API Help
+doclet.Window_Help_title={0}: API Help
+doclet.Help_line_1=How This API Document Is Organized
+doclet.Help_line_2=This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+doclet.Help_line_3=The {0} page is the front page of this API document and provides a list of all packages with a summary for each.  This page can also contain an overall description of the set of packages.
+doclet.Help_line_4=Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain five categories:
+doclet.Help_line_5=Class/Aspect/Interface
+doclet.Help_line_6=Each class, aspect, interface, inner class, inner aspect, and inner interface has its own separate page. Each of these pages has three sections consisting of a class/aspect/interface description, summary tables, and detailed member descriptions:
+doclet.Help_line_7=Class/aspect inheritance diagram
+doclet.Help_line_8=Direct Subclasses/Subaspects
+doclet.Help_line_9=All Known Subinterfaces
+doclet.Help_line_10=All Known Implementing Classes/Aspects
+doclet.Help_line_11=Class/aspect/interface declaration
+doclet.Help_line_12=Class/aspect/interface description
+doclet.Help_line_13=Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+doclet.Help_line_14=Use
+doclet.Help_line_15=Each documented package, class and interface has its own Use page.  This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A.  You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+doclet.Help_line_16=Tree (Class/Aspect Hierarchy)
+doclet.Help_line_17_with_tree_link=There is a {0} page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with <code>java.lang.Object</code>. The interfaces do not inherit from <code>java.lang.Object</code>.
+doclet.Help_line_18=When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
+doclet.Help_line_19=When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+doclet.Help_line_20_with_deprecated_api_link=The {0} page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+doclet.Help_line_21=Index
+doclet.Help_line_22=The {0} contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+doclet.Help_line_23=Prev/Next
+doclet.Help_line_24=These links take you to the next or previous class, interface, package, or related page.
+doclet.Help_line_25=Frames/No Frames
+doclet.Help_line_26=These links show and hide the HTML frames.  All pages are available with or without frames.
+doclet.Help_line_27=Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
+doclet.Help_line_28=This help file applies to API documentation generated using the standard doclet. 
+doclet.The=The
+doclet.Style_line_1=Javadoc style sheet
+doclet.Style_line_2=Define colors, fonts and other style attributes here to override the defaults 
+doclet.Style_line_3=Page background color
+doclet.Style_line_4=Table colors
+doclet.Style_line_5=Dark mauve
+doclet.Style_line_6=Light mauve
+doclet.Style_line_7=White
+doclet.Style_line_8=Font used in left-hand frame lists
+doclet.Style_line_9=Example of smaller, sans-serif font in frames
+doclet.Style_line_10=Navigation bar fonts and colors
+doclet.Style_line_11=Dark Blue
+doclet.ClassUse_Packages.that.use.0=Packages that use {0}
+doclet.ClassUse_Uses.of.0.in.1=Uses of {0} in {1}
+doclet.ClassUse_Classes.in.0.used.by.1=Classes in {0} used by {1}
+doclet.ClassUse_Aspects.in.0.used.by.1=Aspects in {0} used by {1}
+doclet.ClassUse_Subclass=Subclasses or subaspects of {0} in {1}
+doclet.ClassUse_Subinterface=Subinterfaces of {0} in {1}
+doclet.ClassUse_ImplementingClass=Classes in {1} that implement {0}
+doclet.ClassUse_Field=Fields in {1} declared as {0}
+
+doclet.ClassUse_AdviceReturn=Advice in {1} that return {0}
+doclet.ClassUse_AdviceArgs=Advice in {1} with parameters of type {0}
+doclet.ClassUse_PointcutReturn=Pointcuts in {1} that return {0}
+doclet.ClassUse_PointcutArgs=Pointcuts in {1} with parameters of type {0}
+doclet.ClassUse_FieldIntroductions={0} fields declared by aspects in {1}
+doclet.ClassUse_ClassIntroductions={0} parent class declarations by aspects in {1}
+doclet.ClassUse_InterfaceIntroductions={0} parent interface declarations by aspects in {1}
+doclet.ClassUse_ClassAdvisors=Aspects in {1} that affect {0}
+doclet.ClassUse_AspectDominatees=Aspects in {1} that are dominated by {0}
+doclet.ClassUse_AspectDominators=Aspects in {1} that dominate {0}
+
+doclet.ClassUse_MethodReturn=Methods in {1} that return {0}
+doclet.ClassUse_MethodArgs=Methods in {1} with parameters of type {0}
+doclet.ClassUse_MethodThrows=Methods in {1} that throw {0}
+doclet.ClassUse_ConstructorArgs=Constructors in {1} with parameters of type {0}
+doclet.ClassUse_ConstructorThrows=Constructors in {1} that throw {0}
+doclet.ClassUse_No.usage.of.0=No usage of {0}
+doclet.Window_ClassUse_Header={0}: Uses of {1} {2}
+doclet.ClassUse_Title=Uses of {0}<br>{1}
+doclet.navClassUse=Use
+doclet.link_option_twice=Extern URL link option(link or linkoffline) used twice.
+doclet.Error_in_packagelist=Error in using -group option: {0} {1} 
+doclet.Groupname_already_used=In -group option, groupname already used: {0}
+doclet.Same_package_name_used=Package name format used twice: {0}
+doclet.Packages_File_line_1=The front page has been relocated.
+doclet.Packages_File_line_2=Please see:
+doclet.usage=Provided by Standard doclet:\n\
+  -d <directory>            Destination directory for output files\n\
+  -use                      Create class and package usage pages\n\
+  -version                  Include @version paragraphs\n\
+  -author                   Include @author paragraphs\n\
+  -splitindex               Split index into one file per letter\n\
+  -windowtitle <text>       Browser window title for the documenation\n\
+  -doctitle <html-code>     Include title for the package index(first) page\n\
+  -header <html-code>       Include header text for each page\n\
+  -footer <html-code>       Include footer text for each page\n\
+  -bottom <html-code>       Include bottom text for each page\n\
+  -link <url>               Create links to javadoc output at <url>\n\
+  -linkoffline <url> <url2> Link to docs at <url> using package list at <url2>\n\
+  -group <name> <p1>:<p2>.. Group specified packages together in overview page\n\
+  -nodeprecated             Do not include @deprecated information\n\
+  -nosince                  Do not include @since information\n\
+  -nodeprecatedlist         Do not generate deprecated list\n\
+  -notree                   Do not generate class hierarchy\n\
+  -noindex                  Do not generate index\n\
+  -nohelp                   Do not generate help link\n\
+  -nonavbar                 Do not generate navigation bar\n\
+  -serialwarn               Generate warning about @serial tag\n\
+  -charset <charset>        Charset for cross-platform viewing of generated documentation.\n\
+  -helpfile <file>          Include file that help link links to\n\
+  -stylesheetfile <path>    File to change style of the generated documentation\n\
+  -docencoding <name>       Output encoding name
+doclet.xusage=Special  options:\n\
+  -Xnodate                  Do not include generation date in output
+doclet.pass_msg=[ {0} started ]
+doclet.done_msg=[ {0} done in {1} ms ]
+doclet.starting_internal_compile=Starting internal compile...
+doclet.initializing_world=Initializing world...
+doclet.declare_parents=declare parents:
diff --git a/aspectj-attic/ajdoc-testsrc/AjdocModuleTests.java b/aspectj-attic/ajdoc-testsrc/AjdocModuleTests.java
new file mode 100644 (file)
index 0000000..5105931
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the compiler and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+
+// default package
+
+import junit.framework.*;
+
+public class AjdocModuleTests extends TestCase {
+
+    public static Test suite() { 
+        TestSuite suite = new TestSuite(AjdocModuleTests.class.getName());
+        suite.addTest(org.aspectj.tools.ajdoc.AjdocTests.suite()); 
+        return suite;
+    }
+
+    public AjdocModuleTests(String name) { super(name); }
+
+}  
diff --git a/aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/AjdocTests.java b/aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/AjdocTests.java
new file mode 100644 (file)
index 0000000..6da9a0f
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This file is part of the compiler and core tools for the AspectJ(tm)
+ * programming language; see http://aspectj.org
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is AspectJ.
+ *
+ * The Initial Developer of the Original Code is Xerox Corporation. Portions
+ * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
+ * All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+
+package org.aspectj.tools.ajdoc;
+
+import junit.framework.*;
+
+public class AjdocTests extends TestCase {
+
+    public static Test suite() { 
+        TestSuite suite = new TestSuite(AjdocTests.class.getName());
+        //$JUnit-BEGIN$
+        suite.addTestSuite(SeeTagImplTest.class); 
+        //$JUnit-END$
+        return suite;
+    }
+
+    public AjdocTests(String name) { super(name); }
+
+}  
diff --git a/aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/JUnitDriver.java b/aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/JUnitDriver.java
new file mode 100644 (file)
index 0000000..a25029d
--- /dev/null
@@ -0,0 +1,117 @@
+package org.aspectj.tools.ajdoc;
+import junit.framework.Test;
+import junit.framework.Assert;
+import junit.textui.TestRunner;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.io.File;
+
+import org.aspectj.tools.ajdoc.Main;
+
+/** 
+ * Test driver for ajdoc
+ * currently only has disabled test cases to invoke ajdoc
+ * but not verify results.
+ * @deprecated org.aspectj.testing.harness.AjdocScript
+ */
+public class JUnitDriver extends TestCase {
+       private static final String[] ME 
+               = new String[] {"org.aspectj.tools.ajdoc.JUnitDriver"};
+       static final String ajbase = "c:/home/wes/aj";
+       static final String testbase = ajbase + "/aj-build-modules/tests/ajdoc/JUnitDriver";
+       static final String srcbase = ajbase + "/aspectj/modules/ajdoc/testsrc";
+
+       private AjdocTestCase[] CASES;
+       
+       protected void setUp() {
+           assertTrue(null == CASES);
+           System.setProperty("seetag.debug", "on");
+               CASES = new AjdocTestCase[]
+                       { // both disabled as samples not checked in
+                       // getLinkTestCase()
+                       //, getJUnitTestCase()
+                       };
+       }
+
+       AjdocTestCase getLinkTestCase() {
+               String outDir = testbase + "/link/api";
+
+               new File(outDir).mkdirs();      
+               return new AjdocTestCase("Link", new String[] 
+                       {
+                         "-d", outDir
+                       , "-private"
+                       , "-sourcepath", srcbase
+                       , "test"   // doc test package only
+                       });
+       }
+
+       AjdocTestCase getJUnitTestCase() {
+               String outDir =  "c:/home/doc/junit/api";
+
+               new File(outDir).mkdir();       
+               return new AjdocTestCase("JUnit", new String[] 
+                       {
+                         "-d", outDir
+                       , "-private"
+                       , "-sourcepath"
+                       , "c:/home/doc/junit/src"
+                       , "junitjunit.awtui"
+                       , "junit.extensions"
+                       , "junit.framework"
+                       , "junit.runner"
+                       , "junit.swingui"
+                       , "junit.swingui.icons"
+                       , "junit.textui"
+                       , "junit.ui"
+                       });
+       }
+       
+       public static void main(String[] args) {
+               
+               TestRunner.main(ME);
+       }
+
+    /** todo result logging? */
+    public static void log(String s) {
+        System.err.println(""+s);
+    }
+
+    /** load all KNOWN_TEST_CLASSES */
+    public static Test suite() { 
+        TestSuite result = new TestSuite();
+        result.addTestSuite(JUnitDriver.class);
+        return result;
+    }
+
+    //------------------ instance members 
+    public JUnitDriver(String name) { super(name); }
+
+       /**
+        * Run known test cases in CASES
+        */
+    public void testAll() {
+           assertTrue(null != CASES);
+       for (int i = 0; i < CASES.length; i++) {
+                       CASES[i].run(this);
+       }
+       
+    }
+    /** this just invokes AJDoc but does not verify results */
+    static class AjdocTestCase {
+        private final String label;
+       public final String[] args;
+        public AjdocTestCase(String label, String[] args) {
+                       this.label = (null == label ? "no label" : label);
+                       this.args = (null == args? new String[] {"help"} : args);
+        }
+       public void run(Assert assert) {
+               int result = Main.execute(args);                
+               assert.assertTrue("result: " + result,0 == result);
+               // now verify...
+       }
+    }
+
+}  
+
diff --git a/aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/SeeTagImplTest.java b/aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/SeeTagImplTest.java
new file mode 100644 (file)
index 0000000..4080a86
--- /dev/null
@@ -0,0 +1,493 @@
+package org.aspectj.tools.ajdoc;
+
+import junit.framework.Test;
+import junit.textui.TestRunner;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.Locale;
+
+import com.sun.javadoc.Doc;
+
+
+/**
+ */
+public class SeeTagImplTest  extends TestCase {
+       /**
+        * Run this class as a JUnit test case in the textui
+        */
+       public static void main(String[] args) {                
+               TestRunner.main(new String[]{"org.aspectj.tools.ajdoc.SeeTagImplTest"});
+       }
+
+    /** set to true to trigger assertion failures 
+     * on any output to error printer.
+     */
+       static boolean FAIL_ON_PRINTERR = false;
+
+    public static Test suite() { 
+        TestSuite result = new TestSuite();
+        result.addTestSuite(SeeTagImplTest.class);
+        return result;
+    }
+       // argh - our only dependency on the compiler module is here XXX
+       static ErrPrinter ERRPRINTER = new ErrPrinter("SeeTagImplTest") {
+        public void printError(String error) {
+            super.printError(error);
+            if (FAIL_ON_PRINTERR)
+                assertTrue(error, false);
+        }
+    };
+
+
+    public SeeTagImplTest(String name) { super(name); }
+
+       protected void setUp() {
+           try {
+                   System.setProperty("seetag.debug","on");
+           } catch (SecurityException e) {} // ignore - ok if property off
+       }               
+                               
+       static class SeeTestCase {
+               final String input;
+               final String type;
+               final String member;
+               final String parms;
+               final String label;
+               SeeTagImpl result;
+
+               public SeeTestCase(String input, String type, String member, 
+                                                       String parms, String label) {
+                       this.input = input;
+                       this.type = type;
+                       this.member = member;
+                       this.parms = parms;
+                       this.label = label;
+               }
+
+               /** 
+                * Run test.
+                * This implementation creates a SeeTagImpl to test 
+                * (only) SeeTagImpl.resolve().
+                */
+               public void run() {
+                   result = make(input);
+                       verify("label", label, result.getLabel());
+                   verify("type", type, renderType(result.getPackageName(), result.getClassName()));
+                       verify("memberName", renderMember(member, parms), result.getMemberName());
+               }
+
+               /** factory for SeeTag based on input normally passed to constructor */
+       SeeTagImpl make(String text) {
+           Doc doc = null;
+           String name = "@link";
+           Locale locale = Locale.getDefault();
+               return new SeeTagImpl(doc, name,text,locale,ERRPRINTER);
+       }
+
+               /** render for comment on error */
+               String renderSeeTagImpl(SeeTagImpl input) {
+                       if (null == input) return "(SeeTagImpl) null";
+                       String label = render(input.getLabel());
+                       return renderType(input.getPackageName(), input.getClassName())
+                               + "#" + input.getMemberName()
+                               + (0 == label.length()? "" : " " + label);
+               }
+               
+               String renderType(String pack, String cl) {
+                   cl = render(cl);
+                   pack = render(pack);
+                       return (0 == pack.length() ? "": pack + ".") + cl;
+               }
+               
+               String renderMember(String name, String parms) {
+                   name = render(name);
+                   parms = render(parms);
+                       return (0 == parms.length() ? name : name + parms);
+               }
+
+               /** render a null string as "" instead of "null" */
+               String render(String str) {
+                   return (null == str ? "" : str);
+               }
+
+               /** treat empty String as null String */
+               String normalize(String str) {
+                   if ((null == str) || (str.length() == 0)) {
+                       return null;
+                   } else {
+                       return str+"";
+                   }
+               }
+                               
+               /** 
+                * assert actual with expected,
+                * including label and entire input in message asserted.
+                */
+               void verify(String label, String expected, String actual) {
+                       expected = normalize(expected);
+                       actual = normalize(actual);
+                       String output = renderSeeTagImpl(result);
+                   String message = "\""+expected+"\".equals(\"" + actual + "\")" 
+                       + " // " + label
+                       + " (\"" + input + "\" -> \"" + output + "\")";
+                   if (null == expected) {
+                       assertTrue(message, null==actual);
+                   } else {
+                       assertTrue(message, expected.equals(actual));
+                   }
+               }
+               
+       }
+       // example of generated
+//     static SeeTestCase[] CASES = new SeeTestCase[] 
+//             { new SeeTestCase("Foo#bar() bash", "Foo", "bar", "()", "bash")
+//             };
+//     public void test1() { CASES[1].run(); }
+
+       // test cases generated by genSeeTestCases.sh
+    static final SeeTestCase[] CASES = new SeeTestCase[] { null // first is null
+        , new SeeTestCase("#memberName ",  "", "memberName", "", "")  // 0
+        , new SeeTestCase(" #memberName   ",  "", "memberName", "", "")
+        , new SeeTestCase("#memberName label",  "", "memberName", "", "label")  // 2
+        , new SeeTestCase(" #memberName  label ",  "", "memberName", "", "label")
+        , new SeeTestCase("#memberName a label",  "", "memberName", "", "a label")  // 4
+        , new SeeTestCase(" #memberName  a label ",  "", "memberName", "", "a label")
+        , new SeeTestCase("#memberName() ",  "", "memberName", "()", "")  // 6
+        , new SeeTestCase(" #memberName ()  ",  "", "memberName", "()", "")
+        , new SeeTestCase("#memberName() label",  "", "memberName", "()", "label")  // 8
+        , new SeeTestCase(" #memberName () label ",  "", "memberName", "()", "label")
+        , new SeeTestCase("#memberName() a label",  "", "memberName", "()", "a label")  // 10
+        , new SeeTestCase(" #memberName () a label ",  "", "memberName", "()", "a label")
+        , new SeeTestCase("#memberName(int) ",  "", "memberName", "(int)", "")  // 12
+        , new SeeTestCase(" #memberName (int)  ",  "", "memberName", "(int)", "")
+        , new SeeTestCase("#memberName(int) label",  "", "memberName", "(int)", "label")  // 14
+        , new SeeTestCase(" #memberName (int) label ",  "", "memberName", "(int)", "label")
+        , new SeeTestCase("#memberName(int) a label",  "", "memberName", "(int)", "a label")  // 16
+        , new SeeTestCase(" #memberName (int) a label ",  "", "memberName", "(int)", "a label")
+        , new SeeTestCase("#memberName(int,String) ",  "", "memberName", "(int,String)", "")  // 18
+        , new SeeTestCase(" #memberName (int,String)  ",  "", "memberName", "(int,String)", "")
+        , new SeeTestCase("#memberName(int,String) label",  "", "memberName", "(int,String)", "label")  // 20
+        , new SeeTestCase(" #memberName (int,String) label ",  "", "memberName", "(int,String)", "label")
+        , new SeeTestCase("#memberName(int,String) a label",  "", "memberName", "(int,String)", "a label")  // 22
+        , new SeeTestCase(" #memberName (int,String) a label ",  "", "memberName", "(int,String)", "a label")
+        , new SeeTestCase("#memberName( int , String[ ][ ] ) ",  "", "memberName", "( int , String[ ][ ] )", "")  // 24
+        , new SeeTestCase(" #memberName ( int , String[ ][ ] )  ",  "", "memberName", "( int , String[ ][ ] )", "")
+        , new SeeTestCase("#memberName( int , String[ ][ ] ) label",  "", "memberName", "( int , String[ ][ ] )", "label")  // 26
+        , new SeeTestCase(" #memberName ( int , String[ ][ ] ) label ",  "", "memberName", "( int , String[ ][ ] )", "label")
+        , new SeeTestCase("#memberName( int , String[ ][ ] ) a label",  "", "memberName", "( int , String[ ][ ] )", "a label")  // 28
+        , new SeeTestCase(" #memberName ( int , String[ ][ ] ) a label ",  "", "memberName", "( int , String[ ][ ] )", "a label")
+        , new SeeTestCase("#memberName( foo.Bar , com.sun.X ) ",  "", "memberName", "( foo.Bar , com.sun.X )", "")  // 30
+        , new SeeTestCase(" #memberName ( foo.Bar , com.sun.X )  ",  "", "memberName", "( foo.Bar , com.sun.X )", "")
+        , new SeeTestCase("#memberName( foo.Bar , com.sun.X ) label",  "", "memberName", "( foo.Bar , com.sun.X )", "label")  // 32
+        , new SeeTestCase(" #memberName ( foo.Bar , com.sun.X ) label ",  "", "memberName", "( foo.Bar , com.sun.X )", "label")
+        , new SeeTestCase("#memberName( foo.Bar , com.sun.X ) a label",  "", "memberName", "( foo.Bar , com.sun.X )", "a label")  // 34
+        , new SeeTestCase(" #memberName ( foo.Bar , com.sun.X ) a label ",  "", "memberName", "( foo.Bar , com.sun.X )", "a label")
+        , new SeeTestCase("#memberName(foo.Bar) ",  "", "memberName", "(foo.Bar)", "")  // 36
+        , new SeeTestCase(" #memberName (foo.Bar)  ",  "", "memberName", "(foo.Bar)", "")
+        , new SeeTestCase("#memberName(foo.Bar) label",  "", "memberName", "(foo.Bar)", "label")  // 38
+        , new SeeTestCase(" #memberName (foo.Bar) label ",  "", "memberName", "(foo.Bar)", "label")
+        , new SeeTestCase("#memberName(foo.Bar) a label",  "", "memberName", "(foo.Bar)", "a label")  // 40
+        , new SeeTestCase(" #memberName (foo.Bar) a label ",  "", "memberName", "(foo.Bar)", "a label")
+        , new SeeTestCase("Type#memberName ",  "Type", "memberName", "", "")  // 42
+        , new SeeTestCase(" Type#memberName   ",  "Type", "memberName", "", "")
+        , new SeeTestCase("Type#memberName label",  "Type", "memberName", "", "label")  // 44
+        , new SeeTestCase(" Type#memberName  label ",  "Type", "memberName", "", "label")
+        , new SeeTestCase("Type#memberName a label",  "Type", "memberName", "", "a label")  // 46
+        , new SeeTestCase(" Type#memberName  a label ",  "Type", "memberName", "", "a label")
+        , new SeeTestCase("Type#memberName() ",  "Type", "memberName", "()", "")  // 48
+        , new SeeTestCase(" Type#memberName ()  ",  "Type", "memberName", "()", "")
+        , new SeeTestCase("Type#memberName() label",  "Type", "memberName", "()", "label")  // 50
+        , new SeeTestCase(" Type#memberName () label ",  "Type", "memberName", "()", "label")
+        , new SeeTestCase("Type#memberName() a label",  "Type", "memberName", "()", "a label")  // 52
+        , new SeeTestCase(" Type#memberName () a label ",  "Type", "memberName", "()", "a label")
+        , new SeeTestCase("Type#memberName(int) ",  "Type", "memberName", "(int)", "")  // 54
+        , new SeeTestCase(" Type#memberName (int)  ",  "Type", "memberName", "(int)", "")
+        , new SeeTestCase("Type#memberName(int) label",  "Type", "memberName", "(int)", "label")  // 56
+        , new SeeTestCase(" Type#memberName (int) label ",  "Type", "memberName", "(int)", "label")
+        , new SeeTestCase("Type#memberName(int) a label",  "Type", "memberName", "(int)", "a label")  // 58
+        , new SeeTestCase(" Type#memberName (int) a label ",  "Type", "memberName", "(int)", "a label")
+        , new SeeTestCase("Type#memberName(int,String) ",  "Type", "memberName", "(int,String)", "")  // 60
+        , new SeeTestCase(" Type#memberName (int,String)  ",  "Type", "memberName", "(int,String)", "")
+        , new SeeTestCase("Type#memberName(int,String) label",  "Type", "memberName", "(int,String)", "label")  // 62
+        , new SeeTestCase(" Type#memberName (int,String) label ",  "Type", "memberName", "(int,String)", "label")
+        , new SeeTestCase("Type#memberName(int,String) a label",  "Type", "memberName", "(int,String)", "a label")  // 64
+        , new SeeTestCase(" Type#memberName (int,String) a label ",  "Type", "memberName", "(int,String)", "a label")
+        , new SeeTestCase("Type#memberName( int , String[ ][ ] ) ",  "Type", "memberName", "( int , String[ ][ ] )", "")  // 66
+        , new SeeTestCase(" Type#memberName ( int , String[ ][ ] )  ",  "Type", "memberName", "( int , String[ ][ ] )", "")
+        , new SeeTestCase("Type#memberName( int , String[ ][ ] ) label",  "Type", "memberName", "( int , String[ ][ ] )", "label")  // 68
+        , new SeeTestCase(" Type#memberName ( int , String[ ][ ] ) label ",  "Type", "memberName", "( int , String[ ][ ] )", "label")
+        , new SeeTestCase("Type#memberName( int , String[ ][ ] ) a label",  "Type", "memberName", "( int , String[ ][ ] )", "a label")  // 70
+        , new SeeTestCase(" Type#memberName ( int , String[ ][ ] ) a label ",  "Type", "memberName", "( int , String[ ][ ] )", "a label")
+        , new SeeTestCase("Type#memberName( foo.Bar , com.sun.X ) ",  "Type", "memberName", "( foo.Bar , com.sun.X )", "")  // 72
+        , new SeeTestCase(" Type#memberName ( foo.Bar , com.sun.X )  ",  "Type", "memberName", "( foo.Bar , com.sun.X )", "")
+        , new SeeTestCase("Type#memberName( foo.Bar , com.sun.X ) label",  "Type", "memberName", "( foo.Bar , com.sun.X )", "label")  // 74
+        , new SeeTestCase(" Type#memberName ( foo.Bar , com.sun.X ) label ",  "Type", "memberName", "( foo.Bar , com.sun.X )", "label")
+        , new SeeTestCase("Type#memberName( foo.Bar , com.sun.X ) a label",  "Type", "memberName", "( foo.Bar , com.sun.X )", "a label")  // 76
+        , new SeeTestCase(" Type#memberName ( foo.Bar , com.sun.X ) a label ",  "Type", "memberName", "( foo.Bar , com.sun.X )", "a label")
+        , new SeeTestCase("Type#memberName(foo.Bar) ",  "Type", "memberName", "(foo.Bar)", "")  // 78
+        , new SeeTestCase(" Type#memberName (foo.Bar)  ",  "Type", "memberName", "(foo.Bar)", "")
+        , new SeeTestCase("Type#memberName(foo.Bar) label",  "Type", "memberName", "(foo.Bar)", "label")  // 80
+        , new SeeTestCase(" Type#memberName (foo.Bar) label ",  "Type", "memberName", "(foo.Bar)", "label")
+        , new SeeTestCase("Type#memberName(foo.Bar) a label",  "Type", "memberName", "(foo.Bar)", "a label")  // 82
+        , new SeeTestCase(" Type#memberName (foo.Bar) a label ",  "Type", "memberName", "(foo.Bar)", "a label")
+        , new SeeTestCase("junit.Type#memberName ",  "junit.Type", "memberName", "", "")  // 84
+        , new SeeTestCase(" junit.Type#memberName   ",  "junit.Type", "memberName", "", "")
+        , new SeeTestCase("junit.Type#memberName label",  "junit.Type", "memberName", "", "label")  // 86
+        , new SeeTestCase(" junit.Type#memberName  label ",  "junit.Type", "memberName", "", "label")
+        , new SeeTestCase("junit.Type#memberName a label",  "junit.Type", "memberName", "", "a label")  // 88
+        , new SeeTestCase(" junit.Type#memberName  a label ",  "junit.Type", "memberName", "", "a label")
+        , new SeeTestCase("junit.Type#memberName() ",  "junit.Type", "memberName", "()", "")  // 90
+        , new SeeTestCase(" junit.Type#memberName ()  ",  "junit.Type", "memberName", "()", "")
+        , new SeeTestCase("junit.Type#memberName() label",  "junit.Type", "memberName", "()", "label")  // 92
+        , new SeeTestCase(" junit.Type#memberName () label ",  "junit.Type", "memberName", "()", "label")
+        , new SeeTestCase("junit.Type#memberName() a label",  "junit.Type", "memberName", "()", "a label")  // 94
+        , new SeeTestCase(" junit.Type#memberName () a label ",  "junit.Type", "memberName", "()", "a label")
+        , new SeeTestCase("junit.Type#memberName(int) ",  "junit.Type", "memberName", "(int)", "")  // 96
+        , new SeeTestCase(" junit.Type#memberName (int)  ",  "junit.Type", "memberName", "(int)", "")
+        , new SeeTestCase("junit.Type#memberName(int) label",  "junit.Type", "memberName", "(int)", "label")  // 98
+        , new SeeTestCase(" junit.Type#memberName (int) label ",  "junit.Type", "memberName", "(int)", "label")
+        , new SeeTestCase("junit.Type#memberName(int) a label",  "junit.Type", "memberName", "(int)", "a label")  // 100
+        , new SeeTestCase(" junit.Type#memberName (int) a label ",  "junit.Type", "memberName", "(int)", "a label")
+        , new SeeTestCase("junit.Type#memberName(int,String) ",  "junit.Type", "memberName", "(int,String)", "")  // 102
+        , new SeeTestCase(" junit.Type#memberName (int,String)  ",  "junit.Type", "memberName", "(int,String)", "")
+        , new SeeTestCase("junit.Type#memberName(int,String) label",  "junit.Type", "memberName", "(int,String)", "label")  // 104
+        , new SeeTestCase(" junit.Type#memberName (int,String) label ",  "junit.Type", "memberName", "(int,String)", "label")
+        , new SeeTestCase("junit.Type#memberName(int,String) a label",  "junit.Type", "memberName", "(int,String)", "a label")  // 106
+        , new SeeTestCase(" junit.Type#memberName (int,String) a label ",  "junit.Type", "memberName", "(int,String)", "a label")
+        , new SeeTestCase("junit.Type#memberName( int , String[ ][ ] ) ",  "junit.Type", "memberName", "( int , String[ ][ ] )", "")  // 108
+        , new SeeTestCase(" junit.Type#memberName ( int , String[ ][ ] )  ",  "junit.Type", "memberName", "( int , String[ ][ ] )", "")
+        , new SeeTestCase("junit.Type#memberName( int , String[ ][ ] ) label",  "junit.Type", "memberName", "( int , String[ ][ ] )", "label")  // 110
+        , new SeeTestCase(" junit.Type#memberName ( int , String[ ][ ] ) label ",  "junit.Type", "memberName", "( int , String[ ][ ] )", "label")
+        , new SeeTestCase("junit.Type#memberName( int , String[ ][ ] ) a label",  "junit.Type", "memberName", "( int , String[ ][ ] )", "a label")  // 112
+        , new SeeTestCase(" junit.Type#memberName ( int , String[ ][ ] ) a label ",  "junit.Type", "memberName", "( int , String[ ][ ] )", "a label")
+        , new SeeTestCase("junit.Type#memberName( foo.Bar , com.sun.X ) ",  "junit.Type", "memberName", "( foo.Bar , com.sun.X )", "")  // 114
+        , new SeeTestCase(" junit.Type#memberName ( foo.Bar , com.sun.X )  ",  "junit.Type", "memberName", "( foo.Bar , com.sun.X )", "")
+        , new SeeTestCase("junit.Type#memberName( foo.Bar , com.sun.X ) label",  "junit.Type", "memberName", "( foo.Bar , com.sun.X )", "label")  // 116
+        , new SeeTestCase(" junit.Type#memberName ( foo.Bar , com.sun.X ) label ",  "junit.Type", "memberName", "( foo.Bar , com.sun.X )", "label")
+        , new SeeTestCase("junit.Type#memberName( foo.Bar , com.sun.X ) a label",  "junit.Type", "memberName", "( foo.Bar , com.sun.X )", "a label")  // 118
+        , new SeeTestCase(" junit.Type#memberName ( foo.Bar , com.sun.X ) a label ",  "junit.Type", "memberName", "( foo.Bar , com.sun.X )", "a label")
+        , new SeeTestCase("junit.Type#memberName(foo.Bar) ",  "junit.Type", "memberName", "(foo.Bar)", "")  // 120
+        , new SeeTestCase(" junit.Type#memberName (foo.Bar)  ",  "junit.Type", "memberName", "(foo.Bar)", "")
+        , new SeeTestCase("junit.Type#memberName(foo.Bar) label",  "junit.Type", "memberName", "(foo.Bar)", "label")  // 122
+        , new SeeTestCase(" junit.Type#memberName (foo.Bar) label ",  "junit.Type", "memberName", "(foo.Bar)", "label")
+        , new SeeTestCase("junit.Type#memberName(foo.Bar) a label",  "junit.Type", "memberName", "(foo.Bar)", "a label")  // 124
+        , new SeeTestCase(" junit.Type#memberName (foo.Bar) a label ",  "junit.Type", "memberName", "(foo.Bar)", "a label")
+        , new SeeTestCase("org.aspectj.Type#memberName ",  "org.aspectj.Type", "memberName", "", "")  // 126
+        , new SeeTestCase(" org.aspectj.Type#memberName   ",  "org.aspectj.Type", "memberName", "", "")
+        , new SeeTestCase("org.aspectj.Type#memberName label",  "org.aspectj.Type", "memberName", "", "label")  // 128
+        , new SeeTestCase(" org.aspectj.Type#memberName  label ",  "org.aspectj.Type", "memberName", "", "label")
+        , new SeeTestCase("org.aspectj.Type#memberName a label",  "org.aspectj.Type", "memberName", "", "a label")  // 130
+        , new SeeTestCase(" org.aspectj.Type#memberName  a label ",  "org.aspectj.Type", "memberName", "", "a label")
+        , new SeeTestCase("org.aspectj.Type#memberName() ",  "org.aspectj.Type", "memberName", "()", "")  // 132
+        , new SeeTestCase(" org.aspectj.Type#memberName ()  ",  "org.aspectj.Type", "memberName", "()", "")
+        , new SeeTestCase("org.aspectj.Type#memberName() label",  "org.aspectj.Type", "memberName", "()", "label")  // 134
+        , new SeeTestCase(" org.aspectj.Type#memberName () label ",  "org.aspectj.Type", "memberName", "()", "label")
+        , new SeeTestCase("org.aspectj.Type#memberName() a label",  "org.aspectj.Type", "memberName", "()", "a label")  // 136
+        , new SeeTestCase(" org.aspectj.Type#memberName () a label ",  "org.aspectj.Type", "memberName", "()", "a label")
+        , new SeeTestCase("org.aspectj.Type#memberName(int) ",  "org.aspectj.Type", "memberName", "(int)", "")  // 138
+        , new SeeTestCase(" org.aspectj.Type#memberName (int)  ",  "org.aspectj.Type", "memberName", "(int)", "")
+        , new SeeTestCase("org.aspectj.Type#memberName(int) label",  "org.aspectj.Type", "memberName", "(int)", "label")  // 140
+        , new SeeTestCase(" org.aspectj.Type#memberName (int) label ",  "org.aspectj.Type", "memberName", "(int)", "label")
+        , new SeeTestCase("org.aspectj.Type#memberName(int) a label",  "org.aspectj.Type", "memberName", "(int)", "a label")  // 142
+        , new SeeTestCase(" org.aspectj.Type#memberName (int) a label ",  "org.aspectj.Type", "memberName", "(int)", "a label")
+        , new SeeTestCase("org.aspectj.Type#memberName(int,String) ",  "org.aspectj.Type", "memberName", "(int,String)", "")  // 144
+        , new SeeTestCase(" org.aspectj.Type#memberName (int,String)  ",  "org.aspectj.Type", "memberName", "(int,String)", "")
+        , new SeeTestCase("org.aspectj.Type#memberName(int,String) label",  "org.aspectj.Type", "memberName", "(int,String)", "label")  // 146
+        , new SeeTestCase(" org.aspectj.Type#memberName (int,String) label ",  "org.aspectj.Type", "memberName", "(int,String)", "label")
+        , new SeeTestCase("org.aspectj.Type#memberName(int,String) a label",  "org.aspectj.Type", "memberName", "(int,String)", "a label")  // 148
+        , new SeeTestCase(" org.aspectj.Type#memberName (int,String) a label ",  "org.aspectj.Type", "memberName", "(int,String)", "a label")
+        , new SeeTestCase("org.aspectj.Type#memberName( int , String[ ][ ] ) ",  "org.aspectj.Type", "memberName", "( int , String[ ][ ] )", "")  // 150
+        , new SeeTestCase(" org.aspectj.Type#memberName ( int , String[ ][ ] )  ",  "org.aspectj.Type", "memberName", "( int , String[ ][ ] )", "")
+        , new SeeTestCase("org.aspectj.Type#memberName( int , String[ ][ ] ) label",  "org.aspectj.Type", "memberName", "( int , String[ ][ ] )", "label")  // 152
+        , new SeeTestCase(" org.aspectj.Type#memberName ( int , String[ ][ ] ) label ",  "org.aspectj.Type", "memberName", "( int , String[ ][ ] )", "label")
+        , new SeeTestCase("org.aspectj.Type#memberName( int , String[ ][ ] ) a label",  "org.aspectj.Type", "memberName", "( int , String[ ][ ] )", "a label")  // 154
+        , new SeeTestCase(" org.aspectj.Type#memberName ( int , String[ ][ ] ) a label ",  "org.aspectj.Type", "memberName", "( int , String[ ][ ] )", "a label")
+        , new SeeTestCase("org.aspectj.Type#memberName( foo.Bar , com.sun.X ) ",  "org.aspectj.Type", "memberName", "( foo.Bar , com.sun.X )", "")  // 156
+        , new SeeTestCase(" org.aspectj.Type#memberName ( foo.Bar , com.sun.X )  ",  "org.aspectj.Type", "memberName", "( foo.Bar , com.sun.X )", "")
+        , new SeeTestCase("org.aspectj.Type#memberName( foo.Bar , com.sun.X ) label",  "org.aspectj.Type", "memberName", "( foo.Bar , com.sun.X )", "label")  // 158
+        , new SeeTestCase(" org.aspectj.Type#memberName ( foo.Bar , com.sun.X ) label ",  "org.aspectj.Type", "memberName", "( foo.Bar , com.sun.X )", "label")
+        , new SeeTestCase("org.aspectj.Type#memberName( foo.Bar , com.sun.X ) a label",  "org.aspectj.Type", "memberName", "( foo.Bar , com.sun.X )", "a label")  // 160
+        , new SeeTestCase(" org.aspectj.Type#memberName ( foo.Bar , com.sun.X ) a label ",  "org.aspectj.Type", "memberName", "( foo.Bar , com.sun.X )", "a label")
+        , new SeeTestCase("org.aspectj.Type#memberName(foo.Bar) ",  "org.aspectj.Type", "memberName", "(foo.Bar)", "")  // 162
+        , new SeeTestCase(" org.aspectj.Type#memberName (foo.Bar)  ",  "org.aspectj.Type", "memberName", "(foo.Bar)", "")
+        , new SeeTestCase("org.aspectj.Type#memberName(foo.Bar) label",  "org.aspectj.Type", "memberName", "(foo.Bar)", "label")  // 164
+        , new SeeTestCase(" org.aspectj.Type#memberName (foo.Bar) label ",  "org.aspectj.Type", "memberName", "(foo.Bar)", "label")
+        , new SeeTestCase("org.aspectj.Type#memberName(foo.Bar) a label",  "org.aspectj.Type", "memberName", "(foo.Bar)", "a label")  // 166
+        , new SeeTestCase(" org.aspectj.Type#memberName (foo.Bar) a label ",  "org.aspectj.Type", "memberName", "(foo.Bar)", "a label")
+        };
+    public void testLink1() { CASES[1].run(); }
+    public void testLink2() { CASES[2].run(); }
+    public void testLink3() { CASES[3].run(); }
+    public void testLink4() { CASES[4].run(); }
+    public void testLink5() { CASES[5].run(); }
+    public void testLink6() { CASES[6].run(); }
+    public void testLink7() { CASES[7].run(); }
+    public void testLink8() { CASES[8].run(); }
+    public void testLink9() { CASES[9].run(); }
+    public void testLink10() { CASES[10].run(); }
+    public void testLink11() { CASES[11].run(); }
+    public void testLink12() { CASES[12].run(); }
+    public void testLink13() { CASES[13].run(); }
+    public void testLink14() { CASES[14].run(); }
+    public void testLink15() { CASES[15].run(); }
+    public void testLink16() { CASES[16].run(); }
+    public void testLink17() { CASES[17].run(); }
+    public void testLink18() { CASES[18].run(); }
+    public void testLink19() { CASES[19].run(); }
+    public void testLink20() { CASES[20].run(); }
+    public void testLink21() { CASES[21].run(); }
+    public void testLink22() { CASES[22].run(); }
+    public void testLink23() { CASES[23].run(); }
+    public void testLink24() { CASES[24].run(); }
+    public void testLink25() { CASES[25].run(); }
+    public void testLink26() { CASES[26].run(); }
+    public void testLink27() { CASES[27].run(); }
+    public void testLink28() { CASES[28].run(); }
+    public void testLink29() { CASES[29].run(); }
+    public void testLink30() { CASES[30].run(); }
+    public void testLink31() { CASES[31].run(); }
+    public void testLink32() { CASES[32].run(); }
+    public void testLink33() { CASES[33].run(); }
+    public void testLink34() { CASES[34].run(); }
+    public void testLink35() { CASES[35].run(); }
+    public void testLink36() { CASES[36].run(); }
+    public void testLink37() { CASES[37].run(); }
+    public void testLink38() { CASES[38].run(); }
+    public void testLink39() { CASES[39].run(); }
+    public void testLink40() { CASES[40].run(); }
+    public void testLink41() { CASES[41].run(); }
+    public void testLink42() { CASES[42].run(); }
+    public void testLink43() { CASES[43].run(); }
+    public void testLink44() { CASES[44].run(); }
+    public void testLink45() { CASES[45].run(); }
+    public void testLink46() { CASES[46].run(); }
+    public void testLink47() { CASES[47].run(); }
+    public void testLink48() { CASES[48].run(); }
+    public void testLink49() { CASES[49].run(); }
+    public void testLink50() { CASES[50].run(); }
+    public void testLink51() { CASES[51].run(); }
+    public void testLink52() { CASES[52].run(); }
+    public void testLink53() { CASES[53].run(); }
+    public void testLink54() { CASES[54].run(); }
+    public void testLink55() { CASES[55].run(); }
+    public void testLink56() { CASES[56].run(); }
+    public void testLink57() { CASES[57].run(); }
+    public void testLink58() { CASES[58].run(); }
+    public void testLink59() { CASES[59].run(); }
+    public void testLink60() { CASES[60].run(); }
+    public void testLink61() { CASES[61].run(); }
+    public void testLink62() { CASES[62].run(); }
+    public void testLink63() { CASES[63].run(); }
+    public void testLink64() { CASES[64].run(); }
+    public void testLink65() { CASES[65].run(); }
+    public void testLink66() { CASES[66].run(); }
+    public void testLink67() { CASES[67].run(); }
+    public void testLink68() { CASES[68].run(); }
+    public void testLink69() { CASES[69].run(); }
+    public void testLink70() { CASES[70].run(); }
+    public void testLink71() { CASES[71].run(); }
+    public void testLink72() { CASES[72].run(); }
+    public void testLink73() { CASES[73].run(); }
+    public void testLink74() { CASES[74].run(); }
+    public void testLink75() { CASES[75].run(); }
+    public void testLink76() { CASES[76].run(); }
+    public void testLink77() { CASES[77].run(); }
+    public void testLink78() { CASES[78].run(); }
+    public void testLink79() { CASES[79].run(); }
+    public void testLink80() { CASES[80].run(); }
+    public void testLink81() { CASES[81].run(); }
+    public void testLink82() { CASES[82].run(); }
+    public void testLink83() { CASES[83].run(); }
+    public void testLink84() { CASES[84].run(); }
+    public void testLink85() { CASES[85].run(); }
+    public void testLink86() { CASES[86].run(); }
+    public void testLink87() { CASES[87].run(); }
+    public void testLink88() { CASES[88].run(); }
+    public void testLink89() { CASES[89].run(); }
+    public void testLink90() { CASES[90].run(); }
+    public void testLink91() { CASES[91].run(); }
+    public void testLink92() { CASES[92].run(); }
+    public void testLink93() { CASES[93].run(); }
+    public void testLink94() { CASES[94].run(); }
+    public void testLink95() { CASES[95].run(); }
+    public void testLink96() { CASES[96].run(); }
+    public void testLink97() { CASES[97].run(); }
+    public void testLink98() { CASES[98].run(); }
+    public void testLink99() { CASES[99].run(); }
+    public void testLink100() { CASES[100].run(); }
+    public void testLink101() { CASES[101].run(); }
+    public void testLink102() { CASES[102].run(); }
+    public void testLink103() { CASES[103].run(); }
+    public void testLink104() { CASES[104].run(); }
+    public void testLink105() { CASES[105].run(); }
+    public void testLink106() { CASES[106].run(); }
+    public void testLink107() { CASES[107].run(); }
+    public void testLink108() { CASES[108].run(); }
+    public void testLink109() { CASES[109].run(); }
+    public void testLink110() { CASES[110].run(); }
+    public void testLink111() { CASES[111].run(); }
+    public void testLink112() { CASES[112].run(); }
+    public void testLink113() { CASES[113].run(); }
+    public void testLink114() { CASES[114].run(); }
+    public void testLink115() { CASES[115].run(); }
+    public void testLink116() { CASES[116].run(); }
+    public void testLink117() { CASES[117].run(); }
+    public void testLink118() { CASES[118].run(); }
+    public void testLink119() { CASES[119].run(); }
+    public void testLink120() { CASES[120].run(); }
+    public void testLink121() { CASES[121].run(); }
+    public void testLink122() { CASES[122].run(); }
+    public void testLink123() { CASES[123].run(); }
+    public void testLink124() { CASES[124].run(); }
+    public void testLink125() { CASES[125].run(); }
+    public void testLink126() { CASES[126].run(); }
+    public void testLink127() { CASES[127].run(); }
+    public void testLink128() { CASES[128].run(); }
+    public void testLink129() { CASES[129].run(); }
+    public void testLink130() { CASES[130].run(); }
+    public void testLink131() { CASES[131].run(); }
+    public void testLink132() { CASES[132].run(); }
+    public void testLink133() { CASES[133].run(); }
+    public void testLink134() { CASES[134].run(); }
+    public void testLink135() { CASES[135].run(); }
+    public void testLink136() { CASES[136].run(); }
+    public void testLink137() { CASES[137].run(); }
+    public void testLink138() { CASES[138].run(); }
+    public void testLink139() { CASES[139].run(); }
+    public void testLink140() { CASES[140].run(); }
+    public void testLink141() { CASES[141].run(); }
+    public void testLink142() { CASES[142].run(); }
+    public void testLink143() { CASES[143].run(); }
+    public void testLink144() { CASES[144].run(); }
+    public void testLink145() { CASES[145].run(); }
+    public void testLink146() { CASES[146].run(); }
+    public void testLink147() { CASES[147].run(); }
+    public void testLink148() { CASES[148].run(); }
+    public void testLink149() { CASES[149].run(); }
+    public void testLink150() { CASES[150].run(); }
+    public void testLink151() { CASES[151].run(); }
+    public void testLink152() { CASES[152].run(); }
+    public void testLink153() { CASES[153].run(); }
+    public void testLink154() { CASES[154].run(); }
+    public void testLink155() { CASES[155].run(); }
+    public void testLink156() { CASES[156].run(); }
+    public void testLink157() { CASES[157].run(); }
+    public void testLink158() { CASES[158].run(); }
+    public void testLink159() { CASES[159].run(); }
+    public void testLink160() { CASES[160].run(); }
+    public void testLink161() { CASES[161].run(); }
+    public void testLink162() { CASES[162].run(); }
+    public void testLink163() { CASES[163].run(); }
+    public void testLink164() { CASES[164].run(); }
+    public void testLink165() { CASES[165].run(); }
+    public void testLink166() { CASES[166].run(); }
+    public void testLink167() { CASES[167].run(); }
+    public void testLink168() { CASES[168].run(); }
+
+       // end of test cases generated
+       
+}
+
+
+
diff --git a/aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/genSeeTestCases.sh b/aspectj-attic/ajdoc-testsrc/org/aspectj/tools/ajdoc/genSeeTestCases.sh
new file mode 100644 (file)
index 0000000..ab8e758
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/sh\r
+# generate test cases for {@link} tags\r
+\r
+## permitted variants:\r
+# - everything but member name can be empty\r
+# - spaces between everything except around sharp #\r
+# - 0..n parm types\r
+# - simple or qualified type names\r
+# - Type[ ][ ] but not Type [ ] [ ]\r
+# todo: \r
+# - URL's acceptable for link??\r
+\r
+count=0\r
+pre="        "\r
+echo "    static final SeeTestCase[] CASES = new SeeTestCase[] { null // first is null"\r
+\r
+for type in "" Type junit.Type org.aspectj.Type; do \r
+for name in memberName; do\r
+for parms in "" "()" "(int)" "(int,String)" "( int , String[ ][ ] )" "( foo.Bar , com.sun.X )" "(foo.Bar)"  ; do\r
+for label in "" label "a label"; do\r
+\r
+   # method, field X no spaces, spaces\r
+   echo "$pre, new SeeTestCase(\"$type#$name$parms $label\",  \"$type\", \"$name\", \"$parms\", \"$label\")  // $count"\r
+   echo "$pre, new SeeTestCase(\" $type#$name $parms $label \",  \"$type\", \"$name\", \"$parms\", \"$label\")"\r
+   count=`expr $count + 2`\r
+done; done; done; done;\r
+echo "${pre}};";\r
+\r
+i=0\r
+while [ $i -lt $count ] ; do\r
+   i=`expr $i + 1` # first is null\r
+   echo "    public void testLink$i() { CASES[$i].run(); }"\r
+done\r
+\r
+    \r
diff --git a/aspectj-attic/readme-aspectj-attic-module.html b/aspectj-attic/readme-aspectj-attic-module.html
new file mode 100644 (file)
index 0000000..3611c5b
--- /dev/null
@@ -0,0 +1,28 @@
+<html>
+<title>AspectJ attic</title>
+<body>
+<h1>AspectJ attic</h1>
+
+The AspectJ attic includes code that is unused now but might
+be part of at least investigations for future solutions.
+None of this code is used or distributed with AspectJ binaries.
+Some of it depends on code under other licenses.  That code is
+not included here, so this project does not compile.
+
+Dependencies not specified in the .project file:
+<ul>
+<li>ajdoc depends on the J2SE 1.3 tools.jar.
+    Other versions will not work.</li>
+<li>ajdoc depends on the AspectJ 1.0 compiler.
+    The 1.1 compiler will not work.</li>
+<li>The testing file-comparison uses jdiff code,
+    available from the JEdit sourceforge project
+    (http://sourceforge.net/projects/jedit) under GPL.
+    (Not to be confused with the jdiff sourceforge
+    project, which produces API differences.)
+    </li>
+</ul>
+
+See also any development notes in the respective source directories.
+</body>
+</html>
diff --git a/aspectj-attic/testing-src/AjcTaskTester.java b/aspectj-attic/testing-src/AjcTaskTester.java
new file mode 100644 (file)
index 0000000..0f9e728
--- /dev/null
@@ -0,0 +1,219 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+import java.io.*;
+import java.util.*;
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import org.apache.tools.ant.types.*;
+
+/**
+ * Tests the AJC ant task.
+ */
+public class AjcTaskTester extends AntTaskTester {
+
+    protected final static String TEST_CLASSES = "test-classes";
+    protected final static String TEST_SOURCES = "../src";
+    protected File buildDir = null;
+
+    /**
+     * We use <code>"tests/ant/etc/ajc.xml"</code>.
+     */
+    public String getAntFile() {
+        return "tests/ant/etc/ajc.xml";
+    }
+
+    /**
+     * Put {@link #TEST_CLASSES} and {@link #TEST_SOURCES}
+     * into the user properties.
+     */
+    protected Map getUserProperties() {
+        Map userProps = new HashMap();
+        userProps.put("ant.test.classes", TEST_CLASSES);
+        userProps.put("ant.test.sources", TEST_SOURCES);        
+        return userProps;
+    }
+
+    ////// Begin tests //////////////////////////////////////////////
+
+    public void test1() { wantClasses("One"); }
+    public void test2() { wantClasses("One,Two"); }
+    public void test3() { wantClasses("One,Two,Three"); }
+    public void test4() { wantClasses("One"); }
+    public void test4b() { wantClasses("One"); }
+    public void test5() { wantClasses("One,Two"); }
+    public void test5b() { wantClasses("One,Two"); }
+    public void test6() { wantClasses("One,Two,Three"); }
+    public void test6b() { wantClasses("One,Two,Three"); }
+    public void test8() { wantClasses("One"); }
+    public void test9() { wantClasses("One"); }
+    public void test10() { wantClasses("One"); }
+    public void test11() { wantClasses("One"); }
+    public void test12() { wantClasses(""); }
+    public void test13() { wantClasses("One"); }
+    public void fail1(BuildException be) {}
+    public void fail2(BuildException be) {}
+    public void fail3(BuildException be) {}
+
+    public void test1_fork() { wantClasses("One"); }
+    public void test2_fork() { wantClasses("One,Two"); }
+    public void test3_fork() { wantClasses("One,Two,Three"); }
+    public void test4_fork() { wantClasses("One"); }
+    public void test4b_fork() { wantClasses("One"); }
+    public void test5_fork() { wantClasses("One,Two"); }
+    public void test5b_fork() { wantClasses("One,Two"); }
+    public void test6_fork() { wantClasses("One,Two,Three"); }
+    public void test6b_fork() { wantClasses("One,Two,Three"); }
+    public void test8_fork() { wantClasses("One"); }
+    public void test9_fork() { wantClasses("One"); }
+    public void test10_fork() { wantClasses("One"); }
+    public void test11_fork() { wantClasses("One"); }
+    public void test12_fork() { wantClasses(""); }
+    public void test13_fork() { wantClasses("One"); }
+    public void fail1_fork(BuildException be) {}
+    public void fail2_fork(BuildException be) {}
+    public void fail3_fork(BuildException be) {}  
+
+    ////// End tests ////////////////////////////////////////////////
+
+    /**
+     * Make the build dir -- e.g. call {@link #makeBuildDir}
+     */
+    protected void beforeEveryTask() {
+        makeBuildDir();
+    }
+
+    /**
+     * Assert classes and clear build dir.
+     *
+     * @see #checkClasses()
+     * @see #clearBuildDir()
+     */
+    protected void afterEveryTask() {
+        checkClasses();
+        clearBuildDir();
+    }
+
+    /**
+     * Expect the classes found in
+     * <code>classNamesWithoutExtensions</code>
+     *
+     * @param classNamesWithoutExtensions Array of class names without
+     *                                    extensions we want to see.
+     * @see   #wantClasses(List)
+     */
+    protected void wantClasses(String[] classNamesWithoutExtensions) {
+        List list = new Vector();
+        for (int i = 0; i < classNamesWithoutExtensions.length; i++) {
+            list.add(classNamesWithoutExtensions[i]);
+        }
+        wantClasses(list);
+    }
+    
+    /**
+     * Expect the classes found in
+     * <code>classNamesWithoutExtensions</code>
+     *
+     * @param classNamesWithoutExtensions String of class names without
+     *                                    extensions we want to see separated
+     *                                    by <code> </code>, <code>,</code>, or
+     *                                    <code>;</code>.
+     * @see   #wantClasses(List)
+     */
+    protected void wantClasses(String classNamesWithoutExtensions) {
+        StringTokenizer tok = new StringTokenizer(classNamesWithoutExtensions, " ,;");
+        List list = new Vector();
+        while (tok.hasMoreTokens()) {
+            list.add(tok.nextToken());
+        }
+        wantClasses(list);
+    }
+
+    /**
+     * Expected each class name found in
+     * <code>classNamesWithoutExtensions</code>.
+     *
+     * @param classNamesWithoutExtensions List of class names without
+     *                                    exntensions.
+     * @see   #want(Object)
+     */
+    protected void wantClasses(List classNamesWithoutExtensions) {
+        Iterator iter = classNamesWithoutExtensions.iterator();
+        while (iter.hasNext()) {
+            String className = iter.next() + "";
+            className = className.replace('.', '/').replace('\\', '/');
+            want(className + ".class");
+        }
+    }
+
+    /**
+     * Assert that all classes in {@link #wants} were found.
+     */
+    protected void checkClasses() {
+        Iterator iter = wants.iterator();
+        while (iter.hasNext()) {
+            String className = iter.next() + "";
+            File file = new File(buildDir, className);
+            if (file != null && file.exists()) {
+                have(className);
+            }
+        }
+    }
+
+    /**
+     * Create a new build dir.
+     */
+    protected void init() {
+        buildDir = new File(project.getBaseDir(), TEST_CLASSES);
+    }
+
+    /**
+     * Make a new build dir using ANT.
+     */
+    protected void makeBuildDir() {
+        try {
+            Mkdir mkdir = (Mkdir)project.createTask("mkdir");
+            mkdir.setDir(buildDir);
+            mkdir.execute();
+        } catch (BuildException be) {
+            be.printStackTrace();
+        }
+    }
+
+    /**
+     * Clear the build dir using ANT.
+     */
+    protected void clearBuildDir() {
+        try {
+            Delete delete = (Delete)project.createTask("delete");
+            FileSet fileset = new FileSet();
+            fileset.setDir(buildDir);
+            fileset.setIncludes("**");
+            delete.addFileset(fileset);
+            delete.execute();
+        } catch (BuildException be) {
+            be.printStackTrace();
+        }        
+    }
+
+    /**
+     * Invoke {@link #runTests(String[])} on a
+     * new instanceof {@link #AjcTaskTester}.
+     *
+     * @param args Command line arguments.
+     */
+    public static void main(String[] args) {
+        new AjcTaskTester().runTests(args);
+    }
+}
diff --git a/aspectj-attic/testing-src/AjcTaskTester2.java b/aspectj-attic/testing-src/AjcTaskTester2.java
new file mode 100644 (file)
index 0000000..f5c5b36
--- /dev/null
@@ -0,0 +1,202 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+import java.io.*;
+import java.util.*;
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import org.apache.tools.ant.types.*;
+
+
+/**
+ * Tests the AJC2 ant task.
+ */
+public class AjcTaskTester2 extends AntTaskTester {
+
+    protected final static String TEST_CLASSES = "test-classes";
+    protected final static String TEST_SOURCES = "../src";
+    protected File buildDir = null;
+
+    /**
+     * We use <code>"tests/ant/etc/ajc2.xml"</code>.
+     */
+    public String getAntFile() {
+        return "tests/ant/etc/ajc2.xml";
+    }
+
+    /**
+     * Put {@link #TEST_CLASSES} and {@link #TEST_SOURCES}
+     * into the user properties.
+     */
+    protected Map getUserProperties() {
+        Map userProps = new HashMap();
+        userProps.put("ant.test.classes", TEST_CLASSES);
+        userProps.put("ant.test.sources", TEST_SOURCES);        
+        return userProps;
+    }
+
+    ////// Begin tests //////////////////////////////////////////////
+
+    public void test1()   { wantClasses("One"); }
+    public void test2()   { wantClasses("One,Two"); }
+    public void test3()   { wantClasses("One,Two,Three"); }
+    public void test4()   { wantClasses("One"); }
+    public void test4b()  { wantClasses("One"); }
+    public void test5()   { wantClasses("One,Two"); }
+    public void test5b()  { wantClasses("One,Two"); }
+    public void test6()   { wantClasses("One,Two,Three"); }
+    public void test6b()  { wantClasses("One,Two,Three"); }
+    public void test8()   { wantClasses("One"); }
+    public void test9()   { wantClasses("One"); }
+    public void test10()  { wantClasses("One"); }
+    public void test11()  { wantClasses("One"); }
+    public void test12()  { wantClasses(""); }
+    public void test13()  { wantClasses("One"); }
+    public void fail1(BuildException be) {}
+    public void fail2(BuildException be) {}
+    public void fail3(BuildException be) {}   
+
+    ////// End tests ////////////////////////////////////////////////
+
+    /**
+     * Make the build dir -- e.g. call {@link #makeBuildDir}
+     */
+    protected void beforeEveryTask() {
+        makeBuildDir();
+    }
+
+    /**
+     * Assert classes and clear build dir.
+     *
+     * @see #checkClasses()
+     * @see #clearBuildDir()
+     */
+    protected void afterEveryTask() {
+        checkClasses();
+        clearBuildDir();
+    }
+
+
+    /**
+     * Expect the classes found in
+     * <code>classNamesWithoutExtensions</code>
+     *
+     * @param classNamesWithoutExtensions Array of class names without
+     *                                    extensions we want to see.
+     * @see   #wantClasses(List)
+     */
+    protected void wantClasses(String[] classNamesWithoutExtensions) {
+        List list = new Vector();
+        for (int i = 0; i < classNamesWithoutExtensions.length; i++) {
+            list.add(classNamesWithoutExtensions[i]);
+        }
+        wantClasses(list);
+    }
+    
+    /**
+     * Expect the classes found in
+     * <code>classNamesWithoutExtensions</code>
+     *
+     * @param classNamesWithoutExtensions String of class names without
+     *                                    extensions we want to see separated
+     *                                    by <code> </code>, <code>,</code>, or
+     *                                    <code>;</code>.
+     * @see   #wantClasses(List)
+     */
+    protected void wantClasses(String classNamesWithoutExtensions) {
+        StringTokenizer tok = new StringTokenizer(classNamesWithoutExtensions, ",;");
+        List list = new Vector();
+        while (tok.hasMoreTokens()) {
+            list.add(tok.nextToken());
+        }
+        wantClasses(list);
+    }
+
+    /**
+     * Expected each class name found in
+     * <code>classNamesWithoutExtensions</code>.
+     *
+     * @param classNamesWithoutExtensions List of class names without
+     *                                    exntensions.
+     * @see   #want(Object)
+     */
+    protected void wantClasses(List classNamesWithoutExtensions) {
+        Iterator iter = classNamesWithoutExtensions.iterator();
+        while (iter.hasNext()) {
+            String className = iter.next() + "";
+            className = className.replace('.', '/').replace('\\', '/');
+            want(className + ".class");
+        }
+    }
+
+    /**
+     * Assert that all classes in {@link #wants} were found.
+     */
+    protected void checkClasses() {
+        Iterator iter = wants.iterator();
+        while (iter.hasNext()) {
+            String className = iter.next() + "";
+            File file = new File(buildDir, className);
+            if (file != null && file.exists()) {
+                have(className);
+            }
+        }
+    }
+
+    /**
+     * Create a new build dir.
+     */
+    protected void init() {
+        buildDir = new File(project.getBaseDir(), TEST_CLASSES);
+    }
+
+    /**
+     * Make a new build dir using ANT.
+     */
+    protected void makeBuildDir() {
+        try {
+            Mkdir mkdir = (Mkdir)project.createTask("mkdir");
+            mkdir.setDir(buildDir);
+            mkdir.execute();
+        } catch (BuildException be) {
+            be.printStackTrace();
+        }
+    }
+
+    /**
+     * Clear the build dir using ANT.
+     */
+    protected void clearBuildDir() {
+        try {
+            Delete delete = (Delete)project.createTask("delete");
+            FileSet fileset = new FileSet();
+            fileset.setDir(buildDir);
+            fileset.setIncludes("**");
+            delete.addFileset(fileset);
+            delete.execute();
+        } catch (BuildException be) {
+            be.printStackTrace();
+        }        
+    }
+
+    /**
+     * Invoke {@link #runTests(String[])} on a
+     * new instanceof {@link #AjcTaskTester2}.
+     *
+     * @param args Command line arguments.
+     */
+    public static void main(String[] args) {
+        new AjcTaskTester2().runTests(args);
+    }
+}
diff --git a/aspectj-attic/testing-src/AjdocTaskTester.java b/aspectj-attic/testing-src/AjdocTaskTester.java
new file mode 100644 (file)
index 0000000..a0e3970
--- /dev/null
@@ -0,0 +1,366 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+import java.io.*;
+import java.util.*;
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import org.apache.tools.ant.types.*;
+
+/**
+ * Tests the Ajdoc ant task.
+ */
+public class AjdocTaskTester extends AntTaskTester {
+
+    /** todo correlate with basedir, local.properties in test-ant-task */
+    protected final static String TEST_DOCDIR  
+        = "test-docs";
+    protected final static String TEST_SOURCES = "../src";
+    protected File docDir = null;
+
+    /**
+     * We use <code>"tests/ant/etc/ajc.xml"</code>.
+     */
+    public String getAntFile() {
+        return "tests/ant/etc/ajdoc.xml";
+    }
+
+    /**
+     * Put {@link #TEST_DOCDIR} and {@link #TEST_SOURCES}
+     * into the user properties.
+     */
+    protected Map getUserProperties() {
+        Map userProps = new HashMap();
+        // these are in local.properties per test-ant-tasks.xml
+        //userProps.put("ajdoc.relative.doc.dir", TEST_DOCDIR );
+        //userProps.put("ajdoc.relative.src.dir", TEST_SOURCES);        
+        return userProps;
+    }
+
+    ////// Begin tests //////////////////////////////////////////////
+
+    public void test_stylesheetfile() {
+        avoid(STYLESHEET_CSS);
+        wantFiles("One.html");
+        wantFiles("mystylesheet.css");
+    }
+
+    public void test_helpfile() {
+        avoid(HELP_DOC_HTML);
+        wantFiles("One.html");
+        wantFiles("myhelp.html");
+    }
+
+    public void test_nodeprecatedlist_no() {
+        wantFiles("One.html");
+    }
+    public void test_nodeprecatedlist_yes() {
+        avoid(DEPRECATED_LIST_HTML);
+        wantFiles("One.html");
+    }
+
+    public void test_nodeprecated_no() { wantFiles("One.html"); }
+    public void test_nodeprecated_yes() { wantFiles("One.html"); }
+
+    public void test_use_no() {
+        wantFiles("One.html");
+    }
+    public void test_use_yes() {
+        wantFiles("One.html");
+        wantFiles("class-use/One.html");
+    }
+
+    public void test_standard_no() {
+        wantFiles("One.html");
+    }
+    public void test_standard_yes() {
+        wantFiles("One.html");
+    }
+
+    public void test_author_no() { wantFiles("One.html"); }
+    public void test_author_yes() { wantFiles("One.html"); }
+
+    public void test_public_no() { wantFiles("One.html"); }
+    public void test_public_yes() { wantFiles("One.html"); }
+    public void test_package_no() { wantFiles("One.html"); }
+    public void test_package_yes() { wantFiles("One.html"); }
+    public void test_protected_no() { wantFiles("One.html"); }
+    public void test_protected_yes() { wantFiles("One.html"); }
+    public void test_private_no() { wantFiles("One.html"); }
+    public void test_private_yes() { wantFiles("One.html"); }
+
+    public void test_splitindex_no() {
+        wantFiles("One.html");
+    }
+    public void test_splitindex_yes() {
+        avoid(INDEX_ALL_HTML);
+        wantFiles("One.html");
+    }
+    
+    public void test_windowtitle() {
+        wantFiles("One.html");
+    }
+    public void test_doctitle() {
+        wantFiles("One.html");
+    }
+    public void test_bottom() {
+        wantFiles("One.html");
+    }
+    public void test_footer() {
+        wantFiles("One.html");
+    }
+    public void test_header() {
+        wantFiles("One.html");
+    }
+
+    public void test_nohelp_no() {
+        wantFiles("One.html");
+    }
+    public void test_nohelp_yes() {
+        avoid(HELP_DOC_HTML);
+        wantFiles("One.html");
+    }
+
+    public void test_noindex_no() {
+        wantFiles("One.html");
+    }
+    public void test_noindex_yes() {
+        avoid(INDEX_ALL_HTML);
+        wantFiles("One.html");
+    }
+
+    public void test_notree_no() {
+        wantFiles("One.html");
+    }
+    public void test_notree_yes() {
+        avoid(OVERVIEW_TREE_HTML);
+        wantFiles("One.html");
+    }
+
+    public void test985() {
+        wantFiles("p1/One.html,p1/pp1/One.html");
+        wantFiles("p2/Two.html,p2/pp2/Two.html");
+    }
+    public void test986() {
+        wantFiles("p1/One.html,p1/pp1/One.html");
+    }
+    public void test987() {
+        wantFiles("p1/One.html");
+        wantFiles("p2/Two.html");
+    }
+    public void test988() {
+        wantFiles("p1/One.html");
+    }
+    public void test989() {
+        wantFiles("p1/One.html,p1/pp1/One.html");
+        wantFiles("p2/Two.html,p2/pp2/Two.html");
+    }
+    public void test990() {
+        wantFiles("p1/One.html,p1/pp1/One.html");
+        wantFiles("p2/Two.html,p2/pp2/Two.html");
+    }
+    public void test991() {
+        wantFiles("p1/One.html,p1/pp1/One.html");
+        wantFiles("p2/Two.html");
+    }
+    public void test992() {
+        wantFiles("p1/One.html,p2/Two.html");
+    }
+    public void test993() {
+        wantFiles("p1/One.html,p1/pp1/One.html");
+    }
+    public void test994() {
+        wantFiles("p1/One.html,p1/pp1/One.html");
+    }
+    public void test995() {
+        wantFiles("p1/One.html");
+    }
+    public void test996() {
+        wantFiles("One.html,Two.html");
+    }
+    public void test997() {
+        wantFiles("One.html");
+    }
+    public void test998() {
+        wantFiles("One.html,Two.html");
+    }
+    public void test999() {
+        wantFiles("One.html");
+    }
+
+
+
+    ////// End tests ////////////////////////////////////////////////
+
+    private final static int OVERVIEW_TREE_HTML           = 0x000001;
+    private final static int INDEX_ALL_HTML               = 0x000002;
+    private final static int DEPRECATED_LIST_HTML         = 0x000004;
+    private final static int ALLCLASSES_FRAME_HTML        = 0x000008;
+    private final static int INDEX_HTML                   = 0x000010;
+    private final static int PACKAGES_HTML                = 0x000020;
+    private final static int OVERVIEW_SUMMARY_HTML        = 0x000040;
+    private final static int PACKAGE_LIST                 = 0x000080;
+    private final static int HELP_DOC_HTML                = 0x000100;
+    private final static int STYLESHEET_CSS               = 0x000200;
+    private final static int ALL                          = 0x0003ff;
+    private final static int TOP                          = ((ALL<<1)|1)&~ALL;
+    private final static String[] FILES = new String[] {
+        "overview-tree.html",
+        "index-all.html",
+        "deprecated-list.html",
+        "allclasses-frame.html",
+        "index.html",
+        "packages.html",
+        "overview-summary.html",
+        "package-list",
+        "help-doc.html",
+        "stylesheet.css",
+    };
+
+    private void wantFiles(int mods) {
+        mods &= (ALL | TOP);
+
+        for (int c = 0; mods != 0x1; c++, mods >>= 0x1) {
+            if ((mods & 0x1) == 0x1) {
+                wantFiles(FILES[c]);
+            } else {
+                avoidFiles(FILES[c]);
+            }
+        }
+    }
+
+    private int MODS = ALL;
+    private void avoid(int mods) {
+        MODS &= ~mods;
+    }
+
+    /**
+     * Make the doc dir -- e.g. call {@link #makeDocDir}
+     */
+    protected void beforeEveryTask() {
+        makeDocDir();
+        wantFiles(MODS);
+    }
+
+    /**
+     * Assert classes and clear doc dir.
+     *
+     * @see #checkDocs()
+     * @see #clearDocDir()
+     */
+    protected void afterEveryTask() {
+        checkDocs();
+        clearDocDir();
+        MODS = ALL;
+    }
+
+    protected void avoidFiles(String filesWithoutHtmlExtensions) {
+        List list = new ArrayList();
+        for (StringTokenizer tok =
+                 new StringTokenizer(filesWithoutHtmlExtensions, " ,;");
+             tok.hasMoreTokens();) {
+            list.add(tok.nextToken());
+        }
+        avoidFiles(list);
+    }
+
+    protected void avoidFiles(List filesWithoutHtmlExtensions) {
+        for (Iterator iter = filesWithoutHtmlExtensions.iterator(); iter.hasNext();) {
+            dont(iter.next()+"");
+        }
+    }
+
+    protected void wantFiles(String filesWithoutHtmlExtensions) {
+        List list = new ArrayList();
+        for (StringTokenizer tok =
+                 new StringTokenizer(filesWithoutHtmlExtensions, " ,;");
+             tok.hasMoreTokens();) {
+            list.add(tok.nextToken());
+        }
+        wantFiles(list);
+    }
+
+    protected void wantFiles(List filesWithoutHtmlExtensions) {
+        for (Iterator iter = filesWithoutHtmlExtensions.iterator(); iter.hasNext();) {
+            want(iter.next()+"");
+        }
+    }
+
+    protected void checkDocs() {
+        for (Iterator iter = wants.iterator(); iter.hasNext();) {
+            String filename = iter.next() + "";
+            File file = new File(docDir, filename);
+            if (file != null && file.exists()) {
+                have(filename);
+            } else {
+                //System.err.println("westodo expected " + file.getPath());
+            }
+        }
+        for (Iterator iter = donts.iterator(); iter.hasNext();) {
+            String filename = iter.next() + "";
+            File file = new File(docDir, filename);
+            if (file != null && file.exists()) {
+                have(filename);
+            } else {
+                //System.err.println("westodo avoiding " + file.getPath());
+            }
+        }
+    }
+
+    /**
+     * Create a new doc dir.
+     */
+    protected void init() {
+        docDir = new File(project.getBaseDir(), TEST_DOCDIR);
+    }
+
+    /**
+     * Make a new doc dir using ANT.
+     */
+    protected void makeDocDir() {
+        try {
+            Mkdir mkdir = (Mkdir)project.createTask("mkdir");
+            mkdir.setDir(docDir);
+            mkdir.execute();
+        } catch (BuildException be) {
+            be.printStackTrace();
+        }
+    }
+
+    /**
+     * Clear the build dir using ANT.
+     */
+    protected void clearDocDir() {
+        try {
+            Delete delete = (Delete)project.createTask("delete");
+            FileSet fileset = new FileSet();
+            fileset.setDir(docDir);
+            fileset.setIncludes("**");
+            delete.addFileset(fileset);
+            delete.execute();
+        } catch (BuildException be) {
+            be.printStackTrace();
+        }        
+    }
+
+    /**
+     * Invoke {@link #runTests(String[])} on a
+     * new instanceof {@link #AjdocTaskTester}.
+     *
+     * @param args Command line arguments.
+     */
+    public static void main(String[] args) {
+        new AjdocTaskTester().runTests(args);
+    }
+}
diff --git a/aspectj-attic/testing-src/AntTaskTester.java b/aspectj-attic/testing-src/AntTaskTester.java
new file mode 100644 (file)
index 0000000..1f032e7
--- /dev/null
@@ -0,0 +1,409 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+import org.apache.tools.ant.*;
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ * Provides utility methods to test ant tasks.
+ */
+public abstract class AntTaskTester implements BuildListener {
+
+    public abstract String getAntFile();
+
+    protected PrintStream out = System.out;
+    protected PrintStream err = System.err;
+    protected void info(Object msg) {
+        out.println(" [" + msg + "]");
+    }
+
+    protected Project project;
+    protected String taskname = "unset";
+
+    protected List errors = new Vector();
+    protected void throwable(Throwable t) {
+        error(taskname, t);
+        t.printStackTrace();
+    }
+    protected void error(String task, Object msg) {
+        error("[" + task + "]: " + msg);
+    }
+    protected void error(Object msg) {
+        err.println("Error: " + msg);
+        errors.add(msg);
+    }
+
+    protected List wants = new Vector();
+    protected void want(Object object) {
+        wants.add(object);
+    }
+    protected List haves = new Vector();
+    protected void have(Object object) {
+        haves.add(object);
+    }
+    protected List donts = new Vector();
+    protected void dont(Object object) {
+        donts.add(object);
+    }
+
+    protected void clear() {
+        wants = new Vector();
+        haves = new Vector();
+        donts = new Vector();
+    }
+
+    protected final boolean verbose = verbose();
+    protected boolean verbose() { return false; }
+    protected void log(String msg) {
+        if (verbose) out.println("[ " + msg + " ]");
+    }
+
+    public void printSummary() {
+        Iterator iter = errors.iterator();
+        out.println();
+        out.println("----------------------- Test Summary -----------------------");
+        if (errors.size() == 0) {
+            out.println("no errors");
+        } else {
+            out.println(errors.size() + " error" + (errors.size() > 1 ? "s" : ""));
+            while (iter.hasNext()) {
+                out.println(" " + iter.next());
+            }
+        }
+        out.println("------------------------------------------------------------");
+    }
+
+    /**
+     * Checks the all the assertions we wanted were achieved
+     * and all those received were desired.
+     */
+    protected void checkAfterTask() {
+        log("checking after task");
+        for (Iterator i = wants.iterator(); i.hasNext();) {
+            Object want = i.next();
+            check(haves.contains(want),
+                  "didn't see " + want + " in " + haves);
+        }
+        for (Iterator i = haves.iterator(); i.hasNext();) {
+            Object have = i.next();
+            check(wants.contains(have),
+                  "shouldn't have seen " + have + " in " + wants);
+        }
+        for (Iterator i = donts.iterator(); i.hasNext();) {
+            Object dont = i.next();
+            check(!haves.contains(dont),
+                  "should't have seen " + dont + " in " + haves);
+        }
+    }
+
+    /**
+     * Logs an error in <code>!b</code> with message <code>msg</code>.
+     *
+     * @param b   <code>true</code> for an error.
+     * @param msg Failure message.
+     */
+    protected void check(boolean b, String msg) {
+        if (!b) error(taskname, msg);
+    }
+
+    /**
+     * Calls {@link #check(boolean,String)} with the result
+     * of comparing equality of <code>o1</code> and <code>o2</code>,
+     * failing with message <code>msg</code>.
+     *
+     * @param o1  First comparison.
+     * @param o2  Other comparison.
+     * @param msg Failure message.
+     */
+    protected void check(Object o1, Object o2, String msg) {
+        if (o1 != null) {
+            check(o1.equals(o2), msg);
+        } else if (o2 != null) {
+            check(o2.equals(o1), msg);
+        } else {
+            check(true, msg);
+        }
+    }
+
+    /**
+     * Calls {@link #runProject} with <code>args</code> and
+     * the result of {@link #getAntFile}.
+     *
+     * @param args Arguments given on the command line.
+     * @see   #runProject(String[], String)
+     */
+    public void runTests(String[] args) {
+        runProject(args, getAntFile());
+    }
+
+    /**
+     * Loads the project, collects a list of methods, and
+     * passes these methods to {@link #runProject(Method[])}.
+     *
+     * @param args      Command line arguments.
+     * @param buildFile XML file that we are giving to ANT.
+     * @see #runProject(Method[])
+     */
+    public void runProject(String[] args, String buildFile) {
+        loadProject(buildFile);
+        Method[] methods = null;
+        if (args == null || args.length == 0 || args[0].equals("${args}")) {
+            methods = getClass().getMethods();
+        } else {
+            methods = new Method[args.length];
+            for (int i = 0; i < args.length; i++) {
+                String name = args[i];
+                if (!Character.isJavaIdentifierStart(name.charAt(0)) || // todo wes: was (i)?
+                    name.charAt(0) == '$') {
+                    continue;
+                }
+                try {
+                    methods[i] = getClass().getMethod(name, new Class[]{});
+                } catch (NoSuchMethodException nsme) {
+                    methods[i] = null;
+                }
+            }
+        }
+        runProject(methods);
+    }
+
+    /**
+     * Execute the targets whose name matches those found in <code>methods</code>.
+     *
+     * @param methods List of methods to execute.
+     */
+    protected final void runProject(Method[] methods) {
+        if (methods == null || methods.length < 1) {
+            return;
+        }
+        for (int i = 0; i < methods.length; i++) {
+            Method method = methods[i];
+            if (method == null) {
+                error("a method is null!");
+                continue;
+            }
+            taskname = method.getName();
+            if (taskname.startsWith("test")) {
+                info("test task: " + taskname);
+                try {
+                    method.invoke(this, new Object[]{});
+                    beforeTasks();
+                    execute(taskname);
+                    afterTasks();
+                } catch (Throwable t) {
+                    throwable(t);
+                } finally {
+                    info("done task: " + taskname);
+                }
+            } else if (taskname.startsWith("fail")) {
+                info("fail task: " + taskname);
+                try {
+                    beforeTasks();
+                    want(taskname + "-error");
+                    execute(taskname);
+                    afterTasks();
+                } catch (Throwable t) {
+                    if (t instanceof BuildException) {
+                        have(taskname + "-error");
+                        try {
+                            method.invoke(this, new Object[]{t});
+                        } catch (Throwable tt) {
+                            throwable(tt);
+                        }
+                    } else {
+                        throwable(t);
+                    }
+                } finally {
+                    info("done task: " + taskname);
+                }
+            }
+        }
+        printSummary();
+    }
+
+    /**
+     * Called before every task.
+     */
+    private final void beforeTasks() {
+        clear();
+        beforeMethod();
+        beforeEveryTask();
+    }
+
+    /**
+     * Called after every task.
+     */
+    private final void afterTasks() {
+        afterMethod();
+        afterEveryTask();
+        checkAfterTask();
+    }    
+
+    /**
+     * Invokes the method with prefix <code>prefix</code>.
+     *
+     * @param prefix Prefix of the method to execute.
+     */
+    private final void taskMethod(String prefix) {
+        String name = prefix + Character.toUpperCase(taskname.charAt(0)) +
+            taskname.substring(1);
+        try {
+            Method method = getClass().getDeclaredMethod(name, new Class[]{});
+            if (method != null) {
+                method.invoke(this, new Object[]{});
+            }
+        } catch (Throwable t) {
+        }
+    }
+
+    /**
+     * Executes the method with prefix <code>after</code>.
+     */
+    private final void afterMethod() {
+        taskMethod("after");
+    }
+
+    /**
+     * Executes the method with prefix <code>before</code>.
+     */
+    private final void beforeMethod() {
+        taskMethod("before");
+    }
+
+    /**
+     * Override this to do some work before every task.
+     */
+    protected void beforeEveryTask() {}
+
+    /**
+     * Override this for initialization -- called at
+     * the end of {@link #loadProject}.
+     */
+    protected void init() {}
+
+    /**
+     * Override this to do some work after every task.
+     */
+    protected void afterEveryTask() {}
+
+    protected void setProperties(Map map, boolean user) {
+        Iterator iter = map.keySet().iterator();
+        while (iter.hasNext()) {
+            Object key = iter.next();
+            Object val = map.get(key);
+            String keyString = key + "";
+            String valString = val + "";
+            if (user) {
+                project.setUserProperty(keyString, valString);
+            } else {
+                project.setProperty(keyString, valString);
+            }
+        }
+    }
+
+    protected void setProperties() {
+        setProperties(getProperties(), false);
+    }
+
+    protected void setUserProperties() {
+        setProperties(getUserProperties(), true);
+    }
+
+    /**
+     * Override this to provide user properties -- default to
+     * an empty <code>HashMap</code>.
+     *
+     * @return Empty <code>HashMap</code>.
+     */
+    protected Map getUserProperties() {
+        return new HashMap();
+    }
+
+    /**
+     * Override this to provide system properties -- default to
+     * an empty <code>HashMap</code>.
+     *
+     * @return Empty <code>HashMap</code>.
+     */
+    protected Map getProperties() {
+        return new HashMap();
+    }
+
+    /**
+     * Loads the project with file name <code>buildFile</code>.
+     *
+     * @param buildFile Name of the XML file to load.
+     */
+    public void loadProject(String buildFile) {
+        project = new Project();
+        project.init();
+        project.setUserProperty("ant.file", new File(buildFile).getAbsolutePath() );
+        setProperties();
+        setUserProperties();
+        project.addBuildListener(this);
+        ProjectHelper.configureProject(project, new File(buildFile));
+        init();
+    }
+
+    public void execute(String targetName) {
+        try { 
+            project.executeTarget(targetName);
+        } finally { 
+        }
+    }
+
+    private static class StringBufferOutputStream extends OutputStream {
+        private StringBuffer buf;
+        public StringBufferOutputStream(StringBuffer buf) {
+            this.buf = buf;
+        }
+        public void write(int c) { 
+            buf.append((char)c);
+        }
+    }
+
+    public boolean verbosity(BuildEvent event) {
+        int[] verbosities = verbosities();
+        int priority = event.getPriority();
+        for (int i = 0; i < verbosities.length; i++) {
+            if (priority == verbosities[i]) return true;
+        }
+        return false;
+    }
+
+    public int[] verbosities() {
+        return new int[] { /*Project.MSG_VERBOSE,*/ Project.MSG_INFO, Project.MSG_WARN, project.MSG_ERR };
+    }
+
+    // BuildListener
+    public void buildFinished(BuildEvent event) {
+    }
+    public void buildStarted(BuildEvent event) {
+    }
+    public void messageLogged(BuildEvent event) {
+        if (verbosity(event)) {
+            out.println(event.getMessage());
+        }
+    }
+    public void targetFinished(BuildEvent event) {
+    }
+    public void targetStarted(BuildEvent event) {
+    }
+    public void taskFinished(BuildEvent event) {
+    }
+    public void taskStarted(BuildEvent event) {
+    }
+}
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/CompareFiles.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/CompareFiles.java
new file mode 100644 (file)
index 0000000..2d16c9e
--- /dev/null
@@ -0,0 +1,571 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare;
+
+import org.aspectj.util.LangUtil;
+
+import jdiff.util.Diff;
+import jdiff.text.FileLine;
+import jdiff.util.DiffNormalOutput;
+
+import java.util.*;
+import java.util.zip.*;
+import java.io.*;
+
+/**  
+ * Compare two files and emit differences.
+ * Requires the jdiff library in jdiff/jdiff.jar
+ */
+public class CompareFiles {
+    protected static String[] NO_STRINGS = new String[]{};
+    /** standard rendering of null references */
+    public static final String NULL = "null";
+    /** filter for the both files  */
+    protected RegexpFilter filter;
+    /** ignore case by converting lines to upper case */
+    protected boolean ignoreCase  = false;
+    /** collapse internal whitespace by converting to space character */
+    protected boolean collapseWhitespace  = true;
+    /** trim leading and trailing whitespace from lines before comparison */
+    protected boolean trimWhitespace  = false;
+    /** output to this File - if not set, System.out */
+    protected File output  = null;
+
+    /**
+     * Compare two files by lines, emitting output to System.out as a series of edits.
+     * @param args  the String[] containing two files to diff plus any number of
+     *              <li>-i "ignore": ignore case</li>
+     *              <li>-t "trim"  : ignore leading and trailing white space</li>
+     *              <li>-b "blanks": ignore differences in all white space</li>
+     * @param lhs the File on the left-hand-side of the comparison
+     * @param rhs the File on the left-hand-side of the comparison
+     * @throws IllegalArgumentException if cannot read both files
+     */
+    public static void main(String[] args) {
+        new CompareFiles().comparefiles(args);
+    }
+
+    /**
+     * Write results of a diff to some output Writer
+     * @param result the DiffResult containing the results of the diff
+     * @param output the Writer to output results to - if null, 
+     *               defaults to System.out, but will be closed if not null
+     * @throws IllegalArgumentException if null == result or output 
+     */
+    public static void writeDiffResult(DiffResult result, File output) 
+        throws IOException {
+        if (null == result) throw new IllegalArgumentException("null result");
+        Writer writer = (null != output ? new FileWriter(output) 
+            : new OutputStreamWriter(System.out));
+        DiffNormalOutput out = new DiffNormalOutput(result.lhsLines, result.rhsLines);
+        out.setOut(writer);
+        out.setLineSeparator(LangUtil.EOL);
+        try {
+            out.writeScript(result.edits);
+        } finally {
+            if (null != output) {
+                try { writer.close(); } 
+                catch (IOException e) {
+                    e.printStackTrace(System.err);
+                }
+            }
+        }
+    } // writeDiffResult
+
+    /**
+     * descend filesystem tree, invoking FileRunnerI.accept() on files.
+     * E.g., To list files from current directory:
+     * <code><pre>descendFileTree(new File("."), new FileRunnerI() {
+     *     public boolean accept(File f){
+     *        System.out.println(f.getAbsolutePath());
+     *        return true;
+     *     }});</code></pre>
+     * @param file root/starting point.  If a file, the only one visited.
+     * @param filter supplies accept(File) routine
+     */
+    public static void descendFileTree(File file, FileFilter filter) {
+        descendFileTree(file, filter, false);
+    }
+
+    /**
+     * Descend filesystem tree, invoking FileFilter.accept() on files
+     * and, if userRecursion, on dirs. If userRecursion, accept() must
+     * call descendFileTree() again to recurse down directories.
+     * This calls fileFilter.accept(File) on all files before doing any dirs.
+     * E.g., To list only files from Unix root:
+     * <code><pre>descendFileTree(new File("/"), new FileFilter() {
+     *     public boolean run(File f){
+     *        System.out.println(f.getAbsolutePath());
+     *        return true;
+     *     }}, false);</code></pre>
+     * To list files/dir from root using user recursion:
+     * <code><pre>descendFileTree(new File("/"), new FileFilter() {
+     *     public boolean run(File f){ 
+     *        System.out.println(f.getAbsolutePath());
+     *        if (f.isDirectory() && (-1 == f.getName().indexOf("CVS")))
+     *           return descendFileTree(f, this, true);
+     *        return true;
+     *     }}, true);</code></pre>
+     * @param file root/starting point.  If a file, the only one visited.
+     * @param filter supplies boolean accept(File) method
+     * @param userRecursion - if true, do accept() on dirs; else, recurse
+     * @return false if any fileFilter.accept(File) did.
+     * @throws IllegalArgumentException if file or fileFilter is null
+     */
+    public static boolean descendFileTree(File file, FileFilter fileFilter, 
+                                          boolean userRecursion) {
+        if (null == file) {throw new IllegalArgumentException("parm File"); }
+        if (null == fileFilter){throw new IllegalArgumentException("parm FileFilter");}
+
+        if (!file.isDirectory()) {
+            return fileFilter.accept(file);
+        } else if (file.canRead()) { 
+            // go through files first
+            File[] files = file.listFiles(ValidFileFilter.FILE_EXISTS); 
+            if (null != files) {
+                for (int i = 0; i < files.length; i++) {
+                    if (!fileFilter.accept(files[i])) {
+                        return false;
+                    }
+                }
+            }
+            // now recurse to handle directories
+            File[] dirs = file.listFiles(ValidFileFilter.DIR_EXISTS);
+            if (null != dirs) {
+                for (int i = 0; i < dirs.length; i++) {
+                    if (userRecursion) {
+                        if (!fileFilter.accept(dirs[i])) {
+                            return false;
+                        }
+                    } else {
+                        if (!descendFileTree(dirs[i], fileFilter,userRecursion)) {
+                            return false;
+                        }
+                    }
+                }
+            }
+        } // readable directory (ignore unreadable ones) 
+        return true;
+    } // descendFiles
+
+    /**
+     * Render a zip/entry combination to String
+     */
+    private static String renderZipEntry(File zipfile, ZipEntry entry) {
+        String filename = (null == zipfile ? "null File" : zipfile.getName());
+        String entryname = (null == entry ? "null ZipEntry" : entry.getName());
+        //return filename + "!" + entryname;
+        return "" + entryname;
+    }
+
+    /**
+     * Initialise the filter.  Users must do this before the filter is
+     * lazily constructed or must set update to true.
+     * @param args the String with any args valid for RegexpFilter.init(String, RegexpFilter)
+     * @param update if true, use existing filter settings unless
+     *            overwritten by the new ones;
+     *            if false, create a new filter using args.
+     * @throws IllegalArgumentException if cannot read both files
+     * @see RegexpFilter#init(String, RegexpFilter)
+     */
+    public void initFilter(String arg, boolean update) {
+        filter = RegexpFilter.init(arg, update ? filter : null);
+    }
+
+    /**
+     * Initialise the filter.  Users must do this before the filter is
+     * lazily constructed or must set update to true.
+     * @param args the String[] with any args valid for RegexpFilter
+     * @param update if true, use existing filter settings unless
+     *            overwritten by the new ones;
+     *            if false, create a new filter using args.
+     * @throws IllegalArgumentException if cannot read both files
+     * @see RegexpFilter#init(String[], RegexpFilter)
+     */
+    public void initFilter(String[] args, boolean update) {
+        filter = RegexpFilter.init(args, update ? filter : null);
+    }
+
+    /**
+     * Compare two files by lines, emitting output to System.out as a series of edits.
+     * @param args  the String[] containing two files to diff 
+     *              (lhs, rhs) plus any args valid for RegexpFilter
+     * @throws IllegalArgumentException if cannot read both files
+     */
+    public final void comparefiles(String[] args) {
+        if (errMessage(null == args, "null args", null)) return;
+        if (errMessage(args.length < 2, "need more args", null)) return;
+        File lhs = new File(args[0]);
+        File rhs = new File(args[1]);
+        if (errMessage(!lhs.canRead(), "!lhs.canRead()", null)) return;
+        if (errMessage(!rhs.canRead(), "!rhs.canRead()", null)) return;
+        int filterArgsLength = args.length - 2;
+        if (0 >= filterArgsLength) {
+            initFilter(NO_STRINGS, false);
+        } else {
+            String[] filterArgs = new String[filterArgsLength];
+            System.arraycopy(args, 0, filterArgs, 0, filterArgsLength);
+            initFilter(filterArgs, false);
+        }
+        
+        try {
+            if (errMessage(!diff(lhs, rhs), "diff(lhs,rhs)",null)) return;
+        } catch (IOException t) {
+            if (errMessage(false, null, t)) return;
+        }
+    } // main
+
+    /**
+     * Compare two files/dirs, emitting output as a series of edits.
+     * If both files are directories, then this compares their contents
+     * (including the contents of any zip or jar files) as a series of paths
+     * (i.e., it will recognize added or removed or changed filenames, but
+     * not files whose contents have changed).
+     * Output will go to the File specifies as "output" or System.out if none specified.
+     * This is costly, creating an in-memory copy, one String per line, of both files.
+     * @param lhs the File/dir on the left-hand-side of the comparison
+     * @param rhs the File/dir on the left-hand-side of the comparison
+     * @throws IllegalArgumentException if either parm is null or not existing,
+     *         or if one is a dir and the other a file
+     * @throws IOException if getFileLines or diff utilities do
+     * @return false if there was some error
+     */
+    public final boolean diff(File lhs, File rhs) throws IOException {
+        DiffResult result = null;
+        String err = null;
+        if ((null == lhs) || (null == rhs) 
+            || (!lhs.exists()) || (!rhs.exists()) 
+            || (!lhs.canRead()) || (!rhs.canRead()) 
+            || (lhs.isDirectory() != rhs.isDirectory())) {
+            err = "need 2 readable files or dirs or zip files - got lhs=" + lhs + " rhs=" + rhs;
+        } else if (lhs.isDirectory()) {
+            result = diffDirUtil(lhs, rhs);
+        } else {
+            boolean lhsIsZip = isZipFile(lhs);
+            if (lhsIsZip != isZipFile(rhs)) {
+                err = "need 2 readable files or dirs or zip files - got lhs=" + lhs + " rhs=" + rhs;
+            } else if (lhsIsZip) {
+                result = diffDirUtil(lhs, rhs);
+            } else {
+                result = diffUtil(lhs, rhs);
+            }
+        }
+        if (null != err) throw new IllegalArgumentException(err);
+        if (errMessage(null == result, null, null)) return false;
+        writeDiffResult(result, output);
+        return true;
+    }
+
+    /**
+     * Compare two files, returning results for further evaluation or processing
+     * @param lhs the File on the left-hand-side of the comparison
+     * @param rhs the File on the left-hand-side of the comparison
+     * @throws IllegalArgumentException if either parm is null
+     * @throws IOException if getFileLines or diff utilities do
+     * @return false if there was some error
+     */
+    public final DiffResult diffUtil(File lhs, File rhs) 
+        throws IOException {
+        if (errMessage(null == lhs, "null lhs", null)) return null;
+        if (errMessage(null == rhs, "null rhs", null)) return null;
+        FileLine[] lhsLines = getFileLines(lhs);
+        FileLine[] rhsLines = getFileLines(rhs);
+        Diff.change edits = new Diff(lhsLines, rhsLines).diff_2(false);
+        return new DiffResult(lhsLines, rhsLines, edits);
+    }
+
+    /**
+     * Read all lines of a file into a String[] (not very efficient),
+     * implementing flag policies.
+     * @param file the File to read
+     * @return a FileLine[] with elements for each line in the file
+     */
+    public FileLine[] getFileLines(File file) throws IOException {
+        if (file.isDirectory()) return getFileLinesForDir(file);
+        final Vector results = new Vector();
+        
+        BufferedReader in = null;
+        try {
+            in = getReader(file);
+            String line;
+            while (null != (line = in.readLine())) { 
+                results.add(toFileLine(line));
+            }
+        } finally {
+            if (null != in) { in.close(); } 
+        }
+        final FileLine[] lines = new FileLine[results.size()];
+        results.copyInto(lines);
+        return lines;
+    }
+    
+    /**
+     * Compare two directories or zip files by listing contents (including contents of zip/jar files) 
+     * and differencing the results.  This does NOT call diff on each file, but only
+     * recognizes when files or zip entries have been added or removed.
+     * @param lhsDir the File for an existing, readable directory (as left-hand-side)
+     * @param rhsDir the File for an existing, readable directory (as right-hand-side)
+     * @throws IllegalArgumentException if null == lhs or rhsDir 
+     */
+    public DiffResult diffDirUtil(File lhsDir, File rhsDir) {
+        FileLine[] lhsLines = getFileLinesForDir(lhsDir);
+        FileLine[] rhsLines = getFileLinesForDir(rhsDir);
+        // now do the comparison as if they were two files
+        Diff.change edits = new Diff(lhsLines, rhsLines).diff_2(false);
+        return new DiffResult(lhsLines, rhsLines, edits);
+    } 
+    
+    /**
+     * Render all sub-elements of a directory as a list of FileLine[], including entries 
+     * in zip and jar files.  The directory prefix is not included in the FileLine.
+     * @param dir the File representing the directory to list
+     * @throws IllegalArgumentException if null == dir  or !dir.isDirectory()
+     */
+    public FileLine[] getFileLinesForDir(File dir) {
+        if (null == dir) throw new IllegalArgumentException("null dir");
+        if (!dir.isDirectory() && ! isZipFile(dir)) throw new IllegalArgumentException("not a dir: " + dir);
+        Collection items = directoryToString(dir, null);
+        return toFileLine(items, dir.getPath(), true);
+    } 
+
+    /** @return true if test or if null != error */
+    protected boolean errMessage(boolean test, String message, Throwable error) {
+        if (test && (null != message)) { System.err.println(message); }
+        if (null != error) { error.printStackTrace(System.err); }
+        return (test || (null != error));
+    }
+
+    /**
+     * Convert current setting into an initialization list for filter
+     */
+    protected String[] getFilterArgs() {
+        return new String[] 
+            { (trimWhitespace     ? "-t" : "-T")
+            , (collapseWhitespace ? "-b" : "-B")
+            , (ignoreCase         ? "-i" : "-I")
+            };
+    }
+
+    /**
+     * Lazy construction of filter
+     */
+    protected RegexpFilter getFilter() {
+        if (null == filter) {
+            filter = RegexpFilter.init(getFilterArgs(), null);
+        }
+        return filter;
+    }
+
+    /**
+     * Factory for reader used by getFileLines(File).
+     * Default implementation creates a BufferedReader.
+     * Subclasses may implement pre-processing filters here.
+     */
+    protected BufferedReader getReader(File file) throws IOException {
+        return new BufferedReader(new FileReader(file));
+    }
+
+    /**
+     * Create a FileLine from the input string,
+     * applying policies for whitespace, etc.
+     * @param string the String to wrap as a FileLine
+     * @return FileLine with string as text and 
+     *        canonical as string modified by any canonicalizing policies.
+     */
+    protected FileLine toFileLine(String string) {
+        String canonical = getFilter().process(string);
+        return new FileLine(string, canonical);
+    }
+
+
+    protected boolean isZipFile(File f) {
+        String s = null;
+        if ((null == f)  || (null == (s = f.getPath()))) {
+            return false;
+        } else {
+            return (f.exists() && !f.isDirectory() && (s.endsWith(".jar")));
+        }
+    }
+
+    /**
+     * Convert to an array of FileLine by optionally removing prefix and/or sorting
+     * @param collection the Collection of String to process
+     */
+    protected FileLine[] toFileLine(Collection collection, String ignorePrefix, boolean sort) {
+        if (null == collection) throw new IllegalArgumentException("null collection");
+        List list = new ArrayList();
+        list.addAll(collection);
+        if (null != ignorePrefix) {
+            for (int i = 0; i < list.size(); i++) {
+                String next = list.get(i).toString();
+                if (next.startsWith(ignorePrefix)) {
+                    list.set(i, next.substring(ignorePrefix.length()));
+                }
+            }
+        }
+        if (sort) {
+            Collections.sort(list);
+        }
+        FileLine[] result = new FileLine[list.size()];
+        int i = 0;
+        for (Iterator it = list.iterator(); it.hasNext();) {
+            result[i++] = toFileLine(it.next().toString());
+        }
+        if (i < result.length) {
+            throw new Error("list lost elements? " + (result.length-i)); 
+        }
+        return result;
+    }
+
+    /**
+     * Return the names of all files below a directory.
+     * If file is a directory, then all files under the directory
+     * are returned.  If file is absolute or relative, all the files are.
+     * If file is a zip or jar file, then all entries in the zip or jar
+     * are listed.  Entries inside those jarfiles/zipfiles are not listed.
+     * There are no guarantees about ordering.
+     * @param dir the File to list for
+     * @param results the Collection to use for the results (may be null)
+     * @throws IllegalArgumentException if null == dir 
+     * @return a Collection of String of paths, including paths inside jars
+     */
+    protected Collection directoryToString(File dir, Collection results) {
+        if (null == dir) throw new IllegalArgumentException("null dir");
+        final Collection result = (results != null? results : new Vector());
+        if (isZipFile(dir)) {
+            zipFileToString(dir, result);
+        } else if (!dir.isDirectory()) {
+            throw new IllegalArgumentException("not a dir: " + dir);
+        } else {
+            AccumulatingFileFilter acFilter = new AccumulatingFileFilter() {
+                    public boolean accumulate(File file) {
+                        String name = file.getPath();
+                        result.add(name);
+                        if (isZipFile(file)) {
+                            zipFileToString(file, result);
+                        }
+                        return true;
+                    }
+                };
+            descendFileTree(dir, acFilter, false);
+        }
+        return result;
+    } // directoryToString
+
+    /**
+     * Render as String the entries in a zip or jar file,
+     * converting each to String beforehand (as jarpath!jarentry)
+     * applying policies for whitespace, etc.
+     * @param file the File to enumerate ZipEntry for
+     * @param results the Colection to use to return the FileLine - may be null
+     * @return FileLines with string as text and 
+     *        canonical as string modified by any canonicalizing policies.
+     */
+    protected Collection zipFileToString(final File zipfile, Collection results) {
+        Collection result = (results != null ? results : new Vector());
+        ZipFile zip = null;
+        try {
+            //ZipFile.OPEN_READ | ZipFile.OPEN_DELETE); delete is 1.3 only
+            zip = new ZipFile(zipfile); 
+            Enumeration enum = zip.entries();
+            // now emitting filename only once, so entries match even if filename does not
+            results.add("ZipFileName: " + zipfile);
+            while (enum.hasMoreElements()) {
+                results.add(renderZipEntry(zipfile, (ZipEntry) enum.nextElement()));
+            }
+            zip.close();
+            zip = null;
+        } catch (Throwable t) {
+            String err = "Error opening " + zipfile + " attempting to continue...";
+            System.err.println(err);
+            t.printStackTrace(System.err);
+        } finally {
+            if (null != zip) {
+                try { zip.close(); }
+                catch (IOException e) {
+                    e.printStackTrace(System.err);
+                }
+            }
+        }
+        return result;
+    }
+
+    /** 
+     * return structure for diffUtil 
+     */
+    public final class DiffResult {
+        public final FileLine[] lhsLines;
+        public final FileLine[] rhsLines;
+        public final Diff.change edits;
+        public DiffResult (FileLine[] lhsLines,
+                           FileLine[] rhsLines,
+                           Diff.change edits) {
+            this.lhsLines = lhsLines;
+            this.rhsLines = rhsLines;
+            this.edits = edits;
+        }
+    }
+
+} // class CompareFiles
+
+class ValidFileFilter implements FileFilter {
+    public static final FileFilter EXIST = new ValidFileFilter();
+    public static final FileFilter FILE_EXISTS = new FilesOnlyFilter();
+    public static final FileFilter DIR_EXISTS = new DirsOnlyFilter();
+    protected ValidFileFilter(){}
+    public boolean accept(File f) {
+        return ((null != f) && (f.exists()));
+    }
+    static class FilesOnlyFilter extends ValidFileFilter {
+        public final boolean accept(File f) {
+            return (super.accept(f) && (!f.isDirectory()));
+        }
+    }
+    static class DirsOnlyFilter extends ValidFileFilter {
+        public final boolean accept(File f) {
+            return (super.accept(f) && (f.isDirectory()));
+        }
+    }
+}
+
+/** 
+ * A FileFilter that accumulates the results when called if they exist.
+ * Subclasses override accumulate to determine whether it should be
+ * accumulated.
+ */
+class AccumulatingFileFilter extends ValidFileFilter {
+    Vector files = new Vector();
+    public final boolean accept(File f) {
+        if (super.accept(f) && (accumulate(f))) {
+            files.add(f);
+        }
+        return true;
+    }
+
+    /** 
+     * This implementation accumulates everything.
+     * Subclasses should override to implement filter
+     * @param file a File guaranteed to exist 
+     * @return true if file should be accumulated. 
+     */
+    public boolean accumulate(File f) {
+        return true;
+    }
+    /**
+     * @return list of files currently accumulated 
+     */
+    public File[] getFiles() {
+        return (File[]) files.toArray(new File[0]);
+    }
+}
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/CompareUtil.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/CompareUtil.java
new file mode 100644 (file)
index 0000000..8358a17
--- /dev/null
@@ -0,0 +1,143 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare;
+
+import java.util.Iterator;
+import java.util.Collection;
+import java.util.List;
+
+/** Minor methods for short-circuiting comparisons */
+public class CompareUtil {    
+    /**
+     * Callers may abort equality checks with false
+     * if this passes its misc short-circuit semantics.
+     * A false result does not mean the arguments
+     * are equal, but a true result does mean they are not equal. 
+     * <pre>if (notSame(foo,bar,true)) then return false;</pre>
+     * @param lhs the Object on the left-hand-side to compare
+     * @param rhs the Object on the right-hand-side to compare
+     * @param considerType if true, then also return true if the 
+     *           right-hand-side cannot be assigned to the left-hand-side
+     * @return true if lhs and rhs are not the same per considerType.
+     */
+    public static boolean notSame(Object lhs, Object rhs, boolean considerType) {
+        if (null == lhs) {
+            return (!(null == rhs));
+        } else if (null == rhs) {
+            return true;
+        } else if (lhs== rhs) {
+            return false;  // known to be same
+        } else if (considerType) {
+            Class lhClass = lhs.getClass();
+            Class rhClass = rhs.getClass();
+            if (!lhClass.isAssignableFrom(rhClass)) {
+                return true;
+            }
+        }
+        return false; // unknown whether equal or not
+    }    
+
+    /**
+     * Return null/equal comparison:
+     * <li>null considered to be lesser</li>
+     * <li>reference or Object.equals() considered to be 0</li>
+     * <li>return Integer.MAX_VALUE for all other cases</li>
+     * <table>
+     * <tr><td>result</td><td>input</td></tr>
+     * <tr><td>-1</td><td>null &lt; rhs</td></tr>
+     * <tr><td>1</td><td>lhs &gt; null</td></tr>
+     * <tr><td>0</td><td>null == null</td></tr>
+     * <tr><td>0</td><td>lhs == rhs</td></tr>
+     * <tr><td>0</td><td>lhs.equals(rhs)</td></tr>
+     * <tr><td>Integer.MAX_VALUE</td><td>{all other cases}</td></tr>
+     * </table>
+     * @see Comparator
+     * @return Integer.MAX_VALUE if uncertain, value otherwise
+     */
+    public static int compare(Object lhs, Object rhs) {
+        if (null == lhs) {
+            return (null == rhs ? 0 : -1);
+        } else if (null == rhs) {
+            return 1;
+        } else if (lhs == rhs) {
+            return 0;  // known to be same
+        } else {
+            return Integer.MAX_VALUE;
+        }
+    }
+
+    /**
+     * Return boolean comparison where true > false.
+     * (Comparable not defined for Boolean)
+     * @see Comparator
+     */
+    public static int compare(boolean lhs, boolean rhs) {
+        return (lhs == rhs ? 0 : (lhs ? 1 : -1));
+    }
+
+    /**
+     * Return String comparison based on {@link compare(Object,Object)}
+     * and {@link String.compareTo(String)}.
+     * @see Comparator
+     */
+    public static int compare(String lhs, String rhs) {
+        int result = compare((Object) lhs, (Object) rhs);
+        if (Integer.MAX_VALUE == result) {
+            result = lhs.compareTo(rhs);
+        }
+        return result;
+    }
+
+    /**
+     * Compare two Collections by reference to a standard List.
+     * The first Collection to not contain a standard element 
+     * when the other does loses. Order is ignored.
+     * The left-hand-side acts as the standard if the standard is null.
+     * @param lhs the List from the left-hand-side
+     * @param rhs the Collection from the right-hand-side
+     * @param standard the List to act as the standard (if null, use lhs)
+     * @param return -1 if lhs is null and rhs is not, 1 if reverse;
+     *        0 if both have all elements in standard,
+     *        1 if lhs has a standard element rhs does not, -1 if reverse
+     *        (testing in standard order)
+     */
+    public static int compare(List lhs, Collection rhs, List standard) {
+        int result = compare(lhs, rhs);
+        if (result == Integer.MAX_VALUE) {
+            if (null == standard) {
+                result = compare(lhs, rhs, lhs); // use lhs as standard
+            } else {
+                boolean leftHasThem = lhs.containsAll(standard);
+                boolean rightHasThem = rhs.containsAll(standard);
+                if (leftHasThem != rightHasThem) {
+                    result = (leftHasThem ? 1 : -1);
+                } else if (leftHasThem) {
+                    result = 0; // they both have them
+                } else {        // first to not have an element loses
+                    Iterator standardIterator = standard.iterator();
+                    while (standardIterator.hasNext()) {
+                        Object standardObject = standardIterator.next();
+                        boolean leftHasIt = lhs.contains(standardObject);
+                        boolean rightHasIt = rhs.contains(standardObject);
+                        if (leftHasIt != rightHasIt) {
+                            result = (leftHasIt ? 1 : -1);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+} // class Util
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNode.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNode.java
new file mode 100644 (file)
index 0000000..cdb0b70
--- /dev/null
@@ -0,0 +1,427 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+package org.aspectj.testing.compare;
+
+import java.util.*;
+
+
+/** 
+ * Generic tree and pairwise traversal over it
+ * for comparison purposes.
+ * Implement a generic tree by delegation and
+ * a traversal method for comparing two trees.
+ * Guarantees after initialization:
+ * <li>nodeComparator is not null</li>
+ * <li>node is not null</li>
+ * <li>children, if any, are assignable to childClass 
+ *     (only as of initialization, since list is adopted)</li>
+ * <li>Obeys GenericTreeNode contract, especially regarding equals</li>
+ * <p>It will throw Error if used before initialization completes.
+ */
+public class GenericTreeNode implements Comparable {
+    /** underlying node - never null */
+    Object node; 
+    /** node children - type-safe if present */
+    List children;
+    /** node parent - may be null if this is tree root */
+    GenericTreeNode parent;
+    /** used to compare underlying node */
+    Comparator nodeComparator;
+    /** Class used to verify children  - may be null */
+    Class childClass;
+
+    /** Track whether we are initialized */
+    boolean ready;
+    /** cache for heavy toString() */
+    String toStringCache;
+
+    // --------------------------------------- static
+    /** Singleton visitor to match trees exactly, stopping at first failure */
+    public static final GenericTreeNodesVisitorI EXACT = new MatchExact();
+
+    /** Singleton visitor to print non-matching nodes to System.err */
+    public static final GenericTreeNodesVisitorI PRINTERR = new PrintNonMatches();
+
+    /** Singleton visitor to print all nodes to System.err */
+    public static final GenericTreeNodesVisitorI PRINTALL = new PrintAllPairs();
+
+
+    /** Singleton comparator for all of us */
+    public static final Comparator COMPARATOR = new gtnComparator();
+
+    /**
+     * Visit two generic trees in order.
+     * Visit the parents, and recursively visit the children.
+     * The children are visited in an order determined by 
+     * (any) ordering factory invoked to produce an ordered pair
+     *  of children lists for visiting.
+     * All children are visited, even if not paired.
+     * When one list of children is smaller, the 
+     * remainder are visited with null complements.
+     * This is true for parents as well; this will visit
+     * all the children of a parent even when the 
+     * other parent is null.
+     * This will return false without further visits 
+     * as soon as the visitor returns false.  That means
+     * the visitor can decide to stop visiting when null
+     * nodes (parent or children) are encountered).
+     * This will return true only after the tree was
+     * visited without objection from the visitor.
+     * <p>A simple example of using this to determine if
+     * two trees are strictly equal is this:
+     * @return false if the visitor returned false for any visit;
+     *         true otherwise.
+     * @throws Error if any children are not GenericTreeNode
+     * @throws IllegalArgumentException if the visitor or both parents are null
+     */
+
+    public static boolean traverse(GenericTreeNode lhsParent
+                                   , GenericTreeNode rhsParent
+                                   , GenericTreeNodeListOrdererFactoryI childrenPrepFactory
+                                   , GenericTreeNodesVisitorI visitor) {
+        if (null == visitor) {
+            throw new IllegalArgumentException("null visitor");
+        }
+        if ((null == lhsParent) && (null == rhsParent)) {
+            throw new IllegalArgumentException("null parents");
+        }
+        if (visitor.visit(lhsParent, rhsParent)) {
+            List lhsList = (null == lhsParent ? null : lhsParent.getChildren());
+            List rhsList = (null == rhsParent ? null : rhsParent.getChildren());
+            if (null != childrenPrepFactory) {
+                GenericTreeNodeListOrdererI factory = 
+                    childrenPrepFactory.produce(lhsParent, rhsParent, visitor);
+                if (null !=  factory) {
+                    List[] prepKids = factory.produceLists(lhsList, rhsList);
+                    if (null != prepKids) {
+                        lhsList = prepKids[0];
+                        rhsList = prepKids[1];
+                    }
+                }
+                
+            }
+            ListIterator lhsIterator = (null == lhsList ? null : lhsList.listIterator());
+            ListIterator rhsIterator = (null == rhsList ? null : rhsList.listIterator());
+            Object lhs = null;
+            Object rhs = null;
+            while (true) {
+                lhs = null;
+                rhs = null;
+                // get the child pair
+                if ((null != lhsIterator) && (lhsIterator.hasNext())) {
+                    lhs = lhsIterator.next();
+                }
+                if ((null != rhsIterator) && (rhsIterator.hasNext())) {
+                    rhs = rhsIterator.next();
+                }
+                if ((null == rhs) && (null == lhs)) {
+                    break;
+                }
+                if ((null != lhs) && (!(lhs instanceof GenericTreeNode))) {
+                    throw new Error("GenericTreeNode expected, got lhs " + lhs);
+                } 
+                if ((null != rhs) && (!(rhs instanceof GenericTreeNode))) {
+                    throw new Error("GenericTreeNode expected, got rhs " + rhs);
+                }
+                // traverse the child pair
+                if (!traverse((GenericTreeNode) lhs, (GenericTreeNode) rhs, 
+                              childrenPrepFactory, visitor)) {
+                    return false;
+                }
+            }
+        }
+        return true; // see also other return statements above
+    }     // traverse
+
+    // --------------------------------------- constructors
+    public GenericTreeNode() {
+        //ready = false;
+    }
+
+    public void init(GenericTreeNode parent, Comparator nodeComparator, 
+                     Object node, List children, Class childClass) {
+        if (ready) ready = false; // weak sync
+        if (null == node) {
+            throw new IllegalArgumentException("null node");
+        }
+        if (null == nodeComparator) {
+            throw new IllegalArgumentException("null nodeComparator");
+        }
+        this.nodeComparator = nodeComparator;
+        this.node = node;
+        this.children = children;
+        this.parent = parent;
+        if (null != childClass) {
+            ListIterator iter = children.listIterator();
+            while (iter.hasNext()) {
+                Object kid = iter.next();
+                if (!(childClass.isAssignableFrom(kid.getClass()))) {
+                    String err = "child " + kid + " is not " + childClass;
+                    throw new IllegalArgumentException(err);
+                }
+            }
+            this.childClass = childClass;
+        }
+        ready = true;
+    }
+
+    //-------------------- Object interface
+    /** 
+     * ambiguous: equal if 
+     * <li>this is the input, or </li>
+     * <li>the input is a GenericTreeNode, and </li>
+     * <li>the underlying nodes are equal(), or</li
+     * <li>the underlying nodes have equal comparators
+     *     which return 0 from compare(...)</li>
+     * @param input the Object to compare with
+     * @return true if this equals input
+     */
+    public boolean equals(Object input) {
+        if (input == this) {
+            return true;
+        } else if (!(input instanceof GenericTreeNode)) {
+            return false;
+        } else {
+            GenericTreeNode in = (GenericTreeNode) input;
+            if (node.equals(in.getNode())) { // assumes nodes are unique, not flyweights?
+                return true;
+            } else {
+                Comparator inComp = in.getNodeComparator();
+                if ((this == nodeComparator) 
+                    || (this == inComp)
+                    || (nodeComparator == inComp) 
+                    || (nodeComparator.equals(inComp))) {
+                    return (0 == nodeComparator.compare(this, in));
+                } else {
+                    return false;
+                }
+            }
+        }
+    }
+
+    /** 
+     * Delegate to the underlying node object 
+     * @return the hashcode of the underlying node object  
+     */
+    public int hashCode() { // todo: probably not correct to delegate to node
+        return node.hashCode();
+    }
+
+    /** toString delegates to longString() */ 
+    public String toString() {
+        if (null == toStringCache) {
+            toStringCache = longString();
+        }
+        return toStringCache;
+    }
+
+    /** 
+     * short rendition delegates to thisString,
+     * prefixing by one tab per parent
+     */
+    public String shortString() {
+        StringBuffer sb = new StringBuffer();
+        // add a tab for each parent
+        GenericTreeNode par = parent;
+        while (null != par) {
+            sb.append("\t");
+            par = par.getParent();
+        } 
+        sb.append(thisString());
+        return sb.toString();
+    }
+
+    /** 
+     * long rendition delegates to parentString, thisString,
+     * and childString as follows:
+     * <pre>GenericTreeNode [parent={parentString()] [children={size}] [Node={thisString()]</pre>
+     */
+    public String longString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("GenericTreeNode ");
+        sb.append("[parent=");
+        sb.append(parentString());
+        sb.append("] [children=");
+        if (null == children) {
+            sb.append("0");
+        } else {
+            sb.append("" + children.size());
+        }
+        sb.append("] [Node=");
+        sb.append(thisString());
+        sb.append("]");
+        return sb.toString();
+    }
+
+    /** render this as "[root] [next] ... [parent]" */
+    protected String thisString() {
+        return node.toString();
+    }
+
+    /** render parent hierarchy as "[root] [next] ... [parent]" */
+    protected String parentString() {
+        if (null == parent) {
+            return "[null]";
+        } else  {
+            Vector parents = new Vector();
+            GenericTreeNode par = parent;
+            do {
+                parents.addElement(par);
+                par = par.getParent();
+            } while (null != par); 
+            int size = parents.size();
+            StringBuffer sb = new StringBuffer(32*size);
+            par = (GenericTreeNode) parents.remove(--size);
+            sb.append("[");
+            do {
+                sb.append(par.toString());
+                par = (size<1?null:(GenericTreeNode) parents.remove(--size));
+                if (null != par) {
+                    sb.append("] [");
+                }
+            } while (null != par);
+            sb.append("]");
+            return sb.toString();
+        }
+    } // parentString()
+
+    // -------------------------- Comparable interface
+    /**
+     * Comparable just delegates to Comparator.
+     * i.e., <code>return compare(this, rhs)</code>
+     * @param rhs the Object to compare from the right 
+     * @throws ClassCastException if either is not instanceof GenericTreeNode
+     * @return 0 if equal, &gt;0 if this is greater than rhs, &lt;0 otherwise.
+     */
+    public int compareTo(Object rhs) { 
+        return COMPARATOR.compare(this, rhs);
+    }
+
+
+    //-------------------- GenericTreeNode interface
+    /** @return the actual underlying node */
+    public Object getNode() { assertReady(); return node ; }
+    /** @return the actual underlying node */
+    public GenericTreeNode getParent() { assertReady(); return parent ; }
+    /** @return List of children - null if none */
+    public List getChildren() { assertReady(); return children ; }
+    /** @return Comparator used for comparing node (not children) */
+    public Comparator getNodeComparator() { assertReady(); return nodeComparator; }
+    /** @return Class which any children can be assigned to */
+    public Class getChildClass() { assertReady(); return childClass; }
+
+    //-------------------- misc
+    protected void assertReady() {
+        if (!ready) throw new Error("not ready");
+    }    
+
+    //-------------------- inner classes
+    /**
+     * This relies entirely on the GenericTreeNode implementation of equals()
+     * which delegates to the underlying node equals() or the comparator
+     */
+    static class MatchExact implements GenericTreeNodesVisitorI {
+        public boolean visit(GenericTreeNode lhs,GenericTreeNode rhs) {
+            return (null == lhs ? (null == rhs) : lhs.equals(rhs));
+        }
+    }
+
+    /**
+     * This prints non-matching pairs to System.err,
+     * returning true always.
+     */
+    static class PrintNonMatches implements GenericTreeNodesVisitorI {
+        public boolean visit(GenericTreeNode lhs,GenericTreeNode rhs) {
+            if (! (null == lhs ? (null == rhs) : lhs.equals(rhs))) {
+                System.err.println("[lhs=" + lhs + "] [rhs=" + rhs + "]");
+            }
+            return true;
+        }
+    }    
+
+    /**
+     * This prints all pairs to System.err, returning true always.
+     */
+    static class PrintAllPairs implements GenericTreeNodesVisitorI {
+        public boolean visit(GenericTreeNode lhs,GenericTreeNode rhs) {
+            System.err.println("[lhs=" + lhs + "] [rhs=" + rhs + "]");
+            return true;
+        }
+    }    
+
+    /**
+     * have to separate to distinguish
+     * gtn.equals() from gtnComparator.equals
+     */
+    static class gtnComparator implements Comparator {
+        public boolean equals(Object o) {
+            if (null == o) return false;
+            return ( o instanceof gtnComparator );
+        }
+        public int hashCode() {
+            return gtnComparator.class.hashCode();
+        }
+        // -------------------------- Comparator interface
+        /**
+         * Shallow compare of two GenericTreeNodes.
+         * <li>any null component translates to "less than" another null component<li>
+         * <li>comparators must be equal according to
+         *   <code>Comparator.equals(Comparator)</code><li>
+         * <li>underlying nodes equal according to
+         *    <code>Comparator.compare(Object lhs, Object rhs)</code><li>
+         * <li>if the two comparators are not equal, then
+         *     do arbitrary ordering of the node by toString().compareTo()
+         *     of the underlying objects</li>
+         * <li>children are ignored.  Two nodes may be equal even if
+         *     they do not have the same children.</li>
+         * @param lhs the Object to compare from the left 
+         * @param rhs the Object to compare from the right 
+         * @throws ClassCastException if either is not instanceof GenericTreeNode
+         */ 
+        public int compare(Object lhs, Object rhs) { 
+            int result = CompareUtil.compare(lhs, rhs);
+            if (Integer.MAX_VALUE == result) {
+                GenericTreeNode lhsNode = (GenericTreeNode) lhs;
+                GenericTreeNode rhsNode = (GenericTreeNode) rhs;
+                Object lhObject = lhsNode.getNode();
+                Object rhObject = rhsNode.getNode();
+                result = CompareUtil.compare(lhObject, rhObject); //
+                if (Integer.MAX_VALUE == result) {
+                    Comparator lhComp = lhsNode.getNodeComparator();
+                    Comparator rhComp = rhsNode.getNodeComparator();
+                    result = CompareUtil.compare(lhComp, rhComp);
+                    if ((Integer.MAX_VALUE == result)
+                        || ((0 == result) && (null == lhComp))) {
+                        // tricky: comparators are not equal or null, - todo
+                        // so unable to determine standard of ordering.
+                        // impose a consistent but arbitrary ordering
+                        // on the underlying objects
+                        System.err.println(" -- result: " + result + " lhComp " + lhComp);
+                        result = lhObject.toString().compareTo(rhObject.toString());
+                    } else if (0 == result) { // ok to use comparator
+                        result = lhComp.compare(lhsNode.getNode(), rhsNode.getNode());
+                    } else {
+                        String err = "Program error - result: " + result
+                            + " lhComp: " + lhComp + " rhComp: " + rhComp;
+                        throw new Error(err);
+                    }
+                }
+            }
+            return result;
+        } // compare 
+    }
+
+} // class GenericTreeNode 
+
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNodeListOrdererFactoryI.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNodeListOrdererFactoryI.java
new file mode 100644 (file)
index 0000000..c985498
--- /dev/null
@@ -0,0 +1,30 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare;
+
+/** 
+ * Factory to produce orderers per children list pair.
+ * Using a factory permits generation/selection of the right orderer 
+ * for each set of children to be compared, potentially considering
+ * the visitor expectations.  Note that while orderers may change during
+ * traversals, visitors do not.
+ */
+public interface GenericTreeNodeListOrdererFactoryI {
+    /** 
+     * Produce the correct orderer for the children of the given GenericTreeNodes
+     * @return GenericTreeNodeListOrdererI for children, or null if none to be used 
+     */
+    public GenericTreeNodeListOrdererI produce(GenericTreeNode lhs, GenericTreeNode rhs,
+                                               GenericTreeNodesVisitorI visitor);
+}
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNodeListOrdererI.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNodeListOrdererI.java
new file mode 100644 (file)
index 0000000..7f5e2bd
--- /dev/null
@@ -0,0 +1,44 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare;
+
+import java.util.List;
+
+/**
+ * Puts two lists of GenericTreeNode children
+ * in traversal order for comparison purposes.
+ * Given two lists, produce two lists which
+ * should be the comparison order of the two.
+ * In the case of set comparison, this will 
+ * impose an ordering on the produced lists 
+ * such that the equal elements are pairs.
+ * In the case of list comparison, it may
+ * impose an ordering if the comparator itself
+ * does not. 
+ * All Lists must contain only GenericTreeNode.
+ */
+public interface GenericTreeNodeListOrdererI {
+    /**
+     * Produce lists representing the proper transformation of 
+     * the children for a given visitor.  
+     * To use the existing lists, return them in a new array.
+     * You may return null for one or both Lists. 
+     * @param lhs the List representing the left-hand-side
+     *            which contains only GenericTreeNode
+     * @param rhs the List representing the right-hand-side
+     *            which contains only GenericTreeNode
+     * @return two lists List[] (0 => lhs, 1 => rhs)
+     */
+    public List[] produceLists(List lhs, List rhs);
+}
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNodesVisitorI.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/GenericTreeNodesVisitorI.java
new file mode 100644 (file)
index 0000000..da1dcf2
--- /dev/null
@@ -0,0 +1,31 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare;
+/**
+ * Visit a node-pair in the trees, 
+ * signalling whether to continue traversal.
+ */
+public interface GenericTreeNodesVisitorI {
+    /**
+     * Visit nodes in parallel trees.
+     * One (but not both) of the input nodes may be null.
+     * @param lhs the GenericTreeNode on the left-hand-side of a binary operation
+     *            (may be null)
+     * @param lhs the GenericTreeNode on the right-hand-side of a binary operation
+     *            (may be null)
+     * @return true if should continue visiting 
+     */
+    public boolean visit(GenericTreeNode lhs, GenericTreeNode rhs);
+}
+
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/Regexp.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/Regexp.java
new file mode 100644 (file)
index 0000000..c32310c
--- /dev/null
@@ -0,0 +1,40 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare;
+
+import java.util.Vector;
+
+/** Generalize regular expression interface (to avoid binding to regexp provider)*/
+public interface Regexp {
+    /** @return the substrings matched in argument by this regular expression */
+    public Vector getGroups(String argument);
+
+    /** @return true if argument is matched by this regular expression */
+    public boolean matches(String argument);
+
+    /** 
+     * Set pattern used in this regular expression.
+     * May throw Exception if the pattern can be determined to be illegal 
+     * during initialization.
+     * @throws Exception if pattern is illegal
+     */
+    public void setPattern(String pattern) throws Exception;
+
+    /** 
+     * @return a string representaion of the pattern 
+     * (may not be legal or the input) 
+     */
+    public String getPattern() ;
+}
+
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/RegexpFactory.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/RegexpFactory.java
new file mode 100644 (file)
index 0000000..0c7bccc
--- /dev/null
@@ -0,0 +1,64 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+// todo: non-distribution license?
+
+package org.aspectj.testing.compare;
+
+// currently in aspectj-external-lib/regexp
+import org.apache.regexp.RE;
+
+import java.util.Vector;
+
+
+/** Factory for our Regexp. */
+public class RegexpFactory {
+    public static Regexp makeRegexp() {
+        return new RegExpDelegate();
+    }
+}
+
+/** Implement Regexp by delegating to org.apache.regexp.RE */
+final class RegExpDelegate implements Regexp {
+    String pattern;
+    RE regexp;
+    public RegExpDelegate() { } 
+    public Vector getGroups(String arg) { 
+        String label = "getGroups(\"" + arg + "\") ";
+        D.log(label);
+        Vector result = null;
+        if ((null != arg) && (matches(arg))) {
+            int size = regexp.getParenCount();
+            D.log(label + " size " + size);
+            result = new Vector(size);
+            for (int i = 0; i < size; i++) {
+                Object item = regexp.getParen(i);
+                result.addElement(item);
+                D.log(label + i + ": " + item);
+            }
+        }
+        return result;
+    }
+    public boolean matches(String arg) {
+        return ((null != regexp) && regexp.match(arg));
+    }
+    public void setPattern(String pattern) throws Exception {
+        this.pattern = pattern;
+        regexp = new RE(this.pattern);
+        D.log("RE: " + regexp + " pattern: /" + pattern + "/");
+    }
+    public String getPattern()  {
+        return pattern;
+    }
+}
+
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/RegexpFilter.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/RegexpFilter.java
new file mode 100644 (file)
index 0000000..7ea6c7e
--- /dev/null
@@ -0,0 +1,622 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+// todo: non-distribution license?
+package org.aspectj.testing.compare;
+
+import org.aspectj.testing.compare.Regexp;
+
+import java.util.*;
+import java.io.*;
+
+
+/** utility class for logging */
+class D {
+    public static boolean LOG = false;
+    public static void log(String s) { if (LOG) System.err.println("## " + s); }
+    static {
+        try {
+            LOG = (null != System.getProperty("DEBUG"));
+        } catch (Throwable t) {
+            // ignore
+        }
+    }
+}
+
+/** utility class for handling errors */
+class ErrHandler {
+    public static final ErrHandler DEFAULT = new ErrHandler();
+    public static final Action INFO = new Action("info") {
+            public void invoke(String message) { System.out.println("INFO: " + message); } };
+    public static final Action WARN = new Action("warn") {
+            public void invoke(String message) { System.err.println("WARNING: " + message); } };
+    public static final Action HALT = new Action("halt") {
+            public void invoke(String message) { throw new RuntimeException(message); } };
+    public static final Action ABORT = new Action("abort") {
+            public void invoke(String message) { throw new Error(message); } };
+    public static final Action EXIT = new Action("exit") {
+            public void invoke(String message) { System.err.println(message); System.exit(1); } };
+    abstract static class Action { 
+        protected final String name;
+        private Action(String name) {
+            this.name = name.toLowerCase().trim();
+        }
+        abstract public void invoke(String message);
+        public String toString() { return name; }
+    }
+    public static final void handleErr(String message, Throwable t) { 
+        DEFAULT.handle(message, t);
+    }
+    public static final void handleErr(String message) { 
+        DEFAULT.handle(message);
+    }
+    public static final void handleErr(String message, Action suggestion) { 
+        DEFAULT.handle(message, suggestion);
+    }
+    public void handle(String message) { handle(message, INFO); }
+    public void handle(String message, Throwable t) { 
+        String eMessage = (null == t ? "" : 
+                           t.getClass().getName() + ": " + t.getMessage());
+        handle(message + eMessage, HALT);
+    }
+    /**
+     * The default implementation just takes the suggested action
+     * @param message the String to pass to any Action
+     * @param suggestion the Action proposed by the caller
+     */
+    public void handle(String message, Action suggestion) {
+        suggestion.invoke(message);
+    }
+}
+
+/* old comments, not correct:
+ * <li>test line against all registered select statements
+ *   to get all the matching (replace) operations (unsupported)</li>
+ * The algorithm is greedy in that if the user requests a line
+ * and the default is no-output, it will read lines from the input
+ * until one is matched (or EOF).
+ */
+
+/**  
+ * Process files in a minimal version of sed:
+ * <li>read line using superclass LineNumberReader.readLine()</li>
+ * <li>Preprocess with case and white space operations</li>
+ * <li>run all the replace operations on the input, in order</li>
+ * <li>return the line.</li>
+ * Using anything but the <code>readLine()</code> method will circumvent
+ * the regular expression replacement processing.
+ */
+public class RegexpFilter {
+    protected static final String[] NO_STRINGS = new String[]{};
+
+    // ---------------------------------------------- static methods
+    /**
+     * Process file (or System.in) like sed.
+     * This only calls <code>RegexpFilterReader.main(args)</code>.
+     * @param args  same as for init(String[], RegexpFilter)
+     */
+    public static void main(String[] args) throws IOException {
+        RegexpFilterReader.main(args);
+    }
+
+    // todo: move String -> String[] (commas) out into utility
+    /**
+     * Initialize a RegexpFilter based on command-line style arguments
+     * in a single String. (Otherwise, same as 
+     *  <code>init(String[], RegexpFilter)</code>)
+     * The Strings are separated at , (unless \ escaped) and trimmed.
+     * Note that the escape characters are removed from before the ,.
+     * @param spec the String to break into String[]
+     * @param toSet the RegexpFilter to initialize - if null, construct one from
+     *              the file argument or stdin if there is no file argument.
+     */
+    public static RegexpFilter init(String arg, RegexpFilter toSet) {
+        if ((null == arg) || (1 > arg.length())) {
+            return init(NO_STRINGS, toSet);
+        } 
+        StringTokenizer st = new StringTokenizer(arg, ",");
+        Vector result = new Vector();
+        String last = null;
+        String next;
+        while (st.hasMoreTokens()) {
+            next = st.nextToken();
+            if (next.endsWith("\\") && (st.hasMoreTokens())) {
+                next = next.substring(0, next.length()-1);
+                last = last == null ? next : last + next;
+                continue;
+            }
+            if (null != last) {
+                next = last + next;
+                last = null;
+            }
+            result.add(next.trim());
+        }
+        String[] args = new String[result.size()];
+        result.copyInto(args);
+        return RegexpFilter.init(args, toSet);
+    }
+
+    /**
+     * Initialize a RegexpFilter based on command-line style arguments.
+     * This is the only way (currently) to set up a RegexpFilter.
+     * syntax: <code>{file | {-i|-t|-b|-s <pattern>|-s <patternFile>}..}</code>
+     * (for booleans, use lowercase to enable, uppercase to disable).
+     * @param args  the String[] containing file to input plus any number of...
+     *              <li>-i "ignore": ignore case</li>
+     *              <li>-t "trim"  : ignore leading and trailing white space</li>
+     *              <li>-b "blanks": ignore differences in all white space</li>
+     *              <li>-s "{s/pattern/expression/};...": 
+     *                      replace pattern in lines with expression</li>
+     *              <li>-S <file>  : same as s, but read commands from file</li>
+     * @param toSet the RegexpFilter to initialize - if null, construct one from
+     *              the file argument or stdin if there is no file argument.
+     */
+    public static RegexpFilter init(String[] args, RegexpFilter toSet) {
+        final String syntax = " - syntax: {file | {-i|-t|-b|-s <pattern>|-s <patternFile>}..}";
+        RegexpFilter result = (null != toSet ? toSet : new RegexpFilter());
+        if ((null != args) && (0 < args.length)) {
+            for (int i = 0; i < args.length; i++) {
+                String arg = args[i];
+                if ((null == arg) || (1 > arg.length())) continue;
+                if (arg.startsWith("-"))  {
+                    switch (arg.charAt(1)) {
+                    case 'i' : result.ignoreCase = true; break;
+                    case 'I' : result.ignoreCase = false; break;
+                    case 'b' : result.collapseWhitespace = true; break;
+                    case 'B' : result.collapseWhitespace = false; break;
+                    case 't' : result.trimWhitespace = true; break;
+                    case 'T' : result.trimWhitespace = false; break;
+                    case 's' : ++i; 
+                        if (i < args.length) {
+                            result.getOperationList().addOperation(args[i]); 
+                        } else {
+                            String err = "need arg after -s " + syntax;
+                            ErrHandler.handleErr(err, ErrHandler.WARN); 
+                        }
+                    break; 
+                    case 'S' : ++i; 
+                        if (i < args.length) {
+                            result.getOperationList().addFile(args[i]); 
+                        } else {
+                            String err = "need arg after -s " + syntax;
+                            ErrHandler.handleErr(err, ErrHandler.WARN); 
+                        }
+                    break; 
+                    default: 
+                        String err = "unrecognized flag : " + arg + syntax;
+                        ErrHandler.handleErr(err, ErrHandler.WARN); 
+                        break;
+                    }
+                } else if (null != result) {
+                    ErrHandler.handleErr("unexpected arg " + arg + syntax, ErrHandler.WARN); 
+                    break;
+                } else { // unflagged argument, need file - should be input file
+                    File _file = new File(arg);
+                    if (_file.exists() && _file.canRead()) {
+                        result.setFile(_file);
+                    }
+                }
+            } // reading args
+        }  // have args
+        return result;
+    } // init
+    
+    // ---------------------------------------------- instance fields
+    /** ignore case by converting lines to upper case */
+    protected boolean ignoreCase  = false;
+    /** collapse internal whitespace by converting to space character */
+    protected boolean collapseWhitespace  = true;
+    /** trim leading and trailing whitespace from lines before comparison */
+    protected boolean trimWhitespace  = false;
+    /** replace input per replace operations */
+    protected boolean replace  = false;
+    /** operations to process the file with */
+    protected OperationList operations;
+    /** handler for our errors*/
+    protected ErrHandler handler  = ErrHandler.DEFAULT;
+    /** the File to use */
+    protected File file = null;
+
+    // ---------------------------------------------- constructors
+    /** no getter/setters yet, so construct using 
+     * <code>static RegexpFilter init(String[],RegexpFilter)</code> 
+     */
+    protected RegexpFilter() { }
+
+    // ---------------------------------------------- instance methods
+   
+
+    /**
+     * Set a file for this RegexpFilter.
+     * This makes command-line initialization easier.
+     * @param file the File to set for this RegexpFilter
+     */
+    public void setFile(File file) { this.file = file; } 
+
+    /**
+     * Return file this RegexpFilter was initialized with.
+     * @return the File this RegexpFilter was initialized with (may be null).
+     */
+    public File getFile() { return file; } 
+    /**
+     * Lazy construction of operations list
+     */
+    protected OperationList getOperationList() {
+        if (null == operations) {
+            operations = new OperationList();
+            replace = true;
+        }
+        return operations;
+    }
+
+    /**
+     * Process line, applying case and whitespace operations
+     * before delegating to replace.
+     * @param string the String to proces
+     * @return the String as processed
+     */
+    protected String process(String string) {
+        String label = "process(\"" + string + "\")";
+        D.log(label);
+        if (null == string) return null;
+        String result = string;
+        if (ignoreCase) {
+            result = result.toUpperCase();
+        }
+        if (trimWhitespace) {
+            result = result.trim();
+        }
+        if (collapseWhitespace) {
+            final StringBuffer collapse = new StringBuffer();
+            StringTokenizer tokens = new StringTokenizer(result);
+            boolean hasMoreTokens = tokens.hasMoreTokens();
+            while (hasMoreTokens) {
+                collapse.append(tokens.nextToken());
+                hasMoreTokens = tokens.hasMoreTokens();
+                if (hasMoreTokens) {
+                    collapse.append(" ");
+                }
+            }
+            result = collapse.toString();
+        }
+        if (replace) {
+            result = getOperationList().replace(result);
+            D.log(label + " result " + result);
+        }
+        return result;
+    }
+
+    /** 
+     * container for ReplaceOperations constructs on add,
+     * runs operations against input.
+     */
+    class OperationList {
+        final ArrayList list;
+        public OperationList() { 
+            list = new ArrayList();
+        }
+
+        /**
+         * Run input through all the operations in this list
+         * and return the result.
+         * @param input the String to process
+         * @return the String result of running input through all replace 
+         *         operations in order.
+         */
+        public String replace(String input) {
+            if (null == input) return null;
+            Iterator operations = operations();
+            while (operations.hasNext()) {
+                ReplaceOperation operation = (ReplaceOperation) operations.next();
+                input = operation.replace(input);
+            }
+            return input;
+        }
+
+        /**
+         * Add operations read from file, one per line,
+         * ignoring empty lines and # or // comments.
+         * ';' delimits operations within a line as it does
+         * for addOperation(String), so you must \ escape ;
+         * in the search or replace segments
+         */
+        public void addFile(String path) { 
+            if (null == path) {
+                handler.handle("null path", ErrHandler.ABORT);
+            } else {
+                File file = new File(path);
+                if (!file.exists() && file.canRead()) {
+                    handler.handle("invalid path: " + path, ErrHandler.ABORT);
+                } else {
+                    BufferedReader reader = null;
+                    int lineNumber = 0;
+                    String line  = null;
+                    try {
+                        reader = new BufferedReader(new FileReader(file));
+                        while (null != (line = reader.readLine())) {
+                            lineNumber++;
+                            int loc = line.indexOf("#");
+                            if (-1 != loc) {
+                                line = line.substring(0,loc);
+                            }
+                            loc = line.indexOf("//");
+                            if (-1 != loc) {
+                                line = line.substring(0,loc);
+                            }
+                            line = line.trim();
+                            if (1 > line.length()) continue;
+                            addOperation(line);
+                        }
+                    } catch (IOException e) {
+                        String message ="Error processing file " + path 
+                            + " at line " + lineNumber + ": \"" + line + "\""
+                            + ": " + e.getClass().getName() + ": " + e.getMessage() ;
+                        handler.handle(message, ErrHandler.ABORT);
+                    } finally {
+                        try  { 
+                            if (reader != null) reader.close();
+                        } catch (IOException e) {
+                            // ignore
+                        }
+                    }
+                }
+            }
+        }
+
+        /**
+         * Add operation to list, emitting warning and returning false if not created.
+         * Add multiple operations at once by separating with ';'
+         * (so any ; in search or replace must be escaped).
+         * @param operation a String acceptable to 
+         *                  <code>ReplaceOperation.makeReplaceOperation(String, ErrHandler)</code>,
+         *                  of the form sX{search}X{replace}X{g};..
+         * @return false if not all added.
+         */
+        public boolean addOperation(String operation) { 
+            StringTokenizer st = new StringTokenizer(operation, ";", false);
+            String last = null;
+            ReplaceOperation toAdd;
+            boolean allAdded = true;
+            while (st.hasMoreTokens()) {
+                // grab tokens, accumulating if \ escapes ; delimiter 
+                String next = st.nextToken();
+                if (next.endsWith("\\") && (st.hasMoreTokens())) {
+                    next = next.substring(0, next.length()-1);
+                    last = (last == null ? next : last + next);
+                    continue;
+                }
+                if (null != last) {
+                    next = last + next;
+                    last = null;
+                }
+                toAdd = ReplaceOperation.makeReplaceOperation(next, handler);
+                if (null != toAdd) {
+                    list.add(toAdd);
+                } else {
+                    String label = "RegexpFilter.OperationList.addOperation(\"" + operation + "\"): ";
+                    handler.handle(label + " input not accepted " , ErrHandler.WARN);
+                    if (allAdded) allAdded = false;
+                }
+            }
+            return allAdded;
+        }
+
+        /**
+         * @return an Iterator over the list of ReplaceOperation
+         */
+        public Iterator operations() {
+            return list.iterator();
+        }
+    } // class OperationList
+} // class RegexpFilter
+
+/**
+ * Encapsulate a search/replace operation which uses a RegExp.
+ */
+class ReplaceOperation {
+    /**
+     * This accepts a sed-like substitute command, except that
+     * the delimiter character may not be used anywhere in the 
+     * search or replace strings, even if escaped.  You may use
+     * any delimiter character.
+     * Note that although g (replace-globally) is supported as input, 
+     * it is ignored in this implementation.
+     * @param operation a String of the form sX{search}X{replace}X{g}
+     */
+    public static ReplaceOperation makeReplaceOperation(String operation, ErrHandler handler) {
+        ReplaceOperation result = null;
+        StringBuffer err = (null == handler ? null : new StringBuffer());
+        final String syntax = "sX{search}X{replace}X{g}";
+        // todo: use Point p = isValidOperation(operation);
+        if (null == operation) {
+            if (null != err) err.append("null operation");
+        } else if (5 > operation.length()) {
+            if (null != err) err.append("empty operation");
+        } else if (!operation.startsWith("s")) {
+            if (null != err) err.append("expecting s: " + syntax);
+       } else {
+            String sep = operation.substring(1,2);
+            int mid = operation.indexOf(sep, 2);
+            if (-1 == mid) {
+                if (null != handler) err.append("expecting middle \"" + sep + "\": " + syntax);
+            } else if (mid == 2) {
+                if (null != handler) err.append("expecting search before middle \"" + sep + "\": " + syntax);
+            } else {
+                int end = operation.indexOf(sep, mid+1);
+                if (-1 == end) {
+                    if (null != handler) err.append("expecting final \"" + sep + "\": " + syntax);
+                } else {
+                    String search = operation.substring(2,mid);
+                    if (!ReplaceOperation.isValidSearch(search)) {
+                        if (null != handler) err.append("invalid search \"" + search + "\": " + syntax);
+                    } else {
+                        String replace = operation.substring(mid+1,end);
+                        if (!ReplaceOperation.isValidReplace(replace)) {
+                            if (null != handler) err.append("invalid replace \"" + replace + "\": " + syntax);
+                        } else {
+                            result = new ReplaceOperation(search, replace, operation.endsWith("g"), handler);
+                        }
+                    }
+                }
+            }
+        }
+        if ((0 < err.length()) && (null != handler)) {
+            err.append(" operation=\"" + operation + "\"");
+            handler.handle(err.toString(), ErrHandler.HALT);
+        }
+        return result;
+    }
+
+    /**
+     * Return true if the input string represents a valid search operation
+     * @param replace the String representing a search expression
+     */
+    protected static boolean isValidSearch(String search) { // todo: too weak to be useful now
+        return ((null != search) && (0 < search.length()));
+    }
+
+    /**
+     * Return Point x=mid, y=end if the input string represents a valid search operation
+     * @param search the String representing a search expression
+    protected static Point isValidOperation(String search) {
+        if (null != search) {
+            final int length = search.length();
+            if (5 < length) {
+                String sep = search.substring(2,3);
+                int mid = search.indexOf(sep, 3);
+                if (3 < mid) {
+                    int end = search.indexOf(sep, mid+1);
+                    if ((end == length-1) 
+                        || ((end == length-2) 
+                            && search.endsWith("g"))) {
+                        return new Point(mid, end);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+     */
+
+    /**
+     * Return true if the input string represents a valid replace operation
+     * @param replace the String representing a replace expression
+     */
+    protected static boolean isValidReplace(String replace) { // todo: too weak to be useful now
+        boolean result = (null != replace); 
+        return result;
+    } // isValidReplace
+
+    // ------------------------------------------------- instance members
+    /** If true, repeat replace as often as possible (todo: repeat not supported) */
+    protected final boolean repeat;
+    /** search pattern */
+    protected final String search;
+    /** replace pattern */
+    protected final String replace;
+    /** regexp processor */
+    protected final Regexp regexp;
+    /** replace buffer (read-only) */
+    protected final char[] replaceBuffer;
+    /** error handler */
+    protected final ErrHandler handler;
+
+    // ------------------------------------------------- constructors
+    private ReplaceOperation(String search, String replace, boolean repeat, ErrHandler handler) {
+        this.search = search; 
+        this.replace = replace; 
+        this.replaceBuffer = replace.toCharArray();
+        this.repeat = repeat; 
+        this.handler = (null != handler ? handler : ErrHandler.DEFAULT);
+        this.regexp = RegexpFactory.makeRegexp();
+        try {
+            this.regexp.setPattern(search);
+        } catch (Exception e) {
+            this.handler.handle("setting search=" + search, e);
+        }
+    }
+
+
+    /**
+     * Return true if the input would be matched by the search string of this ReplaceOperation.
+     * @param input the String to compare
+     * @return true if the input would be matched by the search string of this ReplaceOperation
+     */
+    public boolean matches(String input) {
+        return ((null != input) && regexp.matches(input));
+    } // matches
+
+    /**
+     * Replace any search text in input with replacement text, 
+     * returning input if there is no match. More specifically, 
+    * <li> emit unmatched prefix, if any</li>
+    * <li> emit replacement text as-is, except that
+    *   \[0-9] in the replacement text is replaced
+    *   with the matching subsection of the input text</li>
+    * <li> emit unmatched suffix, if any</li>
+     * @param input the String to search and replace
+     * @throws IllegalArgumentException if null == input 
+     */
+    public String replace(String input) {
+        if (null == input) throw new IllegalArgumentException("null input");
+        String label = "replace(\"" + input + "\") ";
+        D.log(label);
+        if (matches(input)) {
+            StringBuffer buffer = new StringBuffer();
+            final int length = replaceBuffer.length;
+            Vector groups = regexp.getGroups(input);
+            if ((null == groups) || (1 > groups.size())) {
+                handler.handle(label + "matched but no groups? ");
+                return input;
+            }
+            buffer.setLength(0);
+            // group 0 is whole; if not same as input, print prefix/suffix
+            String matchedPart = (String) groups.elementAt(0);
+            final int matchStart = input.indexOf(matchedPart);
+            final int matchEnd = matchStart + matchedPart.length();
+            if (0 < matchStart) {
+                buffer.append(input.substring(0, matchStart));
+            }
+            // true if \ escaping special char, esp. replace \[0-9]
+            boolean specialChar = false; 
+            for (int i = 0; i < length; i++) {
+                char c = replaceBuffer[i];
+                if (specialChar) { 
+                    int value = Character.digit(c, 10); // only 0-9 supported
+                    if ((0 <= value) && (value < groups.size())) {
+                        buffer.append((String) groups.elementAt(value));
+                    } else {
+                        buffer.append(c);
+                    }
+                    specialChar = false;
+                } else if ('\\' != c) {
+                    D.log("." + c);
+                    buffer.append(c);
+                } else {
+                    specialChar = true;
+                }
+            }
+            if (specialChar) {
+                handler.handle(label + "\\ without register: " + replace,
+                               ErrHandler.ABORT);
+            }
+            if (matchEnd < input.length()) {
+                buffer.append(input.substring(matchEnd));
+            }
+            input = buffer.toString();
+        }
+        return input;
+    } // replace
+} // class ReplaceOperation
+
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/RegexpFilterReader.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/RegexpFilterReader.java
new file mode 100644 (file)
index 0000000..5021a5e
--- /dev/null
@@ -0,0 +1,291 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+package org.aspectj.testing.compare;
+
+
+import org.aspectj.testing.util.StringVisitor;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.util.Vector;
+
+/**
+ * Adapt Writer to StringVisitor, with pre- and post-write
+ * methods for subclasses to override.
+ */
+class StringDumper implements StringVisitor {
+    /** subclasses should write errors here and be silent if null */
+    protected PrintStream errSink;
+    private final boolean appendNewlines;
+    private final BufferedWriter writer;
+    /** true only if writer non-null and close() was invoked */
+    private boolean closed;
+
+    /**
+     * @param writer the Writer to write to - ignored if null
+     * @param appendNewLines if true, append newlines after writing
+     */
+    public StringDumper(BufferedWriter writer, boolean appendNewlines) {
+        this.appendNewlines = appendNewlines;
+        this.writer = writer;
+        // closed = false;
+        errSink = System.err;
+    }
+
+    /**
+     * Set error sink - may be null to ignore IOExceptions.
+     * @param err the PrintStream to use for errors (silent if null)
+     */
+    public void setErrorSink(PrintStream err) {
+        errSink = err;
+    }
+
+    /**
+     * Invoked before the String is written.
+     * This implementation does nothing.
+     * @param string the String to be written
+     * @return false if writing should abort
+     */
+    protected boolean preWrite(String string) 
+        throws IOException {
+        return true;
+    }
+
+    /**
+     * Implement StringVisitor.accept(String)
+     * by doing preWrite(String), process(String),
+     * writer.write(String...), and postWrite(String),
+     * any one of which may result in a false return value.
+     * @throws Error if invoked after <code>close()</code>
+     */
+    public final boolean accept(String string) {
+        if (closed) {
+            String m = "did close() before accept(\"" + string + "\")";
+            throw new Error(m);
+        }
+        if (null == writer) return false;
+        try {
+            if (!preWrite(string)) return false;
+            string = process(string);
+            if (null == string) return false;
+            if (null != writer) writer.write(string, 0, string.length());
+            if (!postWrite(string)) return false;
+        } catch (IOException e) {
+            PrintStream sink = errSink;
+            if (null != sink) e.printStackTrace(sink);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Transform the input before writing.
+     * This implementation returns the input.
+     * @param string the String to transform
+     * @return the String as changed - if null,
+     *         then halt and return false from the accept method.
+     */
+    protected String process(String string) {
+        return string;
+    }
+
+    /**
+     * Invoked after the String is written.
+     * This implementation handles writing of the newline.
+     * @param string the String that was written
+     * @return false if writing should abort
+     */
+    protected boolean postWrite(String string) 
+        throws IOException {
+        if (appendNewlines && null != writer) {
+            writer.newLine();
+        }
+        return true;
+    }
+
+    /** convenience method to close adopted writer */
+    public void close() throws IOException {
+        if (null != writer) {
+            writer.close();
+            closed = true;
+        }
+    }
+}
+class FilteredDumper extends StringDumper {
+    protected final RegexpFilter filter;
+    public FilteredDumper(BufferedWriter writer, 
+                          boolean appendNewlines,
+                          RegexpFilter filter) {
+        super(writer, appendNewlines);
+        this.filter = filter;
+    }
+    public String process(String arg) {
+        return filter.process(arg);
+    }
+}
+
+class FilteredAccumulator extends FilteredDumper {
+    protected final Vector results;
+    public FilteredAccumulator(RegexpFilter filter) {
+        super(null, false, filter);
+        results = new Vector();
+    }
+    public String process(String arg) {
+        arg = super.process(arg);
+        synchronized (results) {
+            results.add(arg);
+        }
+        return arg;
+    }
+    public Vector getResults() {
+        synchronized (results) {
+            return (Vector) results.clone();
+        }
+    }
+}
+
+/**  
+
+/**  
+ * Input file, using a RegexpFilter to preprocess each line.
+ * <li>read line using superclass LineNumberReader.readLine()</li>
+ * <li>Preprocess with case and white space operations</li>
+ * <li>run all the replace operations on the input, in order</li>
+ * <li>return the line.</li>
+ * Using anything but the <code>readLine()</code> method will circumvent
+ * the regular expression replacement processing.
+ */
+public class RegexpFilterReader extends BufferedReader {
+
+    // ---------------------------------------------- static methods
+
+    /**
+     * Pass lines from BufferedReader to visitor.
+     * Stop reading lines if visitor returns false.
+     * @param input the BufferedReader with the input 
+     *              - if null, use System.in
+     * @param visitor the StringVisitor to pass each line 
+     *                if null, just read in all lines and ignore
+     */
+    public static void visitLines(BufferedReader input, 
+                                  StringVisitor visitor) 
+        throws IOException {
+        final boolean openInput = (null == input);
+        if (openInput) input = new BufferedReader(new InputStreamReader(System.in));
+        try {
+            String line = null;
+            if (null == visitor) { 
+                while (null != (line = input.readLine())) { 
+                    // read and ignore
+                }
+            } else {
+                while (null != (line = input.readLine())) { 
+                    if (!visitor.accept(line)) {
+                        break;
+                    }
+                }
+            }
+        } finally {
+            if (openInput && (null != input)) {
+                try { input.close(); }  // todo: ok to close since System.in underlies?
+                catch (IOException e) {
+                    e.printStackTrace(System.err);
+                }
+            }
+        }
+    } // visitLines
+
+    // todo move write(in,out) to a utility class
+    /**
+     * Convenience method to write one file to another by line.
+     * Neither input nor output are closed.
+     * @param input the BufferedReader with the input - if null, use System.in
+     * @param output the BufferedWriter for the output - if null, use System.out
+     */
+    public static void write(BufferedReader input, 
+                             BufferedWriter output)  
+        throws IOException {
+        final boolean openOutput = (null == output);
+        if (openOutput) output = new BufferedWriter(new OutputStreamWriter(System.out));
+        StringDumper visitor = new StringDumper(output, true);
+        try {
+            RegexpFilterReader.visitLines(input, visitor);
+        } finally {
+            if (openOutput && (null != visitor)) {
+                try { visitor.close(); }  // todo: ok to close since System.out underlies?
+                catch (IOException e) {
+                    e.printStackTrace(System.err);
+                }
+            }
+        }
+    } // write
+
+    /**
+     * Process file (or System.in) like sed.
+     * @param args  the String[] containing RegexpFilter arguments
+     */
+    public static void main(String[] args) throws IOException {
+        RegexpFilter filter = RegexpFilter.init(args, null);
+        if (null != filter) {
+            File file = filter.getFile();
+            Reader reader = null;
+            if (file != null) {
+                reader = new FileReader(file);
+            } else {
+                reader = new InputStreamReader(System.in);
+            }
+            RegexpFilterReader me = new RegexpFilterReader(reader);
+            me.setFilter(filter);
+            RegexpFilterReader.write(me, null);
+        }
+    }
+
+    // ---------------------------------------------- constructors
+    public RegexpFilterReader(Reader reader) {
+        super(reader);
+    }
+    public RegexpFilterReader(Reader reader, int size) {
+        super(reader, size);
+    }
+
+    // ---------------------------------------------- instance fields
+    protected RegexpFilter filter;
+    // ---------------------------------------------- instance methods
+    public void setFilter(RegexpFilter filter) {
+        this.filter = filter;
+    }
+   
+    /**
+     * Process each line as it is read in by the superclass.
+     */
+    public String readLine() throws IOException {
+        RegexpFilter filter = this.filter;
+        String line =  super.readLine();
+        if (null != filter) {
+            line = filter.process(line);
+        }
+        return line;
+    }
+
+} // class RegexpFilterReader
+
+
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/TreeCompare.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/TreeCompare.java
new file mode 100644 (file)
index 0000000..cbf92da
--- /dev/null
@@ -0,0 +1,217 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare;
+import org.aspectj.testing.compare.adapters.StructureGenericTreeNodeFactory;
+import org.aspectj.testing.compare.adapters.JTreeNodeGenericTreeNodeFactory;
+import org.aspectj.testing.compare.adapters.GenericTreeNodeFactoryI;
+// target
+// XXX compiler import org.aspectj.asm.StructureNode;
+// testing
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.DefaultMutableTreeNode;
+// utils
+import java.io.*;
+
+/**
+ * Compare two generic trees for tree-equality.
+ * Currently does not indicate where or how they failed.
+ * Input trees are serialized to disk in a format that
+ * is (or can be wrapped using) <code>GenericTreeNode</code>.
+ * requires files expected.ser and actual.ser
+ * to deserialize to type StructureNode (untested - use Structure)
+ * or Swing TreeNode.
+ */
+public class TreeCompare {
+    public static boolean DODIFF;
+       /**
+        * @param args ignored - reading expected.ser and actual.ser
+        */
+    public static void main(String[] args) {
+        TreeCompare me = new TreeCompare();
+        File expected = new File("expected.ser");
+        File actual = new File("actual.ser");
+        if ((args.length > 0)
+            || (!expected.exists() || (!actual.exists()))) {
+            DODIFF = (args.length > 1);
+            takeSnapshot(expected);
+            takeSnapshot(actual);
+        }
+        me.compareSnapshots(expected, actual);
+    }
+    private static void takeSnapshot(File file) {
+        DefaultMutableTreeNode snapshot = getRoot(file) ;
+        ObjectOutputStream p = null;
+        FileOutputStream ostream = null;
+        try {
+            ostream = new FileOutputStream(file);
+            p = new ObjectOutputStream(ostream);
+            p.writeObject(snapshot);
+        } catch (IOException e) {
+            e.printStackTrace(System.err);
+        } finally {
+            try {
+                if (null != p) p.flush();
+                if (null != ostream) ostream.close();
+            } catch (IOException o) {} // ignored
+        }
+    }
+
+    private static DefaultMutableTreeNode getRoot(File file) {
+        boolean isActual = (!DODIFF ? false : (-1 != (file.getPath().indexOf("actual"))));
+        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Edna");
+        DefaultMutableTreeNode child = new DefaultMutableTreeNode("Evalyn");
+        root.add(child);
+        child.add(new DefaultMutableTreeNode("Marsha"));
+        child.add(new DefaultMutableTreeNode("Ray"));
+        if (DODIFF && isActual) { // Bill added to actual
+            child.add(new DefaultMutableTreeNode("Bill"));
+        }
+        child = new DefaultMutableTreeNode("Clifford");
+        root.add(child);
+        child.add(new DefaultMutableTreeNode("Terry"));
+        if (DODIFF && isActual) { // Peter mispelled in actual
+            child.add(new DefaultMutableTreeNode("peter"));
+        } else {
+            child.add(new DefaultMutableTreeNode("Peter"));
+        }
+        child.add(new DefaultMutableTreeNode("Mary"));
+        child = new DefaultMutableTreeNode("Anastasia");
+        root.add(child);
+        child.add(new DefaultMutableTreeNode("Victor"));
+        child.add(new DefaultMutableTreeNode("Valerie"));
+        child.add(new DefaultMutableTreeNode("Valentine"));
+        if (DODIFF && isActual) { // Vim added in actual, with a child
+            DefaultMutableTreeNode par = new DefaultMutableTreeNode("VimAdded");
+            par.add(new DefaultMutableTreeNode("Vim kid"));
+            child.add(par);
+        }
+        return root;
+    }
+
+    /**
+     * Compare two File by reading in as serialized
+     * and selecting the appropriate wrappers for the resulting
+     * Object.
+     */
+    public void compareSnapshots(File expected, File actual) {
+        try {
+            // construct the respective trees
+            FileInputStream efStream = new FileInputStream(expected);
+            ObjectInputStream eStream  = new ObjectInputStream(efStream);
+            FileInputStream afStream = new FileInputStream(actual);
+            ObjectInputStream aStream  = new ObjectInputStream(afStream);
+            Object expectedObject = eStream.readObject();
+            Object actualObject = aStream.readObject();
+            Class expectedObjectClass = (null == expectedObject ? null : expectedObject.getClass());
+            Class actualObjectClass = (null == actualObject ? null : actualObject.getClass());
+            // todo yuck: switch by type using known factories
+// XXX compiler
+//            if (StructureNode.class.isAssignableFrom(expectedObjectClass)) {
+//                             if (StructureNode.class.isAssignableFrom(actualObjectClass)) {
+//                    compareSnapshots((StructureNode) expectedObject,(StructureNode) actualObject);
+//                    System.err.println("ok");
+//                } else {
+//                    signalDifferentTypes(expectedObject, actualObject);
+//                }
+//            } else if (DefaultMutableTreeNode.class.isAssignableFrom(expectedObjectClass)) {
+//                             if (DefaultMutableTreeNode.class.isAssignableFrom(actualObjectClass)) {
+//                    compareSnapshots((DefaultMutableTreeNode) expectedObject,
+//                                                                      (DefaultMutableTreeNode) actualObject);
+//                } else {
+//                    signalDifferentTypes(expectedObject, actualObject);
+//                }
+//            } else {
+                System.err.println("Unrecognized objects - expected: "
+                                   + expectedObject + " actual: " + actualObject);
+//            }
+        } catch (Throwable t) {
+            System.err.println("TEST FAILED: " + t.getMessage());
+            t.printStackTrace(System.err);
+            return;
+        }
+    } // compareSnapshots(File, File)
+
+    public void signalDifferentTypes(Object lhs, Object rhs) {
+        Class lhc = lhs.getClass();
+        Class rhc = rhs.getClass();
+        String err = "Different Types? lhs: " + lhc + "=" + lhs
+            + " rhs: " + rhc + "=" + rhs;
+        throw new Error(err);
+    }
+
+    /**
+     * Compare two StructureNode by wrapping in GenericTreeNode
+     */
+// XXX compiler
+//    public void compareSnapshots(StructureNode expected, StructureNode actual) {
+//        try {
+//            GenericTreeNodeFactoryI factory =
+//                StructureGenericTreeNodeFactory.SINGLETON;
+//            // this is the custom part: adapter generating generic model
+//            GenericTreeNode expectRoot
+//                = factory.createGenericTreeNode(expected, null);
+//            GenericTreeNode actualRoot
+//                = factory.createGenericTreeNode(actual, null);
+//            if (null == actualRoot) System.err.println("null actualRoot");
+//            if (null == expectRoot) System.err.println("null expectRoot");
+//            compareSnapshots(expectRoot, actualRoot);
+//        } catch (Throwable t) {
+//            System.err.println("TEST FAILED: " + t.getMessage());
+//            t.printStackTrace(System.err);
+//            return;
+//        }
+//    } // compareSnapshots(TreeModel, TreeModel)
+
+    /**
+     * Compare two Swing TreeModel by wrapping in GenericTreeNode
+     */
+    public void compareSnapshots(TreeNode expected, TreeNode actual) {
+        try {
+            GenericTreeNodeFactoryI factory =
+                JTreeNodeGenericTreeNodeFactory.SINGLETON;
+            // this is the custom part: adapter generating generic model
+            GenericTreeNode expectRoot
+                = factory.createGenericTreeNode(expected, null);
+            GenericTreeNode actualRoot
+                = factory.createGenericTreeNode(actual, null);
+            if (null == actualRoot) System.err.println("null actualRoot");
+            if (null == expectRoot) System.err.println("null expectRoot");
+            compareSnapshots(expectRoot, actualRoot);
+        } catch (Throwable t) {
+            System.err.println("TEST FAILED: " + t.getMessage());
+            t.printStackTrace(System.err);
+            return;
+        }
+    } // compareSnapshots(TreeModel, TreeModel)
+
+    /** Compare GenericTreeNode trees exactly, printing errors */
+    public void compareSnapshots(GenericTreeNode expected, GenericTreeNode actual) {
+        try {
+            //GenericTreeNodesVisitorI visitor = GenericTreeNode.PRINTALL;
+            GenericTreeNodesVisitorI visitor = GenericTreeNode.PRINTERR;
+            //GenericTreeNodesVisitorI visitor = GenericTreeNode.EXACT;
+
+            if (GenericTreeNode.traverse(expected, actual, null, visitor)) {
+                System.err.println("TEST PASSED");
+            } else {
+                System.err.println("TEST FAILED");
+            }
+        } catch (Throwable t) {
+            System.err.println("TEST FAILED: " + t.getMessage());
+            t.printStackTrace(System.err);
+            return;
+        }
+    } // compareSnapshots(GenericTreeNode, GenericTreeNode)
+} // TreeCompare
+
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/GenericTreeNodeFactoryI.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/GenericTreeNodeFactoryI.java
new file mode 100644 (file)
index 0000000..adee3d3
--- /dev/null
@@ -0,0 +1,33 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare.adapters;
+
+import org.aspectj.testing.compare.GenericTreeNode;
+/**
+ * Encapsulate the implementation of an factory to create
+ * a GenericTreeNode tree from a given input type, to permit
+ * a general, pluggable factory to operate based on source type.
+ */
+public interface GenericTreeNodeFactoryI {
+    /** @return the expected Class of the root node supported by this factory */
+    public Class getRootClass();
+
+    /**
+     * Create a wrapped generic tree with the input root tree as delegates.
+     * @param root the {rootClass} root of the tree to convert - never null
+     * @throws IllegalArgumentException if root is null or not assignable to rootClass
+     */
+    public GenericTreeNode createGenericTreeNode(Object root, GenericTreeNode parent);
+}
+
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/JTreeNodeGenericTreeNodeFactory.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/JTreeNodeGenericTreeNodeFactory.java
new file mode 100644 (file)
index 0000000..5f48eef
--- /dev/null
@@ -0,0 +1,102 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare.adapters;
+
+import org.aspectj.testing.compare.GenericTreeNode;
+import org.aspectj.testing.compare.*;
+
+import javax.swing.tree.*; // sample uses TreeModel...
+import java.util.*; 
+
+/**
+ * Factory for adapting Swing TreeNode to GenericTreeNode
+ */
+public class JTreeNodeGenericTreeNodeFactory implements GenericTreeNodeFactoryI {
+    public static final GenericTreeNodeFactoryI SINGLETON
+        = new JTreeNodeGenericTreeNodeFactory();
+    private JTreeNodeGenericTreeNodeFactory() {}
+    public Class getRootClass() {
+        return TreeNode.class;
+    }
+
+    /** 
+     * Adapt swing TreeModel to tree rooted at GenericTreeNode 
+     * Only takes the current state of a TreeModel which does not
+     * change during the construction of the adapter. If the
+     * TreeModel changes, you can ask the adapter for a newly
+     * wrapped tree.
+     * Recursively convert entire tree from root to a wrapped tree
+     * Note this takes a snapshot of the tree such that changes to
+     * the TreeModel after the constructor returns are ignored.
+     * Changes during the constructor produce undetermined results.
+     * @param root the TreeNode taken as root of a tree to wrap
+     * @param parent the parent of the resulting GenericTreeNode
+     * @throws IllegalArgumentException if root is null 
+     *         or if children are not instanceof TreeNode.
+     */
+    public GenericTreeNode createGenericTreeNode(Object root, GenericTreeNode parent) {
+        if (null == root) {
+            throw new IllegalArgumentException("null root");
+        }
+        if (! (root instanceof TreeNode)) {
+            throw new IllegalArgumentException("not TreeNode: " + root);
+        }
+        TreeNode rootNode = (TreeNode) root;
+        final int numKids = rootNode.getChildCount();
+        ArrayList kids = new ArrayList(numKids);
+        Enumeration children = rootNode.children();
+        Object child;
+        GenericTreeNode result = new GenericTreeNode();
+        for (int i = 0; i < numKids; i++) {
+            if (! children.hasMoreElements()) {
+                throw new Error("(! children.hasNext())");
+            } 
+            child = children.nextElement();
+            if (! (child instanceof TreeNode)) {
+                throw new Error("! (child instanceof TreeNode)): " + child );
+            }
+            kids.add(createGenericTreeNode((TreeNode) child, result));
+        }
+        //result.init(parent, GenericTreeNode.COMPARATOR, rootNode, kids, null);
+        result.init(parent, JTreeNodeComparator.SINGLETON, rootNode, kids, null);
+        return result;
+    } 
+
+    /** Comparator for swing TreeNode todo convert from TreeNode to DefaultMutableTreeNode */
+    static class JTreeNodeComparator implements Comparator {
+        public static Comparator SINGLETON = new JTreeNodeComparator();
+        private JTreeNodeComparator () {}
+        public int compare(Object lhs, Object rhs) {
+            int result = CompareUtil.compare(lhs, rhs);
+            if (Integer.MAX_VALUE == result) {
+                Class lhClass = lhs.getClass() ;
+                Class rhClass = rhs.getClass() ;
+                if ((DefaultMutableTreeNode.class.isAssignableFrom(lhClass)) 
+                    && (DefaultMutableTreeNode.class.isAssignableFrom(rhClass))) {
+                    DefaultMutableTreeNode lh = (DefaultMutableTreeNode) lhs ;
+                    DefaultMutableTreeNode rh = (DefaultMutableTreeNode) rhs ;
+                    Object lhObject = lh.getUserObject();
+                    Object rhObject = rh.getUserObject();
+                    result = CompareUtil.compare(lhs, rhs);
+                    if (Integer.MAX_VALUE == result) {
+                        result = lhObject.toString().compareTo(rhObject.toString());
+                    }
+                } else { // urk - broken unless wrapper
+                    result = lhs.toString().compareTo(rhs.toString());
+                }
+            }
+            return result;
+        }
+    }
+}
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/Structure.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/Structure.java
new file mode 100644 (file)
index 0000000..b669f7c
--- /dev/null
@@ -0,0 +1,438 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare.adapters;
+
+import org.aspectj.testing.compare.GenericTreeNode;
+import org.aspectj.testing.compare.GenericTreeNodesVisitorI;
+import org.aspectj.testing.compare.GenericTreeNodeListOrdererFactoryI;
+import org.aspectj.testing.compare.GenericTreeNodeListOrdererI;
+import org.aspectj.testing.compare.adapters.StructureGenericTreeNodeFactory;
+
+// XXX compiler import org.aspectj.asm.StructureNode;
+// XXX wes move to ajde tests import org.aspectj.tools.ajde.StructureUtilities;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * Compare or print (serialized) structure tree/graph(s).
+ * Mostly thread-safe, except that (todo for now) PRINT_SINK is a mutable static
+ * variable settable by the arguments.
+ * See {@link #main(String[]) main} for usage.
+ */
+public class Structure {
+    // ---------------------------------- static fields
+    // PRINT_SINK as static permits static inner class singleton visitors to reflect output sink policy
+    /** WARNING: print sink changeable at runtime (affects all instances of class!) */
+    public static PrintStream PRINT_SINK = System.err;
+
+    /** singleton factory to sort by string */
+    protected static final GenericTreeNodeListOrdererFactoryI STRING_SORTER_FACTORY
+        = new StringSortFactory();
+    /** singleton factory to sort by string */
+    protected static final GenericTreeNodeListOrdererI STRING_SORTER
+        = new StringSort();
+    /** singleton to sort by string */
+    protected static final Comparator STRING_COMP = new StringComparator();
+    /** default visitor printer expects only one of pair and render each parent as tab */
+    protected static final GenericTreeNodesVisitorI PRINT_EACH = new PrintEach();
+    /** visitor printer prints long version of both input (todo: not redirected by toOut) */
+    protected static final GenericTreeNodesVisitorI PRINT_ALL = GenericTreeNode.PRINTALL;
+    /** visitor printer prints long version of both input if non-matching (todo: not redirected by toOut) */
+    protected static final GenericTreeNodesVisitorI PRINT_ERR = GenericTreeNode.PRINTERR;
+    /** parms: default list of files used if no files given */
+    public static final String DEFAULT_LST = "default.lst";
+    /** parms: default argument list if none given */
+    public static final String[] DEFAULT_ARGS = new String[]
+    { "-d" , "classes" , "-workingdir", "ajworkingdir", "-argfile", DEFAULT_LST};
+
+    // ---------------------------------- static methods
+    /**
+     * Print and/or compare Structure trees.
+     * One (actual) can be compiled at the same time;
+     * either (expected or actual) may be read in from a serialized tree.
+     * Supported arguments:
+     * <table>
+     * <tr><td>{ajc compiler args}</td>
+     *     <td>The set of compiler arguments, to compile a new tree</td></tr>
+     * <tr><td>-expect {file}.ser</td>
+     *     <td>The old Structure tree to read in and compare with new</td></tr>
+     * <tr><td>-actual {file}.ser</td>
+     *     <td>The new Structure tree to read in (i.e., no compile)</td></tr>
+     * <tr><td>-save {file}.ser</td>
+     *     <td>Serialize the results of the compile to {file}.ser.</td></tr>
+     * <tr><td>-printall</td>
+     *     <td>Print all pairs in long format</td></tr>
+     * <tr><td>-printeach</td>
+     *     <td>Print each item in short format
+     *         - used when only one tree is available</td></tr>
+     * <tr><td>-printerr</td>
+     *     <td>Print pairs of items that do not match
+     *         - used when only both trees are available</td></tr>
+     * <tr><td>-sortString</td>
+     *     <td>before comparing, do a string-sort on each child list.</td></tr>
+     * <tr><td>-toOut</td>
+     *     <td>Redirect output from System.err to System.out (for all instances of this class)</td></tr>
+     * <tr><td>-notest</td>
+     *     <td>Do not run test (e.g., just compile and save)</td></tr>
+     * </table>
+     * @param args the String[] of arguments for this test - defaults supplied if empty.
+     */
+    public static void main(String[] args) {
+        new Structure().runTest(args);
+    }
+
+    // ---------------------------------- static util
+    protected static final void log(String s) {
+        final PrintStream sink = PRINT_SINK;
+        if ((null != s) &&  (null != sink)) {
+            sink.println("Structure: " + s);
+        }
+    }
+
+    protected static void signal(String message) {
+        log(message);
+    }
+    protected static void signal(String context, String event) {
+        log(context + ": " + event);
+    }
+    protected static void signal(String context, Throwable event) {
+        if (null == event) {
+            log(context);
+        } else {
+            String msg = event.getMessage();
+            log(context + ": " + msg);
+            event.printStackTrace(PRINT_SINK);
+        }
+    }
+
+    // ---------------------------------- instance fields
+    /** args result: path to serialize actual tree to */
+    protected String actualSavePath = null;
+    /** args result: path of actual serialized tree */
+    protected String actualPath = null;
+    /** args result: path of expected serialized tree */
+    protected String expectedPath = null;
+    /** args result: false if not running comparisons */
+    protected boolean doComparison = true;
+
+    /** visitor to run - print or test (default is PRINT_ALL) */
+    protected GenericTreeNodesVisitorI visitor = PRINT_ALL;
+    /** this determines for each set of children whether/how to sort them */
+    protected GenericTreeNodeListOrdererFactoryI sorter = null;
+
+    // ---------------------------------- instance methods
+    /** no-arg (default) constructor */
+    public Structure() { }
+
+    /**
+     * Clear settings before running.
+     * Use this unless you want to inherit settings from
+     * a prior run.  You can specify new arguments that
+     * overwrite the old settings.
+     * @param args the String[] used for runTest(String[])
+     * @see #clear()
+     * @see #runTest(String[])
+     */
+    public synchronized void clearAndRunTest(String[] args) {
+        actualSavePath = null;
+        actualPath = null;
+        expectedPath = null;
+        doComparison = true;
+        visitor = PRINT_ALL;
+        runTest(args);
+    }
+
+    /**
+     * Read and/or write and/or compare structure trees.
+     * Any results are delivered by the comparison visitors.
+     * The test process is as follows:
+     * <li>processArgs(..)</li>
+     * <li>saveActual(..) if saving actual to file</li>
+     * <li>doComparison(..) of actual and expected per visitor/sorter options</li>
+     * <p>If you run this consecutively, you'll inherit the values
+     * of the last run that you do not overwrite
+     * unless you invoke {@link #clear()}.  The method synchronization
+     * will not prevent another thread from interrupting your
+     * @param args the String[] defined by <code>main(String[] args)</code>
+     */
+    public synchronized void runTest(String[] args) {
+        if (null == args) throw new IllegalArgumentException("null args");
+        args = processArgs(args);
+        if (null == args) throw new IllegalArgumentException("bad args");
+// XXX compiler 
+////        StructureNode lhsRoot = loadStructureNode(expectedPath);
+////        StructureNode rhsRoot = loadStructureNode(actualPath);
+////        if (null == rhsRoot) { // not serialized - try compile
+////            // XXX wes move to ajde tests rhsRoot = StructureUtilities.buildStructureModel(args);
+////        }
+////        // save actual, if requested
+////        saveActual(rhsRoot);
+////        // do comparison (i.e., run test)
+////        doComparison(lhsRoot, rhsRoot);
+    }
+
+   /**
+     * Process arguments by extracting our arguments from callee arguments
+     * and initializing the class accordingly.
+     * {@link See main(String[])} for a list of valid arguments.
+     * @param args the String[] adopted, elements shifted down to remove ours
+     * @return a String[] containing args not relevant to us (i.e., for callee = compiler)
+     */
+    protected String[] processArgs(String[] args) {
+        if ((null == args) || (1 > args.length)) {
+            return processArgs(DEFAULT_ARGS);
+        }
+        int numFiles = 0;
+        int numArgFiles = 0;
+        final String SKIP = "skip";
+        String calleeArg;
+        int readIndex = 0;
+        int writeIndex = 0;
+        while (readIndex < args.length) {
+            final String arg = args[readIndex];
+            calleeArg = arg;
+            // assume valid arg for callee unless shown to be ours
+            if ((null == arg) || (0 == arg.length())) {
+                signal("processArgs", "empty arg at index "+ readIndex);
+                break;
+            } else if (arg.startsWith("@") || "-argfile".equals(arg)) {
+                numArgFiles++;
+            } else if (arg.endsWith(".java")) {
+                numFiles++;
+            } else if (arg.startsWith("-")) {
+                calleeArg = SKIP; // assume args are ours unless found otherwise
+                if ("-toOut".equals(arg)) {
+                    Structure.PRINT_SINK = System.out;
+                } else if ("-notest".equals(arg)) {
+                    doComparison = false;
+                } else if ("-printall".equals(arg)) {
+                    visitor = PRINT_ALL;
+                } else if ("-printeach".equals(arg)) {
+                    visitor = PRINT_EACH;
+                } else if ("-printerr".equals(arg)) {
+                    visitor = PRINT_ERR;
+                } else if ("-sortString".equals(arg)) {
+                    sorter = STRING_SORTER_FACTORY;
+                } else {  // the rest of ours require a parm
+                    readIndex++;
+                    String next = ((readIndex < args.length)
+                                   ? args[readIndex] : null);
+                    boolean nextIsOption
+                        = ((null != next) && next.startsWith("-"));
+                    if ("-expect".equals(arg)) {
+                        expectedPath = next;
+                    } else if ("-actual".equals(arg)) {
+                        actualPath = next;
+                    } else if ("-save".equals(arg)) {
+                        actualSavePath = next;
+                    } else {
+                        readIndex--;
+                        calleeArg = arg; // ok, not ours - save
+                    }
+                    if ((calleeArg == SKIP)
+                        && ((null == next) || (nextIsOption))) {
+                        signal("processArgs", arg + " requires a parameter");
+                        break;
+                    }
+                }
+            }
+            if (SKIP != calleeArg) {
+                args[writeIndex++] = calleeArg;
+            }
+            readIndex++;
+        }  // end of reading args[]
+        if (readIndex < args.length) { // bad args[] - abort (see signals above)
+            return null;
+        }
+        // if no input specified, supply default list file
+        if ((0 == numFiles) && (0 == numArgFiles) && (null == actualPath)) {
+            if (writeIndex+3 > args.length) {
+                String[] result = new String[writeIndex+2];
+                System.arraycopy(args, 0, result, 0, writeIndex);
+                args = result;
+            }
+            args[writeIndex++] = "-argfile";
+            args[writeIndex++] = DEFAULT_LST;
+        }
+        // if some args clipped (ours), clip array to actual (callee)
+        if (writeIndex < args.length) {
+            String[] result = new String[writeIndex];
+            System.arraycopy(args, 0, result, 0, writeIndex);
+            args = result;
+        }
+        return args;
+    } // processArgs(String[])
+
+// XXX compiler
+//    /**
+//     * Load any StructureNode tree at path, if possible
+//     * @param path the String path to a serialized StructureNode
+//     */
+//    protected StructureNode loadStructureNode(String path) {
+//        if (null == path) return null;
+//        StructureNode result = null;
+//        try {
+//            FileInputStream stream = new FileInputStream(path);
+//            ObjectInputStream ois  = new ObjectInputStream(stream);
+//            Object o = ois.readObject();
+//            Class oClass = (null == o ? null : o.getClass());
+//            if (StructureNode.class.isAssignableFrom(oClass)) {
+//                result = (StructureNode) o;
+//            } else {
+//                signal("loadStructureNode(\"" + path
+//                       + "\") - wrong type: " + oClass);
+//            }
+//        } catch (Throwable t) {
+//            signal("loadStructureNode(\"" + path + "\")", t);
+//        }
+//        return result;
+//     }
+//
+//    /**
+//     * Save any StructureNode tree to actualSavePath, if possible
+//     * @param actual the StructureNode root of the actual tree to save
+//     *        (ignored if null)
+//     */
+//    protected void saveActual(StructureNode actual) {
+//        if ((null != actual) && (null != actualSavePath)) {
+//            ObjectOutputStream p = null;
+//            FileOutputStream ostream = null;
+//            try {
+//                ostream = new FileOutputStream(actualSavePath);
+//                p = new ObjectOutputStream(ostream);
+//                p.writeObject(actual);
+//            } catch (Throwable e) {
+//                signal("saveActual(\"" + actual + "\") -> "
+//                       + actualSavePath, e);
+//            } finally {
+//                try {
+//                    if (null != p) p.flush();
+//                    if (null != ostream) ostream.close();
+//                } catch (IOException o) {} // ignored
+//            }
+//        }
+//    }
+
+    /**
+     * Compare two trees based on the settings for
+     * the visitor and sorter.  All results should be
+     * delivered by the visitor.
+     * @param expected the StructureNode actual tree to compare
+     * @param actual the StructureNode actual tree to compare
+     */
+    // XXX compiler
+//    protected void doComparison(StructureNode expected, StructureNode actual) {
+//        if (doComparison) {
+//            final GenericTreeNodeFactoryI fact =
+//                StructureGenericTreeNodeFactory.SINGLETON;
+//            GenericTreeNode lhs = null;
+//            if (expected != null) {
+//                lhs = fact.createGenericTreeNode(expected, null);
+//            }
+//            GenericTreeNode rhs = null;
+//            if (actual != null) {
+//                rhs = fact.createGenericTreeNode(actual, null);
+//            }
+//            GenericTreeNode.traverse(lhs, rhs, sorter, visitor);
+//        }
+//    }
+
+    /**
+     * A visitor which prints each to the sink (if any).
+     * If only one of the pair is not null,
+     * render it using GenericTreeNode.shortString()
+     */
+    static class PrintEach implements GenericTreeNodesVisitorI {
+        private PrintEach() {}
+        public boolean visit(GenericTreeNode lhs,GenericTreeNode rhs) {
+            PrintStream sink = PRINT_SINK;
+            if (null != sink) {
+                if ((lhs != null) && (rhs != null)) { // both
+                    sink.println("[lhs=" + lhs + "] [rhs=" + rhs + "]");
+                } else {
+                    GenericTreeNode gtn = (null == lhs ? rhs : lhs);
+                    if (null != gtn) {                // one
+                        sink.println(gtn.shortString());
+                    }
+                }
+            }
+            return true;
+        }
+    }  // class PrintEach
+
+    static class StringSortFactory implements GenericTreeNodeListOrdererFactoryI {
+        /**
+         * Produce the correct orderer for the children of the given GenericTreeNodes
+         * This always produces the same StringSorter.
+         * @return GenericTreeNodeListOrdererI for children, or null if none to be used
+         */
+        public GenericTreeNodeListOrdererI produce(GenericTreeNode lhs, GenericTreeNode rhs,
+                                                   GenericTreeNodesVisitorI visitor) {
+            return STRING_SORTER;
+        }
+    } // class StringSortFactory
+
+    /**
+     * sort input lists by Comparator <code>Structure.STRING_COMP</code>.
+     */
+    static class StringSort implements GenericTreeNodeListOrdererI {
+        /**
+         * Order input lists (not copies)
+         * using the Comparator <code>Structure.STRING_COMP</code>.
+         * @param lhs the List representing the left-hand-side
+         *            which contains only GenericTreeNode
+         * @param rhs the List representing the right-hand-side
+         *            which contains only GenericTreeNode
+         * @return two lists List[] (0 => lhs, 1 => rhs)
+         */
+        public List[] produceLists(List lhs, List rhs) {
+            if (null != lhs) Collections.sort(lhs, STRING_COMP);
+            if (null != rhs) Collections.sort(rhs, STRING_COMP);
+            List[] result = new List[2];
+            result[0] = lhs;
+            result[1] = rhs;
+            return result;
+        }
+    } // class CompSort
+
+    /**
+     * Comparator that imposes case-sensitive String order
+     * based on GenericTreeNode.shortString() if both are
+     * GenericTreeNode, or toString() otherwise.
+     * If both are null, considered equal.
+     * If one is null, the other is considered larger.
+     */
+    static class StringComparator implements Comparator {
+        public int compare(Object lhs, Object rhs) {
+            if (null == lhs) {
+                return (null == rhs ? 0 : -1);
+            } else if (null == rhs) {
+                return 1;
+            } else if ((lhs instanceof GenericTreeNode)
+                       && (rhs instanceof GenericTreeNode)) {
+                String lhsString = ((GenericTreeNode) lhs).shortString();
+                String rhsString = ((GenericTreeNode) rhs).shortString();
+                if (null == lhsString) {
+                    return (null == rhsString ? 0 : rhsString.compareTo(lhsString));
+                } else {
+                    return lhsString.compareTo(rhsString);
+                }
+            } else {
+                return lhs.toString().compareTo(rhs.toString());
+            }
+        }
+    } // class StringComparator
+} // class Structure
+
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/StructureGenericTreeNodeFactory.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/StructureGenericTreeNodeFactory.java
new file mode 100644 (file)
index 0000000..1f5883d
--- /dev/null
@@ -0,0 +1,308 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare.adapters;
+//
+//import org.aspectj.asm.SourceLocation;
+import org.aspectj.testing.compare.GenericTreeNode;
+//import org.aspectj.testing.compare.*;
+//import org.aspectj.asm.StructureNode;
+//import org.aspectj.asm.LinkNode;
+//import org.aspectj.asm.RelationNode;
+//import org.aspectj.asm.Relation;
+//import org.aspectj.asm.ProgramElementNode;
+//import java.util.*;
+//
+///**
+// * Factory for adapting StructureNode trees to GenericTreeNode
+// */
+// XXX compiler
+public class StructureGenericTreeNodeFactory implements GenericTreeNodeFactoryI {
+    public GenericTreeNode createGenericTreeNode(Object root,
+                                                 GenericTreeNode parent) {
+                                                    return null;
+    }
+    /**
+        * @see org.aspectj.testing.compare.adapters.GenericTreeNodeFactoryI#getRootClass()
+        */
+       public Class getRootClass() {
+               return null;
+       }
+
+}
+//    protected static final String[] MODIFIERS = new String[]
+//    { "strictfp", "abstract", "synchronized", "native",
+//      "final", "transient", "static", "volatile" };
+//    protected static final List MODIFIERS_LIST = Arrays.asList(MODIFIERS);
+//    protected static final String[] ACCESS = new String[]
+//    { "private", "protected", "package", "public", "privileged" };
+//    protected static final List ACCESS_LIST = Arrays.asList(ACCESS);
+//
+//    /** represent empty list of children (todo: use immutable instead) */
+//    public static final List EMPTY_LIST = new ArrayList();
+//    public static final GenericTreeNodeFactoryI SINGLETON
+//        = new StructureGenericTreeNodeFactory();
+//    /** delegate of the factory */
+//    private static final Comparator NODE_COMPARATOR;
+//
+//    static {
+//        SubTypeComparator init = new SubTypeComparator();
+//        init.addComparator(LinkNode.class, LinkNodeComparator.SINGLETON);
+//        init.addComparator(RelationNode.class, RelationNodeComparator.SINGLETON);
+//        init.addComparator(ProgramElementNode.class, ProgramElementNodeComparator.SINGLETON);
+//        init.addComparator(StructureNode.class, StructureNodeComparator.SINGLETON);
+//        GenericTreeNodeComparator gtnc = new GenericTreeNodeComparator(init);
+//        NODE_COMPARATOR = gtnc;
+//    }
+//
+//    private StructureGenericTreeNodeFactory() {}
+//    public Class getRootClass() {
+//        return StructureNode.class;
+//    }
+//
+//    /**
+//     * Adapt Structure model to tree rooted at GenericTreeNode.
+//     * Only takes the current state of a model which does not
+//     * change during the construction of the adapter. If the
+//     * model changes, you can ask the adapter for a newly
+//     * wrapped tree.
+//     * @param root the TreeNode taken as root of a tree to wrap
+//     * @param parent the parent of the resulting GenericTreeNode
+//     * @throws IllegalArgumentException if root is null
+//     *         or if children are not instanceof TreeNode.
+//     */
+//    public GenericTreeNode createGenericTreeNode(Object root,
+//                                                 GenericTreeNode parent) {
+//        if (null == root) {
+//            throw new IllegalArgumentException("null root");
+//        }
+//        if (! (root instanceof StructureNode)) {
+//            throw new IllegalArgumentException("not StructureNode: " + root);
+//        }
+//        GenericTreeNode result = new GenericTreeNode();
+//        StructureNode rootNode = (StructureNode) root;
+//        List kidList = rootNode.getChildren();
+//        List kids = EMPTY_LIST;
+//        // get kids of result
+//        if (null != kidList) {
+//            final int numKids = kidList.size();
+//            ArrayList newKids = new ArrayList(numKids);
+//            ListIterator kidIter = kidList.listIterator();
+//            Object child;
+//            for (int i = 0; i < numKids; i++) {
+//                if (! kidIter.hasNext()) { // items removed from list while iterating
+//                    throw new Error("(! hasNext())");
+//                }
+//                child = kidIter.next();
+//                if (! (child instanceof StructureNode)) {
+//                    throw new Error("! (child instanceof StructureNode)): " + child );
+//                }
+//                newKids.add(createGenericTreeNode((StructureNode) child, result));
+//            }
+//            kids = newKids;
+//        }
+//        // todo: select comparator here - avoids type checking at run time
+//        //result.init(parent, StructureComparator.SINGLETON, rootNode, kids, null);
+//        result.init(parent, NODE_COMPARATOR, rootNode, kids, null);
+//        return result;
+//    }
+//
+//    /** Comparator for GenericTreeNode delegates to handler for nodes... */
+//    static final class GenericTreeNodeComparator implements Comparator {
+//        private final Comparator delegate;
+//        private GenericTreeNodeComparator (Comparator delegate) {
+//            this.delegate = delegate;
+//        }
+//        public final int compare(Object lhs, Object rhs) {
+//            return delegate.compare(((GenericTreeNode)lhs).getNode()
+//                                    , ((GenericTreeNode)lhs).getNode());
+//        }
+//    }
+//
+//    /**
+//     * Comparator for RelationNode delegates to String & boolean comparison of public attributes.
+//     */
+//    static class RelationNodeComparator implements Comparator {
+//        public static Comparator SINGLETON = new RelationNodeComparator();
+//        private RelationNodeComparator () {}
+//        /**
+//         * Comparator for RelationNode uses String & boolean comparison of public attributes
+//         * forwardNavigationName, backNavigationName, associationName, symmetrical, associative.
+//         */
+//        public int compare(Object lhs, Object rhs) {
+//            int result = CompareUtil.compare(lhs, rhs);
+//            if (Integer.MAX_VALUE == result) {
+//                RelationNode lh = (RelationNode) lhs ;
+//                RelationNode rh = (RelationNode) rhs ;
+//                Relation leftRelation = lh.getRelation();
+//                Relation rightRelation = rh.getRelation();
+//                String left = null;
+//                String right = null;
+//                result = CompareUtil.compare(leftRelation, rightRelation);
+//                if (0 == result) {
+//                    left = leftRelation.getForwardNavigationName();
+//                    right = rightRelation.getForwardNavigationName();
+//                    result = CompareUtil.compare(left, right);
+//                }
+//                if (0 == result) {
+//                    left = leftRelation.getBackNavigationName();
+//                    right = rightRelation.getBackNavigationName();
+//                    result = CompareUtil.compare(left, right);
+//                }
+//                if (0 == result) {
+//                    left = leftRelation.getAssociationName();
+//                    right = rightRelation.getAssociationName();
+//                    result = CompareUtil.compare(left, right);
+//                }
+//                boolean l = false;
+//                boolean r = false;
+//                if (0 == result) {
+//                    l = leftRelation.isSymmetrical();
+//                    r = rightRelation.isSymmetrical();
+//                    result = CompareUtil.compare(l, r);
+//                }
+//                if (0 == result) {
+//                    l = leftRelation.isTransitive();
+//                    r = rightRelation.isTransitive();
+//                    result = CompareUtil.compare(l, r);
+//                }
+//            }
+//            return result;
+//        }
+//    }
+//
+//    /** Comparator for ProgramElementNode. */
+//    static class ProgramElementNodeComparator implements Comparator {
+//        public static Comparator SINGLETON = new ProgramElementNodeComparator();
+//        private ProgramElementNodeComparator () {}
+//        public int compare(Object lhs, Object rhs) {
+//            int result = CompareUtil.compare(lhs, rhs);
+//            if (Integer.MAX_VALUE == result) {
+//                ProgramElementNode lh = (ProgramElementNode) lhs ;
+//                ProgramElementNode rh = (ProgramElementNode) rhs ;
+//
+//                boolean rhStmntKind = rh.isCode();
+//                boolean lhStmntKind = lh.isCode();
+//                if (lhStmntKind != rhStmntKind) {
+//                    return (lhStmntKind ? 1 : -1);
+//                }
+//                String left= lh.getKind();
+//                String right= rh.getKind();
+//                // boilerplate
+//                result = CompareUtil.compare(left, right);
+//                if (Integer.MAX_VALUE == result) {
+//                    result = left.compareTo(right);
+//                    if (0 != result) return result;
+//                }
+//                right = rh.getSignature();
+//                left = lh.getSignature();
+//                result = CompareUtil.compare(left, right);
+//                if (Integer.MAX_VALUE == result) {
+//                    result = left.compareTo(right);
+//                    if (0 != result) return result;
+//                }
+//                List rightList = rh.getModifiers();
+//                List leftList = lh.getModifiers();
+//                result = CompareUtil.compare(leftList, rightList, MODIFIERS_LIST);
+//                if (0 != result) return result;
+//
+//                result = compare(rh.getAccessibility(), lh.getAccessibility());
+//                if (0 != result) return result;
+//
+//                right = rh.getDeclaringType();
+//                left = lh.getDeclaringType();
+//                result = CompareUtil.compare(left, right);
+//                if (Integer.MAX_VALUE == result) {
+//                    result = left.compareTo(right);
+//                    if (0 != result) return result;
+//                }
+//
+//                SourceLocation leftSourceLocation = rh.getSourceLocation();
+//                SourceLocation rightSourceLocation = rh.getSourceLocation();
+//                int iright= rightSourceLocation.getLineNumber();
+//                int ileft= leftSourceLocation.getLineNumber();
+//                if (iright != ileft) return (ileft-iright);
+//                iright= rightSourceLocation.getColumnNumber();
+//                ileft= leftSourceLocation.getColumnNumber();
+//                if (iright != ileft) return (ileft-iright);
+//
+//                right= rh.getFormalComment();
+//                left= lh.getFormalComment();
+//                if (Integer.MAX_VALUE == result) {
+//                    result = left.compareTo(right);
+//                    if (0 != result) return result;
+//                }
+//
+//                right = rh.toString();  // ignored? super
+//                left = lh.toString();  // ignored? super
+//                if (Integer.MAX_VALUE == result) {
+//                    result = left.compareTo(right);
+//                    if (0 != result) return result;
+//                }
+//                // ignore source file path - may change?
+//                // lhSourceFilePath = lh.getSourceFilePath(); // ignored
+//                // lh.sourceFilePath = lh.getSourceFilePath(); // ignored
+//                // List rhRelations= rh.getRelations() ; // ignored
+//                // List lhRelations= lh.getRelations();  // ignored
+//                return 0;
+//            }
+//            return result;
+//        }
+//    }
+//    
+//    /** Comparator for LinkNode. */
+//    static class LinkNodeComparator implements Comparator {
+//        public static Comparator SINGLETON = new LinkNodeComparator();
+//        private LinkNodeComparator () {}
+//        public int compare(Object lhs, Object rhs) {
+//            int result = CompareUtil.compare(lhs, rhs);
+//            if (Integer.MAX_VALUE == result) {
+//                LinkNode lh = (LinkNode) lhs ;
+//                LinkNode rh = (LinkNode) rhs ;
+//                // LinkNode only has child and lexical name in toString
+//                result = lh.toString().compareTo(rh.toString());
+//            }
+//            return result;
+//        }
+//    }   // class LinkNodeComparator
+//
+//    /**
+//     * Comparator for StructureNode.
+//     * <li>todo: implement comparators for each StructureNode subtype</li>
+//     */
+//    static class StructureNodeComparator implements Comparator {
+//        public static Comparator SINGLETON = new StructureNodeComparator();
+//        private StructureNodeComparator () {}
+//        public int compare(Object lhs, Object rhs) {
+//            int result = CompareUtil.compare(lhs, rhs);
+//            if (Integer.MAX_VALUE == result) {
+//                Class lhClass = lhs.getClass() ;
+//                Class rhClass = rhs.getClass() ;
+//                if ((StructureNode.class.isAssignableFrom(lhClass))
+//                    && (StructureNode.class.isAssignableFrom(rhClass))) {
+//                    StructureNode lh = (StructureNode) lhs ;
+//                    StructureNode rh = (StructureNode) rhs ;
+//                    Object lhObject = lh.getName(); // todo: weak name-based comparison
+//                    Object rhObject = rh.getName();
+//                    result = CompareUtil.compare(lhs, rhs);
+//                    if (Integer.MAX_VALUE == result) {
+//                        result = lhObject.toString().compareTo(rhObject.toString());
+//                    }
+//                } else { // urk - broken unless wrapper
+//                    result = lhs.toString().compareTo(rhs.toString());
+//                }
+//            }
+//            return result;
+//        }
+//    }
+//}
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/SubTypeComparator.java b/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/SubTypeComparator.java
new file mode 100644 (file)
index 0000000..3094fdb
--- /dev/null
@@ -0,0 +1,224 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.testing.compare.adapters;
+
+import org.aspectj.testing.compare.CompareUtil;
+import java.util.Comparator;
+
+// for testing code
+import java.util.*;
+import java.text.Collator;
+
+/** 
+ * This adopts pairs of [Class, Comparator]
+ * and implements compare by delegation thereto, 
+ * selecting the first added where the classes of the both inputs
+ * are assignable to the pair Class.
+ * It first applies the null-semantics of CompareUtil.compare(..),
+ * which holds that null values are less-than non-null values,
+ * and that two nulls are equal.
+ * Note that this class uses Object.equals(..)'s default reference
+ * equality, so two SubTypeComparator with the same list 
+ * of delegates will NOT be considered equal.
+ * <p>todo: This class is not thread-safe.
+ * <p>todo: immutable: final list copy on construction to implement equals??
+ */
+public class SubTypeComparator implements Comparator {
+       /** order-sensitive comparators collection */
+       private Vector comparators;
+       /** copy of comparators for compare method */
+       private Struct[] cache;
+
+       /** default constructor */
+       public SubTypeComparator () {
+               comparators = new Vector();
+       }
+
+       /**
+        * Return true if the Class is in the list of comparators
+        * as of the initial execution of the method.
+        * @param c the Class to look for a comparator
+        * @return true of comparator exists for c
+        */
+       private boolean contains(Class c) {
+               final int size = comparators.size();
+               for (int i = 0; i < size; i++) {
+                       if (c == ((Struct) comparators.elementAt(i)).accepts) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Get copy of comparators for compare operation.
+        */
+       private Struct[] getComparators() { // todo: sync on comparators
+               if ((null == cache) || (cache.length < comparators.size())) {
+                       cache = new Struct[comparators.size()];
+                       comparators.copyInto(cache);
+               }
+               return cache;
+       }
+
+       /**
+        * Add a Class, Comparator pair as delegate when
+        * both input are assignable to Class.
+        * Note that additions are checked in the order they are added,
+        * so add the lowest subtypes first.  (i.e., if you add
+        * a comparator for Class Object first, none of the others
+        * will ever match.)
+        * @param accepts the Class supertype of objects to accept
+        * @param comparator the Comparator to use on such objects
+        * @return false if not added, because either input is null
+        *         or because the Class is represented already.
+        */
+       public final boolean addComparator(Class accepts, Comparator comparator) {
+               if ((null == accepts) || (null == comparator)
+                       || (contains(accepts))) {
+                       return false;
+               }
+               comparators.addElement(new Struct(accepts, comparator));
+               return true;
+       }
+
+       /** 
+        * This implements compare by delegating
+        * to the first input Comparator 
+        * where the class of the both input
+        * is assignable to the pair Class.
+        * It first enforces the null-semantics of CompareUtil.compare(..).
+        * @throws ClassCastException if both input are not null and
+        *         they are not assignable to any registered Comparator.
+        */
+       public final int compare(Object lhs, Object rhs) {
+               int result = CompareUtil.compare(lhs, rhs);
+               if (Integer.MAX_VALUE == result) {
+                       Class lhClass = lhs.getClass() ;
+                       Class rhClass = rhs.getClass() ;
+                       Struct[] comp = getComparators();
+                       Class compClass;
+                       for (int i = 0; i < comp.length; i++) {
+                               compClass = comp[i].accepts;
+                               if ((compClass.isAssignableFrom(lhClass))
+                                       && (compClass.isAssignableFrom(lhClass))) {
+                                       return comp[i].comparator.compare(lhs, rhs);
+                               }
+                       }
+                       // not found - throw ClassCastException
+                       String mssg = "Unable to find Comparator for "
+                               + "lhs Class: " + lhClass.getName()
+                               + " rhs Class: " + rhClass.getName();
+                       throw new ClassCastException(mssg);
+               }
+               return result;
+       }
+
+       /** 
+        * (unnecessary) Struct to hold class-comparator pair 
+        * is preparation for using collections
+        */
+       static class Struct {
+               public final Class accepts;
+               public final Comparator comparator;
+               /**
+                * @param accepts the Class to accept input for - not null
+                * @param comparator the Comparator to compare input with - not null
+                */
+               public Struct(Class accepts,Comparator comparator) {
+                       this.accepts = accepts;
+                       this.comparator = comparator;
+               }
+               /** delegate to accept hashcode */
+               public int hashCode() { return accepts.hashCode() ; }
+               /** WARNING: fast comparison based only on accept key reference identity */
+               public boolean equals(Object o) {
+                       return ((null != o) && (o instanceof Struct)
+                                       && (accepts == ((Struct)o).accepts));
+               }
+       } // class Struct
+
+       //----------------------------------------------- test code 
+       /** test code */
+       static class Test { // todo move elsewhere
+               public void runTest(String[] args) {
+                       if ((null == args) || (1 > args.length)) {
+                               args = new String[] { "one", "two", "THREE", "FOUR", "fIVE", "6" };
+                       }
+                       SubTypeComparator me = new SubTypeComparator();
+                       String[] copy = new String[args.length];
+                       System.arraycopy(args, 0, copy, 0, copy.length);
+                       List list = Arrays.asList(args);
+                       Throwable result  = test(me, list);
+                       if ((null == result)
+                                && (!ClassCastException.class.isAssignableFrom(result.getClass()))) {
+                               System.err.println("FAIL: expected cce: " + result);
+                       }
+                       me.addComparator(String.class, Collator.getInstance());
+                       me.addComparator(Object.class, new Comparator () { 
+                                       public int compare (Object lhs, Object rhs) { 
+                                               throw new Error("never used");
+                                       }});
+                       result  = test(me, list);
+                       if (null != result) {
+                               if (ClassCastException.class.isAssignableFrom(result.getClass())) {
+                                       System.err.println("FAIL: unexpected cce: " + result);
+                               } else {
+                                       System.err.println("FAIL: unexpected Throwable: " + result);
+                               }
+                       }
+                       // heterogeneous - pick Object
+                       Object[] temp = new Object[] { "string", new Integer(1) };
+                       result  = test(me, Arrays.asList(temp));
+                       if ((null == result)
+                                && (!Error.class.isAssignableFrom(result.getClass()))) {
+                               System.err.println("FAIL: expected Error: " + result);
+                       }
+                       
+                       StringBuffer toPrint = print(Arrays.asList(copy), null);
+                       toPrint.append("\n");
+                       print(list, toPrint);
+                       System.err.println(toPrint.toString());
+               }
+
+               StringBuffer print(List list, StringBuffer sb) {
+                       if (null == sb) sb = new StringBuffer();
+                       sb.append("[");
+                       ListIterator iter = list.listIterator();
+                       while (iter.hasNext()) {
+                               sb.append(iter.next().toString());
+                               if (iter.hasNext()) sb.append(", ");
+                       }
+                       sb.append("]");
+                       return sb;
+               }
+
+               /**
+                * run comparison, return true if got expected exception
+                */
+               Throwable test(Comparator c, List l) {
+                       try {
+                               Collections.sort(l,c);
+                               return null;
+                       } catch (Throwable r) {
+                               return r;
+                       }
+               }
+       } // class Test
+
+       /** invoke Test.runTest(args) todo remove */
+       public static void main(String[] args) {
+               new Test().runTest(args);
+       }
+} // class SubTypeComparator
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/package.html b/aspectj-attic/testing-src/org/aspectj/testing/compare/adapters/package.html
new file mode 100644 (file)
index 0000000..c2d839e
--- /dev/null
@@ -0,0 +1,50 @@
+<html>
+<body>
+These adapters facilitate using the GenericTreeNode
+comparison utilities on different types of trees.
+The classes currently in this package support Swing
+<code>TreeNode</code> and AspectJ compiler <code>StructureNode</code>.
+
+<p>
+<code>Structure</code> supports a command-line interface for
+compiling <code>StructureNode</code> trees using 
+<code>AspectJCompiler</code> and saving 
+or loading them using serialization.  Once loaded, two trees
+can be compared using the <code>GenericTreeNode.traverse(..)</code> method,
+providing it the appropriate visitors and comparators to implement
+a comparison of the expected and actual structure trees and
+report on any differences.  (This is used to validate that
+changes to the structure tree are backwards compatible with
+trees from previous compiles, since the structure tree is
+effectively exported from the compiler to the IDE tools.)
+
+<p>
+If you want to support new trees,
+<code>GenericTreeNodeFactoryI</code> is the interface to implement.
+It specifies a factory to provide a <code>Comparator</code> based
+on a given pair to be compared. This means that you can
+use (or generate) comparators based on specific pairs.
+Usually you will implement only for the target type,
+so your factory may be final and always return a 
+singleton <code>Comparator.</code>
+<p>
+The <code>SubTypeComparator</code> implements a <code>Comparator</code>
+container that acts as a <code>Comparator</code> by delegating to
+contained <code>Comparator</code>s registered along with the class of the input
+they accept.  This permits you to write type-specific
+<code>Comparator</code>s for heterogeneous trees.  It does require
+both members of the comparison be assignable to the
+target class.
+
+<p> 
+<code>StructureGenericTreeNodeFactory</code> is an implementation of
+<code>GenericTreeNodeFactoryI</code> for StructureNode trees.  It
+contains comparator classes for <code>RelationNode</code>, <code>LinkNode,</code>
+and <code>ProgramElementNode</code>, 
+combined using a <code>SubTypeComparator.</code>
+<p> 
+<code>JTreeNodeGenericTreeNodeFactory</code> is an implementation of
+<code>GenericTreeNodeFactoryI</code>  for Swing <code>TreeNode</code>'s, done only
+for testing purposes.
+</body>
+</html>
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/compare/package.html b/aspectj-attic/testing-src/org/aspectj/testing/compare/package.html
new file mode 100644 (file)
index 0000000..6bfec16
--- /dev/null
@@ -0,0 +1,128 @@
+<html>
+<body>
+This package implements a general tree comparison as a
+special case of visiting generic trees pairwise.
+Trees are wrapped as <code>GenericTreeNode</code>, which has a static
+method <code>boolean traverse(..)</code> which accepts
+a visitor and traverses a pair of trees, calling the
+visitor on each.
+<p>This package supports four forms of generality 
+through the following classes:
+<table border="+1">
+<tr><th>Classes</th>
+    <th>Capability</th></tr>
+<tr><td valign="top">GenericTreeNode</td>
+   <td>Able to handle trees of varying types
+       by wrapping in a generic form.<td>
+   </tr>
+<tr><td valign="top">GenericTreeNodesVisitorI, GenericTreeNode.traverse(..)</td>
+    <td>Can handle any type of pairwise visitor function
+        by accepting visitor in the traverse method.</td>
+   </tr>
+<tr><td valign="top">{java.util.Comparator}, GenericTreeNode.getComparator()</td>
+    <td>The object comparison can be sensitive to the type
+    of the object on a per-object basis, established during
+    the process of wrapping the tree.</td>
+   </tr>
+<tr><td valign="top">GenericTreeListOrdererI, GenericTreeListOrdererFactoryI</td>
+    <td>The ordering of children can be appropriate to
+    the objective of the traversal. e.g., when computing
+    "set intersection" rather than "list equals", the
+    order of children might be changed to align matching
+    children for the visits.
+    <br>This ordering can be determined as appropriate for each
+    list comparison by implementing a factory which selects
+    from the appropriate orderers.  Any factory product is used
+    by the traverse(..) method to order children before
+    visiting.</td>
+   <td></td>
+   </tr>
+</table>
+
+<p><u>Supported variants</u>:
+The following variants are implemented or planned using the components above:
+<table border="1">
+<tr><th>Component</th><th>Description</th></tr>
+<tr><td colspan=2>Current</th></tr>
+<tr><td>GenericTreeNode.PRINTALL</td>
+    <td>A visitor which prints out the entire tree.</td></tr>
+<tr><td>GenericTreeNode.PRINTERR</td>
+    <td>A visitor which prints the nonmatching pairs.</td></tr>
+<tr><td>GenericTreeNode.EXACT</td>
+    <td>A visitor which returns false if any pairs do not match.</td></tr>
+<tr><td>TreeCompare</td>
+    <td>A sample program to read in serialized trees and compare them.
+        (but see Structure in the compare subpackage for a better example) </td></tr>
+<tr><td>CompareUtil</td>
+    <td>Misc comparison utilities (e.g., for short-circuiting comparisons).</td></tr>
+<tr><td colspan=2>Planned</th></tr>
+<tr><td>GenericTreeNode.KIDDIFF</td>
+    <td>A visitor which calculates tree differences, using ordering children
+           (catches swaps, missed or added elements, within children)</td></tr>
+<tr><td>GenericTreeNode.TREEDIFF</td>
+    <td>A visitor which calculates tree differences, accumulating the tree
+           (catches swaps, missed or added elements, throughout tree.)</td></tr>
+</table>
+
+<p><u>Use</u>:
+  Run TreeCompare to use the comparer from the command line on a supported tree,
+   (currently only the Swing TreeNode implemented as DefaultMutableTreeNode).
+
+<p><u>Programming</u>:<br>
+To support a new tree, see the Structure example in the compare subpackage
+or use example of the Swing TreeNode:
+<li>Write an adapter that uses GenericTreeNode to wrap your tree nodes</li>
+<li>Write a factory that produces a wrapped tree</li>
+<li>Write a Comparator that compares the underlying node object 
+    to include with each node object wrapped. Be sure to implement
+    the Comparator.equals(Object) method correctly, i.e., returning
+    true when it is equivalent to another comparator.  It is best 
+    to use a singleton for each type of node you support. </li>
+<li>Optionally write a visitor to perform whatever operations you wish.
+    Note that visitors must tolerate a single null input in order to
+    completely traverse unmatching trees.</li>
+<li>To perform operations requiring preprocessing of child List's,
+    write children orderer(s) and provide a factory to select them.</li>
+
+<p>To design new algorithms/applications, bear in mind the main tools:
+<li>The comparator that follows the node object</li>
+<li>The visitor that traverses the tree </li>
+<li>The child orderer that may preprocess the child lists </li>
+<br>In particular, when going beyond pair-wise comparisons to
+    list-wise or tree-wise comparisons, you'll have to decide
+    where to put the appropriate logic.  You may have a relatively
+    lightweight visitor and a heavyweight orderer, or no
+    orderer at all. In that case, you may need to invoke a 
+    special method on your visitor after the traversal completes
+    to do any final processing.
+
+<h2>Future Work</h2>:
+<p><u>Smarter group comparisons</u>:
+<br>Does calculating maps help with diagnosing problems?
+<pre>
+Given two lists,
+  A [ a, b, c, d, e, f, g, h ]
+  B [ a, e, c, d, b, g, h ]
+The result should say:
+  - B swapped order of e and b
+  - B omitted f
+Note the match-map (index of matching element, if any):
+  A->B [ 0, 4, 2, 3, 1, -, 5, 6 ]
+  B->A [ 0, 4, 2, 3, 1, 6, 7 ]
+the shift-map (difference between expected and actual order):
+  A->B [ 0, 3, 0, 0, -3, -, -1, -1 ]
+  B->A [ 0, 3, 0, 0, -3, 1, 1 ]
+
+Thus:
+- detect swaps as complementary out-of-index order pairs
+  (todo: three-way or n-ary?)
+  - fix or ignore swaps
+- detect shifts as complementary series
+  where shift-width n is +/- for both
+  - -n => 
+    - if negative element is actual, n elements omitted
+    - if negative element is expected, n elements added
+<pre>
+
+</body>
+</html>
diff --git a/aspectj-attic/testing-src/org/aspectj/testing/taskdefs/CompareFiles.java b/aspectj-attic/testing-src/org/aspectj/testing/taskdefs/CompareFiles.java
new file mode 100644 (file)
index 0000000..fe1b760
--- /dev/null
@@ -0,0 +1,103 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation, 
+ *               2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+package org.aspectj.testing.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import org.apache.tools.ant.*;
+
+/**
+ * Wrap file comparison utility as ant taskdef.
+ * (Whitespace semantics track the String.trim() and StringTokenizer class.)
+ * <table>
+ * <tr><td>lhsFile</td><td>path to left-hand-side file to compare (required)</td></tr>
+ * <tr><td>rhsFile</td><td>path to right-hand-side file to compare (required)</td></tr>
+ * <tr><td>output</td><td>path to output file (System.out otherwise)</td></tr>
+ * <tr><td>ignoreCase</td><td>convert to uppercase before comparison (boolean yes/no)</td></tr>
+ * <tr><td>trimWhitespace</td><td>ignore leading/trailing white space(boolean yes/no)</td></tr>
+ * <tr><td>collapseWhitespace</td><td>convert all white space runs to a single space (boolean yes/no)</td></tr>
+ * <tr><td>filterSpec</td><td>all specifications for a filter, based on the RegexpFilter class
+ *               (currently, syntax: <code>{file | {-i|-t|-b|-s <pattern>|-s <patternFile>}..}</code></td></tr>
+ * </table>
+ * @see org.aspectj.testing.compare.RegexpFilter#init(String[],RegexpFilter)
+ */
+public class CompareFiles extends org.apache.tools.ant.Task {
+    /*
+      Unable to implement multiple inheritance except by delegation:
+      - Task subclass must be outer or ant throws InstantiationException
+      - if/since outer, the subclass getter/setters cannot refer to 
+        protected fields in worker superclass absent inner worker 
+        subclass delegate methods.  yuck.
+      - getting access errors when trying to use the RuntimeConfigurable
+        to initialize the task.  Looking at the Ant code, it does not
+        appear to be used for tasks??  I found none using it and the
+        initialization seems wrong...
+    */
+    final private Worker worker;
+    public CompareFiles() { 
+        worker = new Worker();
+    }
+    protected File lhsFile;
+    protected File rhsFile;
+    public void setLhsFile(File file)             { lhsFile = file; }
+    public void setRhsFile(File file)             { rhsFile = file; }
+    public void setOutput(File file)              { worker.setOutput(file); }
+    public void setFilterSpec(String str)         { worker.setFilterSpec(str); }
+    public void setCollapseWhitespace(boolean ok) { worker.setCollapseWhitespace(ok); }
+    public void setTrimWhitespace(boolean ok)     { worker.setTrimWhitespace(ok); }
+    public void setIgnoreCase(boolean ok)         { worker.setIgnoreCase(ok); }
+    public void execute() throws BuildException   { 
+        if (!lhsFile.canRead()) {
+            log("FAIL taskdefs.CompareFiles: bad lhsFile: " + lhsFile);
+        } else if (!rhsFile.canRead()) {
+            log("FAIL taskdefs.CompareFiles: bad rhsFile: " + rhsFile);
+        } else if (rhsFile.isDirectory() != lhsFile.isDirectory()) {
+            log("FAIL taskdefs.CompareFiles: both must be dirs."
+                + " lhsFile=" + lhsFile
+                + " rhsFile=" + rhsFile);
+        } else {
+            worker.dodiff(lhsFile, rhsFile); 
+        }
+    }
+} // class CompareFiles
+
+/** worker class exposes state and converts Exception to BuildException */
+class Worker extends org.aspectj.testing.compare.CompareFiles {
+    String spec = null;
+    public void setOutput(File file)              { output = file; }
+    public void setCollapseWhitespace(boolean ok) { collapseWhitespace = ok; }
+    public void setTrimWhitespace(boolean ok)     { trimWhitespace = ok; }
+    public void setIgnoreCase(boolean ok)         { ignoreCase = ok; }
+    public void setFilterSpec(String str)         { spec = str; }
+    public void initFilter() {
+        if (null != spec) {
+            initFilter(spec, false);
+        }
+    }
+
+    public void dodiff(File lhsFile, File rhsFile) throws BuildException {
+        initFilter();
+        try {
+            super.diff(lhsFile, rhsFile);
+        } catch (IOException t) {
+            String s = t.getClass().getName() + ": " + t.getMessage();
+            throw new BuildException(s, t);
+        } catch (Throwable e) {
+            String s = e.getClass().getName() + ": " + e.getMessage();
+            throw new BuildException("Error - " + s, e);
+        } 
+    }    
+} // class CompareFiles$Worker
+