Browse Source

Lightweight ajdoc prototype.

tags/v_preCompileLoopAlteration
mkersten 20 years ago
parent
commit
83198dbf96

+ 11
- 0
ajdoc/.classpath View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="src" path="/asm"/>
<classpathentry kind="src" path="/org.aspectj.ajdt.core"/>
<classpathentry kind="src" path="/bridge"/>
<classpathentry kind="src" path="/util"/>
<classpathentry kind="lib" path="C:/Apps/j2sdk1.4.2/lib/tools.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

+ 21
- 0
ajdoc/.project View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ajdoc</name>
<comment></comment>
<projects>
<project>asm</project>
<project>bridge</project>
<project>org.aspectj.ajdt.core</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>

+ 43
- 0
ajdoc/src/org/aspectj/tools/ajdoc/Config.java View File

@@ -0,0 +1,43 @@
/* *******************************************************************
* 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
* Mik Kersten port to AspectJ 1.1+ code base
* ******************************************************************/

package org.aspectj.tools.ajdoc;

interface Config {
static final String DECL_ID_STRING = "__AJDECLID:";
static final String DECL_ID_TERMINATOR = ":__";
static final String WORKING_DIR = "ajdocworkingdir";
static final String DIR_SEP_CHAR = "/";
static final String VERSION = "ajdoc version 0.8beta4";
static final String USAGE =
"Usage: ajdoc <options> <source files>\n" +
"\n" +
"where <options> includes:\n"+
" -public Show only public classes and members\n"+
" -protected Show protected/public classes and members\n"+
" -package Show package/protected/public classes and members\n" + // default
" -private Show all classes and members\n" +
" -help Display command line options\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" +
" -d <directory> Destination directory for output files\n" +
" -argfile <file> the file is a line-delimted list of arguments" +
" -verbose Output messages about what Javadoc is doing\n" +
" -v Print out the version of ajdoc" +
"\n"+
"If an argument is of the form @<filename>, the file will be interpreted as\n"+
"a line delimited set of arguments to insert into the argument list.";

}

+ 293
- 0
ajdoc/src/org/aspectj/tools/ajdoc/Declaration.java View File

@@ -0,0 +1,293 @@
/* *******************************************************************
* 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
* Mik Kersten port to AspectJ 1.1+ code base
* ******************************************************************/

package org.aspectj.tools.ajdoc;
import java.util.Enumeration;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;


import java.util.*;

// Make sure that references to Vector use the standard version
// This lets us generate serialized files which interoperate with other code better
import java.util.Vector;

public class Declaration implements Serializable {
private int beginLine;
private int endLine;
private int beginColumn;
private int endColumn;

private String modifiers;
private String fullSignature;
private String signature;
private String crosscutDesignator;

private String packageName;

private String kind;
private String declaringType;

private String filename;
private String formalComment;

private Declaration[] declarations;

private Handle crosscutDeclarationHandle;
private Handle[] pointedToByHandles;
private Handle[] pointsToHandles;

transient private Declaration crosscutDeclaration;
transient private Declaration[] pointedToBy = null;
transient private Declaration[] pointsTo = null;

private Declaration parentDeclaration = null;

public Declaration(int beginLine, int endLine, int beginColumn, int endColumn,
String modifiers, String signature, String fullSignature,
String crosscutDesignator,
String declaringType, String kind,
String filename, String formalComment,
String packageName)
{
this.beginLine = beginLine;
this.endLine = endLine;
this.beginColumn = beginColumn;
this.endColumn = endColumn;

this.modifiers = modifiers;
this.signature = signature;
this.fullSignature = fullSignature;

this.crosscutDesignator = crosscutDesignator;

this.declaringType = declaringType;
this.kind = kind;

this.filename = filename;
this.formalComment = formalComment;

this.packageName = packageName;

this.pointedToByHandles = new Handle[0];
this.pointsToHandles = new Handle[0];
//???
this.declarations = new Declaration[0];
}

public int getBeginLine() { return beginLine; }
public int getEndLine() { return endLine; }
public int getBeginColumn() { return beginColumn; }
public int getEndColumn() { return endColumn; }

public String getModifiers() { return modifiers; }
public String getFullSignature() { return fullSignature; }
public String getSignature() { return signature; }

public String getPackageName() { return packageName; }

public String getCrosscutDesignator() { return crosscutDesignator; }

public Declaration getParentDeclaration() { return parentDeclaration; }

public Declaration getCrosscutDeclaration() {
if (crosscutDeclaration == null && crosscutDeclarationHandle != null) {
crosscutDeclaration = crosscutDeclarationHandle.resolve();
}
return crosscutDeclaration;
}

public void setCrosscutDeclaration(Declaration _crosscutDeclaration) {
crosscutDeclaration = _crosscutDeclaration;
}

public String getDeclaringType() { return declaringType; }
public String getKind() {
if (kind.startsWith("introduced-")) {
return kind.substring(11);
} else {
return kind;
}
}

public String getFilename() { return filename; }
public String getFormalComment() { return formalComment; }

public Declaration[] getDeclarations() {
return declarations;
}
public void setDeclarations(Declaration[] decs) {
declarations = decs;
if (decs != null) {
for (int i = 0; i < decs.length; i++) {
decs[i].parentDeclaration = this;
}
}
}
public void setPointedToBy(Declaration[] decs) { pointedToBy = decs; }
public void setPointsTo(Declaration[] decs) { pointsTo = decs; }


public Declaration[] getPointedToBy() {
if (pointedToBy == null) {
pointedToBy = resolveHandles(pointedToByHandles);
}
return pointedToBy; //.elements();
}

public Declaration[] getPointsTo() {
if (pointsTo == null) {
pointsTo = resolveHandles(pointsToHandles);
}
return pointsTo; //.elements();
}

private Declaration[] filterTypes(Declaration[] a_decs) {
List decs = new LinkedList(Arrays.asList(a_decs));
for(Iterator i = decs.iterator(); i.hasNext(); ) {
Declaration dec = (Declaration)i.next();
if (!dec.isType()) i.remove();
}
return (Declaration[])decs.toArray(new Declaration[decs.size()]);
}


public Declaration[] getTargets() {
Declaration[] pointsTo = getPointsTo();

if (kind.equals("advice")) {
return pointsTo;
} else if (kind.equals("introduction")) {
return filterTypes(pointsTo);
} else {
return new Declaration[0];
}
}

// Handles are used to deal with dependencies between Declarations in different files
private Handle getHandle() {
return new Handle(filename, beginLine, beginColumn);
}

private Declaration[] resolveHandles(Handle[] handles) {
Declaration[] declarations = new Declaration[handles.length];
int missed = 0;
for(int i=0; i<handles.length; i++) {
//if (handles[i] == null) continue;
declarations[i] = handles[i].resolve();
if (declarations[i] == null) missed++;
}
if (missed > 0) {
Declaration[] decs = new Declaration[declarations.length - missed];
for (int i=0, j=0; i < declarations.length; i++) {
if (declarations[i] != null) decs[j++] = declarations[i];
}
declarations = decs;
}
return declarations;
}

private Handle[] getHandles(Declaration[] declarations) {
Handle[] handles = new Handle[declarations.length];
for(int i=0; i<declarations.length; i++) {
//if (declarations[i] == null) continue;
handles[i] = declarations[i].getHandle();
}
return handles;
}

// Make sure that all decs are convertted to handles before serialization
private void writeObject(ObjectOutputStream out) throws IOException {
pointedToByHandles = getHandles(getPointedToBy());
pointsToHandles = getHandles(getPointsTo());
if (crosscutDeclaration != null) {
crosscutDeclarationHandle = crosscutDeclaration.getHandle();
}
out.defaultWriteObject();
}

// support functions
public Declaration[] getCrosscutDeclarations() {
return getDeclarationsHelper("pointcut");
}

public Declaration[] getAdviceDeclarations() {
return getDeclarationsHelper("advice");
}

public Declaration[] getIntroductionDeclarations() {
return getDeclarationsHelper("introduction");
}

private Declaration[] getDeclarationsHelper(String kind) {
Declaration[] decls = getDeclarations();
List result = new ArrayList();
for ( int i = 0; i < decls.length; i++ ) {
Declaration decl = decls[i];
if ( decl.getKind().equals(kind) ) {
result.add(decl);
}
}
return (Declaration[])result.toArray(new Declaration[result.size()]);
}


public boolean isType() {
return getKind().equals("interface") || getKind().equals("class");
}

public boolean hasBody() {
String kind = getKind();
return kind.equals("class") || kind.endsWith("constructor") ||
(kind.endsWith("method") && getModifiers().indexOf("abstract") == -1 &&
getModifiers().indexOf("native") == -1);
}

public boolean isIntroduced() {
return kind.startsWith("introduced-");
}

public boolean hasSignature() {
String kind = getKind();
if ( kind.equals( "class" ) ||
kind.equals( "interface" ) ||
kind.equals( "initializer" ) ||
kind.equals( "field" ) ||
kind.equals( "constructor" ) ||
kind.equals( "method" ) ) {
return true;
}
else {
return false;
}
}

private static class Handle implements Serializable {
public String filename;
public int line, column;

public Handle(String filename, int line, int column) {
this.filename = filename;
this.line = line;
this.column = column;
}

public Declaration resolve() {
SymbolManager manager = SymbolManager.getDefault();
return manager.getDeclarationAtPoint(filename, line, column);
}
}
}

+ 700
- 0
ajdoc/src/org/aspectj/tools/ajdoc/Main.java View File

@@ -0,0 +1,700 @@
/* *******************************************************************
* 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
* Mik Kersten port to AspectJ 1.1+ code base
* ******************************************************************/

package org.aspectj.tools.ajdoc;

import java.io.File;
import java.io.FileOutputStream;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.StringReader;
import java.io.FilenameFilter;

import java.util.*;

/**
* This is an old implementation of ajdoc that does not use an OO style. However, it
* does the job, and should serve to evolve a lightweight ajdoc implementation until
* we can make a properly extended javadoc implementation.
*
* @author Mik Kersten
*/
public class Main implements Config {

static SymbolManager symbolManager = null;

/** Command line options. */
static Vector options = new Vector();

/** Options to pass to ajc. */
static Vector ajcOptions = new Vector();

/** All of the files to be processed by ajdoc. */
static Vector filenames = new Vector();

/** List of files to pass to javadoc. */
static Vector fileList= new Vector();

/** List of packages to pass to javadoc. */
static Vector packageList = new Vector();

/** Default to package visiblity. */
static String docModifier = "package";

static Vector sourcepath = new Vector();

static boolean verboseMode = false;
static boolean packageMode = false;
static boolean authorStandardDocletSwitch = false;
static boolean versionStandardDocletSwitch = false;
static File rootDir = null;
static Hashtable declIDTable = new Hashtable();
static String docDir = ".";

public static void clearState() {
symbolManager = null;
options = new Vector();
ajcOptions = new Vector();
filenames = new Vector();
fileList= new Vector();
packageList = new Vector();
docModifier = "package";
sourcepath = new Vector();
verboseMode = false;
packageMode = false;
rootDir = null;
declIDTable = new Hashtable();
docDir = ".";
}

public static void main(String[] args) {

// STEP 1: parse the command line and do other global setup
sourcepath.addElement("."); // add the current directory to the classapth
parseCommandLine(args);
rootDir = getRootDir();
symbolManager = SymbolManager.getDefault();
File[] inputFiles = new File[filenames.size()];
File[] signatureFiles = new File[filenames.size()];
try {
// create the workingdir if it doesn't exist
if ( !(new File( Config.WORKING_DIR ).isDirectory()) ) {
File dir = new File( Config.WORKING_DIR );
dir.mkdir();
dir.deleteOnExit();
}

for (int i = 0; i < filenames.size(); i++) {
inputFiles[i] = findFile((String)filenames.elementAt(i));
//signatureFiles[i] = createSignatureFile(inputFiles[i]);
}

// PHASE 0: call ajc
ajcOptions.addElement( "-noExit" );
ajcOptions.addElement( "-emacssym" ); // TODO: wrong option to force model gen
String[] argsToCompiler = new String[ajcOptions.size() + inputFiles.length];
int i = 0;
for ( ; i < ajcOptions.size(); i++ ) {
argsToCompiler[i] = (String)ajcOptions.elementAt(i);
//System.out.println(">>> ajc: " + argsToCompiler[i]);
}
for ( int j = 0; j < inputFiles.length; j++) {
argsToCompiler[i] = inputFiles[j].getAbsolutePath();
//System.out.println(">> file to ajc: " + inputFiles[j].getAbsolutePath());
i++;
}

System.out.println( "> calling ajc..." );

try {
(new org.aspectj.tools.ajc.Main() {
public void exit(int status) {
if (status != 0) {
System.out.println( "> compile failed, exiting ajdoc" );
System.exit( -1 );
}
}
}).main(argsToCompiler);
}
catch ( SecurityException se ) {
System.exit( -1 );
}
/*
for (int ii = 0; ii < inputFiles.length; ii++) {
String tempFP = inputFiles[ii].getAbsolutePath();
tempFP = tempFP.substring(0, tempFP.length()-4);
tempFP += "ajsym";
System.out.println( ">> checking: " + tempFP);
File tempF = new File(tempFP);
if ( !tempF.exists() ) System.out.println( ">>> doesn't exist!" );
}
*/
for (int ii = 0; ii < filenames.size(); ii++) {
signatureFiles[ii] = createSignatureFile(inputFiles[ii]);
}

// PHASE 1: generate Signature files (Java with DeclIDs and no bodies).
System.out.println( "> building signature files..." );
Phase1.doFiles(declIDTable, symbolManager, inputFiles, signatureFiles);

// PHASE 2: let Javadoc generate HTML (with DeclIDs)
System.out.println( "> calling javadoc..." );
String[] javadocargs = null;
if ( packageMode ) {
int numExtraArgs = 2;
if (authorStandardDocletSwitch) numExtraArgs++;
if (versionStandardDocletSwitch) numExtraArgs++;
javadocargs = new String[numExtraArgs + options.size() + packageList.size() +
fileList.size() ];
javadocargs[0] = "-sourcepath";
javadocargs[1] = Config.WORKING_DIR;
int argIndex = 2;
if (authorStandardDocletSwitch) {
javadocargs[argIndex] = "-author";
argIndex++;
}
if (versionStandardDocletSwitch) {
javadocargs[argIndex] = "-version";
}
//javadocargs[1] = getSourcepathAsString();
for (int k = 0; k < options.size(); k++) {
javadocargs[numExtraArgs+k] = (String)options.elementAt(k);
}
for (int k = 0; k < packageList.size(); k++) {
javadocargs[numExtraArgs+options.size() + k] = (String)packageList.elementAt(k);
}
for (int k = 0; k < fileList.size(); k++) {
javadocargs[numExtraArgs+options.size() + packageList.size() + k] = (String)fileList.elementAt(k);
}
}
else {
javadocargs = new String[options.size() + signatureFiles.length];
for (int k = 0; k < options.size(); k++) {
javadocargs[k] = (String)options.elementAt(k);
}
for (int k = 0; k < signatureFiles.length; k++) {
javadocargs[options.size() + k] = signatureFiles[k].getCanonicalPath();
}
}
Phase2.callJavadoc(javadocargs);

//for ( int o = 0; o < inputFiles.length; o++ ) {
// System.out.println( "file: " + inputFiles[o] );
//}

// PHASE 3: add AspectDoc specific stuff to the HTML (and remove the DeclIDS).
/** We start with the known HTML files (the ones that correspond directly to the
* input files.) As we go along, we may learn that Javadoc split one .java file
* into multiple .html files to handle inner classes or local classes. The html
* file decorator picks that up.
*/
System.out.println( "> Decorating html files..." );
Phase3.decorateHTMLFromInputFiles(declIDTable,
rootDir,
symbolManager,
inputFiles,
docModifier);
removeDeclIDsFromFile("index-all.html");
removeDeclIDsFromFile("serialized-form.html");
for (int p = 0; p < packageList.size(); p++) {
removeDeclIDsFromFile(((String)packageList.elementAt(p)).replace('.','/') +
Config.DIR_SEP_CHAR +
"package-summary.html" );
}
} catch (Throwable e) {
handleInternalError(e);
exit(-2);
}
}

static void removeDeclIDsFromFile(String filename) {
// Remove the decl ids from "index-all.html"
File indexFile = new File( docDir + Config.DIR_SEP_CHAR + filename );
try {
if ( indexFile.exists() ) {
BufferedReader indexFileReader = new BufferedReader( new FileReader( indexFile ) );
String indexFileBuffer = "";
String line = indexFileReader.readLine();
while ( line != null ) {
int indexStart = line.indexOf( Config.DECL_ID_STRING );
int indexEnd = line.indexOf( Config.DECL_ID_TERMINATOR );
if ( indexStart != -1 && indexEnd != -1 ) {
line = line.substring( 0, indexStart ) +
line.substring( indexEnd+Config.DECL_ID_TERMINATOR.length() );
}
indexFileBuffer += line;
line = indexFileReader.readLine();
}
FileOutputStream fos = new FileOutputStream( indexFile );
fos.write( indexFileBuffer.getBytes() );
}
}
catch (IOException ioe) {
// be siltent
}
}

static void callAJC( String[] ajcargs ) {
final SecurityManager defaultSecurityManager = System.getSecurityManager();

System.setSecurityManager( new SecurityManager() {
public void checkExit(int status) {
System.setSecurityManager( defaultSecurityManager );
//throw new SecurityException( "status code: " + status );
//System.exit( -1 );
}
public void checkPermission( java.security.Permission permission ) {
if ( defaultSecurityManager != null )
defaultSecurityManager.checkPermission( permission );
}
public void checkPermission( java.security.Permission permission,
Object context ) {
if ( defaultSecurityManager != null )
defaultSecurityManager.checkPermission( permission, context );
}
} );

try {
org.aspectj.tools.ajc.Main.main( ajcargs );
}
catch ( SecurityException se ) {
// Do nothing since we expect it to be thrown
//System.out.println( ">> se: " + se.getMessage() );
} catch ( IOException ioe ) {
System.out.println( ">> io error: " + ioe.getMessage() );
}
// Set the security manager back
System.setSecurityManager( defaultSecurityManager );
}


/**
* If the file doesn't exist on the specified path look for it in all the other
* paths specified by the "sourcepath" option.
*/
static File findFile( String filename ) throws IOException {

return new File( filename );
/*
File file = new File(filename);
if (file.exists()) {
return file;
}
else {
for ( int i = 0; i < sourcePath.size(); i++ ) {
File currPath = new File((String)sourcePath.elementAt(i));
File currFile = new File(currPath + "/" + filename); // !!!
if ( file.exists()) {
return file;
}
}
}
throw new IOException("couldn't find source file: " + filename);
*/
}

static Vector getSourcePath() {
Vector sourcePath = new Vector();
boolean found = false;
for ( int i = 0; i < options.size(); i++ ) {
String currOption = (String)options.elementAt(i);
if (found && !currOption.startsWith("-")) {
sourcePath.add(currOption);
}
if (currOption.equals("-sourcepath")) {
found = true;
}
}
return sourcePath;
}

static File getRootDir() {
File rootDir = new File( "." );
for ( int i = 0; i < options.size(); i++ ) {
if ( ((String)options.elementAt(i)).equals( "-d" ) ) {
rootDir = new File((String)options.elementAt(i+1));
if ( !rootDir.exists() ) {
System.out.println( "Destination directory not found: " +
(String)options.elementAt(i+1) );
System.exit( -1 );
}
}
}
return rootDir;
}

static File createSignatureFile(File inputFile) throws IOException {
Declaration[] decls = symbolManager.getDeclarations(inputFile.getAbsolutePath());
Declaration decl = null;
String packageName = null;
if ( decls != null && decls[0] != null ) {
decl = decls[0];
packageName = decl.getPackageName();
}
String filename = "";
if ( packageName != null ) {
//System.err.println(">> creating: " + packageName);
String pathName = Config.WORKING_DIR + '/' + packageName.replace('.', '/');
//System.err.println(">> pathName: " + pathName);
File packageDir = new File(pathName);
if ( !packageDir.exists() ) {
packageDir.mkdirs();
//packageDir.deleteOnExit();
}
//verifyPackageDirExists(packageName, null);
packageName = packageName.replace( '.','/' ); // !!!
filename = Config.WORKING_DIR + Config.DIR_SEP_CHAR + packageName +
Config.DIR_SEP_CHAR + inputFile.getName();
}
else {
filename = Config.WORKING_DIR + Config.DIR_SEP_CHAR + inputFile.getName();
}
File signatureFile = new File( filename );
//signatureFile.deleteOnExit();
return signatureFile;
}


static void verifyPackageDirExists( String packageName, String offset ) {
System.err.println(">>> name: " + packageName + ", offset: " + offset);
if ( packageName.indexOf( "." ) != -1 ) {
File tempFile = new File("c:/aspectj-test/d1/d2/d3");
tempFile.mkdirs();
String currPkgDir = packageName.substring( 0, packageName.indexOf( "." ) );
String remainingPkg = packageName.substring( packageName.indexOf( "." )+1 );
String filePath = null;
if ( offset != null ) {
filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR +
offset + Config.DIR_SEP_CHAR + currPkgDir ;
}
else {
filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR + currPkgDir;
}
File packageDir = new File( filePath );
if ( !packageDir.exists() ) {
packageDir.mkdir();
packageDir.deleteOnExit();
}
if ( remainingPkg != "" ) {
verifyPackageDirExists( remainingPkg, currPkgDir );
}
}
else {
String filePath = null;
if ( offset != null ) {
filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR + offset + Config.DIR_SEP_CHAR + packageName;
}
else {
filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR + packageName;
}
File packageDir = new File( filePath );
if ( !packageDir.exists() ) {
packageDir.mkdir();
packageDir.deleteOnExit();
}
}
}

static void parseCommandLine(String[] args) {
if (args.length == 0) {
displayHelpAndExit( null );
}
List vargs = new LinkedList(Arrays.asList(args));

parseArgs(vargs, new File( "." )); // !!!

if (filenames.size() == 0) {
displayHelpAndExit( "ajdoc: No packages or classes specified" );
}
}

static void setSourcepath(String arg) {
sourcepath.clear();
arg = arg + ";"; // makes things easier for ourselves
StringTokenizer tokenizer = new StringTokenizer(arg, ";");
while (tokenizer.hasMoreElements()) {
sourcepath.addElement(tokenizer.nextElement());
}
}

static String getSourcepathAsString() {
String cPath = "";
for (int i = 0; i < sourcepath.size(); i++) {
cPath += (String)sourcepath.elementAt(i) + Config.DIR_SEP_CHAR + Config.WORKING_DIR;
if (i != sourcepath.size()-1) {
cPath += ";";
}
}
return cPath;
}

static void parseArgs(List vargs, File currentWorkingDir) {
boolean addNextAsOption = false;
boolean addNextAsArgFile = false;
boolean addNextToAJCOptions = false;
boolean addNextAsDocDir = false;
boolean addNextAsClasspath = false;
boolean ignoreArg = false; // used for discrepancy betwen class/sourcepath in ajc/javadoc
boolean addNextAsSourcePath = false;
if ( vargs.size() == 0 ) {
displayHelpAndExit( null );
}
for (int i = 0; i < vargs.size() ; i++) {
String arg = (String)vargs.get(i);
ignoreArg = false;
if ( addNextToAJCOptions ) {
ajcOptions.addElement( arg );
addNextToAJCOptions = false;
}
if ( addNextAsDocDir ) {
docDir = arg;
addNextAsDocDir = false;
}
if ( addNextAsClasspath ) {
addNextAsClasspath = false;
}
if ( addNextAsSourcePath ) {
setSourcepath( arg );
addNextAsSourcePath = false;
ignoreArg = true;
}
if ( arg.startsWith("@") ) {
expandAtSignFile(arg.substring(1), currentWorkingDir);
}
else if ( arg.equals( "-argfile" ) ) {
addNextAsArgFile = true;
}
else if ( addNextAsArgFile ) {
expandAtSignFile(arg, currentWorkingDir);
addNextAsArgFile = false;
}
else if (arg.equals("-d") ) {
addNextAsOption = true;
options.addElement(arg);
addNextAsDocDir = true;
}
else if ( arg.equals( "-bootclasspath" ) ) {
addNextAsOption = true;
addNextToAJCOptions = true;
options.addElement( arg );
ajcOptions.addElement( arg );
}
else if ( arg.equals( "-classpath" ) ) {
addNextAsOption = true;
addNextToAJCOptions = true;
addNextAsClasspath = true;
options.addElement( arg );
ajcOptions.addElement( arg );
}
else if ( arg.equals( "-sourcepath" ) ) {
addNextAsSourcePath = true;
//options.addElement( arg );
//ajcOptions.addElement( arg );
}
else if (arg.startsWith("-") || addNextAsOption) {
if ( arg.equals( "-private" ) ) {
docModifier = "private";
}
else if ( arg.equals( "-package" ) ) {
docModifier = "package";
}
else if ( arg.equals( "-protected" ) ) {
docModifier = "protected";
}
else if ( arg.equals( "-public" ) ) {
docModifier = "public";
}
else if ( arg.equals( "-verbose" ) ) {
verboseMode = true;
}
else if ( arg.equals( "-author" ) ) {
authorStandardDocletSwitch = true;
}
else if ( arg.equals( "-version" ) ) {
versionStandardDocletSwitch = true;
}
else if ( arg.equals( "-v" ) ) {
printVersion();
exit(0);
}
else if ( arg.equals( "-help" ) ) {
displayHelpAndExit( null );
}
else if ( arg.equals( "-doclet" ) || arg.equals( "-docletpath" ) ) {
System.out.println( "The doclet and docletpath options are not currently supported \n" +
"since ajdoc makes assumptions about the behavior of the standard \n" +
"doclet. If you would find this option useful please email us at: \n" +
" \n" +
" asupport@aspectj.org \n" +
" \n" );
exit(0);
}
else if ( addNextAsOption ) {
// just pass through
}
else {
displayHelpAndExit( null );
}
options.addElement(arg);
addNextAsOption = false;
}
else {
// check if this is a file or a package
if ( arg.indexOf( ".java" ) == arg.length() - 5 ||
arg.indexOf( ".lst" ) == arg.length() - 4 &&
arg != null ) {
File f = new File(arg);
if (f.isAbsolute()) {
filenames.addElement(arg);
}
else {
filenames.addElement( currentWorkingDir + Config.DIR_SEP_CHAR + arg );
}
fileList.addElement( arg );
}

// PACKAGE MODE STUFF
else if (!ignoreArg) {
packageMode = true;
packageList.addElement( arg );
arg = arg.replace( '.', '/' ); // !!!

// do this for every item in the classpath
for ( int c = 0; c < sourcepath.size(); c++ ) {
String path = (String)sourcepath.elementAt(c) + Config.DIR_SEP_CHAR + arg;
File pkg = new File(path);
if ( pkg.isDirectory() ) {
String[] files = pkg.list( new FilenameFilter() {
public boolean accept( File dir, String name ) {
int index1 = name.lastIndexOf( "." );
int index2 = name.length();
if ( (index1 >= 0 && index2 >= 0 ) &&
(name.substring(index1, index2).equals( ".java" ) ) ) {
return true;
}
else {
return false;
}
}
} );
for ( int j = 0; j < files.length; j++ ) {
filenames.addElement( (String)sourcepath.elementAt(c) +
Config.DIR_SEP_CHAR +
arg + Config.DIR_SEP_CHAR + files[j] );
}
}
else if (c == sourcepath.size() ) { // last element on classpath
System.out.println( "ajdoc: No package, class, or source file " +
"found named " + arg + "." );
}
else {
// didn't find it on that element of the classpath but that's ok
}
}
}
}
}
// set the default visibility as an option to javadoc option
if ( !options.contains( "-private" ) &&
!options.contains( "-package" ) &&
!options.contains( "-protected" ) &&
!options.contains( "-public" ) ) {
options.addElement( "-package" );
}

}

static void expandAtSignFile(String filename, File currentWorkingDir) {
List result = new LinkedList();

File atFile = qualifiedFile(filename, currentWorkingDir);
String atFileParent = atFile.getParent();
File myWorkingDir = null;
if (atFileParent != null) myWorkingDir = new File(atFileParent);

try {
BufferedReader stream = new BufferedReader(new FileReader(atFile));
String line = null;
while ( (line = stream.readLine()) != null) {
// strip out any comments of the form # to end of line
int commentStart = line.indexOf("//");
if (commentStart != -1) {
line = line.substring(0, commentStart);
}

// remove extra whitespace that might have crept in
line = line.trim();
// ignore blank lines
if (line.length() == 0) continue;
result.add(line);
}
} catch (IOException e) {
System.err.println("Error while reading the @ file " + atFile.getPath() + ".\n"
+ e);
System.exit( -1 );
}

parseArgs(result, myWorkingDir);
}

static File qualifiedFile(String name, File currentWorkingDir) {
name = name.replace('/', File.separatorChar);
File file = new File(name);
if (!file.isAbsolute() && currentWorkingDir != null) {
file = new File(currentWorkingDir, name);
}
return file;
}


static void displayHelpAndExit(String message) {
if (message != null) System.err.println(message);
System.err.println();
System.err.println(Config.USAGE);
exit(0);
}

static protected void exit(int value) {
System.out.flush();
System.err.flush();
System.exit(value);
}

/* This section of code handles errors that occur during compilation */
static final String internalErrorMessage =
"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" +
" \n";

static public void handleInternalError(Throwable uncaughtThrowable) {
System.err.println("An internal error occured in ajdoc");
System.err.println(internalErrorMessage);
System.err.println(uncaughtThrowable.toString());
uncaughtThrowable.printStackTrace();
System.err.println();
}

static void printVersion() {
System.out.println( Config.VERSION );
}

}



+ 229
- 0
ajdoc/src/org/aspectj/tools/ajdoc/Phase1.java View File

@@ -0,0 +1,229 @@
/* *******************************************************************
* 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
* Mik Kersten port to AspectJ 1.1+ code base
* ******************************************************************/

package org.aspectj.tools.ajdoc;

import java.io.File;
import java.io.FileOutputStream;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.StringReader;
import java.util.StringTokenizer;

import java.util.*;

class Phase1 {

static Hashtable declIDTable = null;

static void doFiles(Hashtable table,
SymbolManager symbolManager,
File[] inputFiles,
File[] signatureFiles) {
declIDTable = table;
for (int i = 0; i < inputFiles.length; i++) {
doFile(symbolManager, inputFiles[i], signatureFiles[i]);
}
}

static void doFile(SymbolManager symbolManager, File inputFile, File signatureFile) {
try {

Declaration[] decls = symbolManager.getDeclarations(inputFile.getCanonicalPath());

PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(signatureFile.getCanonicalPath())));

// write the package info
if ( decls != null && decls[0] != null && decls[0].getPackageName() != null ) {
writer.println( "package " + decls[0].getPackageName() + ";" );
}

if (decls != null) {
doDecls(decls, writer, false);
}
writer.close(); //this isn't in a finally, because if we got an
//error we don't really want the contents anyways
}
catch (IOException e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}

static void doDecls (Declaration[] decls,
PrintWriter writer,
boolean declaringDeclIsInterface) throws IOException {
for (int i = 0; i < decls.length; i++) {
Declaration decl = decls[i];
//System.out.println( ">> sig: " + decl.getSignature() );
doDecl(decl, writer, declaringDeclIsInterface);
}
}

static void doDecl(Declaration decl,
PrintWriter writer,
boolean declaringDeclIsInterface) throws IOException {
String formalComment = decl.getFormalComment();
String fullSignature = decl.getFullSignature();
System.err.println("> full: " + fullSignature);
Declaration[] ptbs = decl.getPointedToBy();
Declaration[] subs = decl.getDeclarations();
if (decl.hasSignature()) {
formalComment = addDeclID(decl, formalComment);

writer.println(formalComment);

// HACK: this should be in Declaration
int implementsClauseIndex = fullSignature.indexOf(" implements");
if (implementsClauseIndex != -1) {
String newSignature = "";
StringTokenizer st = new StringTokenizer(fullSignature.substring(implementsClauseIndex, fullSignature.length()));
for (String element = (String)st.nextElement(); st.hasMoreElements(); element = (String)st.nextElement()) {
if (element.indexOf("$MightHaveAspect") != -1
&& element.indexOf("implements") != -1) {
newSignature += element;
}
}
if (!newSignature.equals("")) {
writer.print(fullSignature.substring(0, implementsClauseIndex)
+ " implements " + newSignature + " " );
} else {
writer.print(fullSignature.substring(0, implementsClauseIndex) + " " );
}
} else {
writer.print(fullSignature + " " );
}

if ((!decl.hasBody() && !decl.getKind().equals( "interface" ) ||
(decl.getKind().equals( "method" ) && declaringDeclIsInterface)) && // !!! bug in Jim's API?
!(decl.getKind().equals("initializer") && decl.getModifiers().indexOf("static") != -1 ) ) {

System.err.println(">>>> kind: " + decl.getKind());

if (decl.getModifiers().indexOf("static final") != -1) {
String fullSig = decl.getFullSignature().trim();
String stripped = fullSig.substring(0, fullSig.lastIndexOf(' '));
//System.err.println(">>> " + fullSig);
String type = stripped.substring(stripped.lastIndexOf(' '), stripped.length());
//System.err.println("> type: " + type);

if (type.equals("boolean")) {
writer.println(" = false");
} else if (type.equals("char")) {
writer.println(" = '0'");
} else if (type.equals("byte")) {
writer.println(" = 0");
} else if (type.equals("short")) {
writer.println(" = 0");
} else if (type.equals("int")) {
writer.println(" = 0");
} else if (type.equals("long")) {
writer.println(" = 0");
} else if (type.equals("float")) {
writer.println(" = 0");
} else if (type.equals("double")) {
writer.println(" = 0");
} else if (type.equals("String")) {
writer.println(" = \"\"");
} else {
writer.println(" = null");
}
}
writer.println(";");
// } else if ((!decl.hasBody() && !decl.getKind().equals( "interface" ) ||
// (decl.getKind().equals( "method" ) && declaringDeclIsInterface)) && // !!! bug in Jim's API?
// !(decl.getKind().equals("initializer") && decl.getModifiers().indexOf("static") != -1 ) ) {
//
// writer.println(";");

} else {
if (subs != null) {
if ( decl.getKind().equals( "interface" ) ) {
declaringDeclIsInterface = true;
}
writer.println("{");
doDecls(subs, writer, declaringDeclIsInterface);
writer.println("}");
}
}
writer.println();
}
}

static int nextDeclID = 0;
static String addDeclID(Declaration decl, String formalComment) {
String declID = "" + ++nextDeclID;
declIDTable.put(declID, decl);
return addToFormal(formalComment, Config.DECL_ID_STRING + declID + Config.DECL_ID_TERMINATOR);
}

/**
* We want to go:
* just before the first period
* just before the first @
* just before the end of the comment
*
* Adds a place holder for the period ('#') if one will need to be
* replaced.
*/
static String addToFormal(String formalComment, String string) {
boolean appendPeriod = true;
if ( (formalComment == null) || formalComment.equals("")) {
//formalComment = "/**\n * . \n */\n";
formalComment = "/**\n * \n */\n";
appendPeriod = false;
}
formalComment = formalComment.trim();

int atsignPos = formalComment.indexOf('@');
int endPos = formalComment.indexOf("*/");
int periodPos = formalComment.indexOf("/**")+2;
//if ( atsignPos == -1 ) {
// periodPos = formalComment.lastIndexOf(".");
//} else {
// periodPos = formalComment.substring(0, atsignPos).lastIndexOf(".");
//}
int position = 0;
String periodPlaceHolder = "";
if ( periodPos != -1 ) {
position = periodPos+1;
//if ( appendPeriod ) {
//periodPlaceHolder = "#";
//}
}
else if ( atsignPos != -1 ) {
string = string + "\n * ";
position = atsignPos;
}
else if ( endPos != -1 ) {
string = "* " + string + "\n";
position = endPos;
}
else {
// !!! perhaps this error should not be silent
throw new Error("Failed to append to formal comment for comment: " +
formalComment );
}

return
formalComment.substring(0, position) + periodPlaceHolder +
string +
formalComment.substring(position);
}

}

+ 66
- 0
ajdoc/src/org/aspectj/tools/ajdoc/Phase2.java View File

@@ -0,0 +1,66 @@
/* *******************************************************************
* 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
* Mik Kersten port to AspectJ 1.1+ code base
* ******************************************************************/

package org.aspectj.tools.ajdoc;

import java.io.File;
import java.io.FileOutputStream;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.StringReader;

import java.util.*;

class Phase2 {
static void callJavadoc( String[] javadocargs ) {
final SecurityManager defaultSecurityManager = System.getSecurityManager();

System.setSecurityManager( new SecurityManager() {
public void checkExit(int status) {
if (status == 0) {
throw new SecurityException();
}
else {
System.setSecurityManager(defaultSecurityManager);
//System.out.println("Error: javadoc exited unexpectedly");
System.exit(0);
throw new SecurityException();
}
}
public void checkPermission( java.security.Permission permission ) {
if ( defaultSecurityManager != null )
defaultSecurityManager.checkPermission( permission );
}
public void checkPermission( java.security.Permission permission,
Object context ) {
if ( defaultSecurityManager != null )
defaultSecurityManager.checkPermission( permission, context );
}
} );

try {
com.sun.tools.javadoc.Main.main( javadocargs );
}
catch ( SecurityException se ) {
// Do nothing since we expect it to be thrown
//System.out.println( ">> se: " + se.getMessage() );
}
// Set the security manager back
System.setSecurityManager( defaultSecurityManager );
}
}

+ 731
- 0
ajdoc/src/org/aspectj/tools/ajdoc/Phase3.java View File

@@ -0,0 +1,731 @@
/* *******************************************************************
* 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
* Mik Kersten port to AspectJ 1.1+ code base
* ******************************************************************/

package org.aspectj.tools.ajdoc;

import java.io.File;
import java.io.FileOutputStream;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.StringReader;

import java.util.*;

class Phase3 {

static List visibleFileList = new ArrayList();
static Hashtable declIDTable = null;
static SymbolManager symbolManager = null;
static File rootDir = null;

static void decorateHTMLFromInputFiles(Hashtable table,
File newRootDir,
SymbolManager sm,
File[] inputFiles,
String docModifier ) throws IOException {
rootDir = newRootDir;
declIDTable = table;
symbolManager = sm;
for (int i = 0; i < inputFiles.length; i++) {
decorateHTMLFromDecls(symbolManager.getDeclarations(inputFiles[i].getCanonicalPath()),
rootDir.getCanonicalPath() + Config.DIR_SEP_CHAR,
docModifier,
false);
}
}

static void decorateHTMLFromDecls(Declaration[] decls, String base, String docModifier, boolean exceededNestingLevel) throws IOException {
if ( decls != null ) {
for (int i = 0; i < decls.length; i++) {
Declaration decl = decls[i];
decorateHTMLFromDecl(decl, base, docModifier, exceededNestingLevel);
}
}
}

/**
* Before attempting to decorate the HTML file we have to verify that it exists,
* which depends on the documentation visibility specified to javadoc.
*
* Depending on docModifier, can document
* - public: only public
* - protected: protected and public (default)
* - package: package protected and public
* - private: everything
*/
static void decorateHTMLFromDecl(Declaration decl,
String base,
String docModifier,
boolean exceededNestingLevel ) throws IOException {
boolean nestedClass = false;
if ( decl.isType() ) {
boolean decorateFile = true;
if ( (docModifier.equals( "private" )) || // everything
(docModifier.equals( "package" ) && decl.getModifiers().indexOf( "private" ) == -1) || // package
(docModifier.equals( "protected" ) && (decl.getModifiers().indexOf( "protected" ) != -1 ||
decl.getModifiers().indexOf( "public" ) != -1 )) ||
(docModifier.equals( "public" ) && decl.getModifiers().indexOf( "public" ) != -1) ) {
visibleFileList.add( getName( decl ) );
String packageName = decl.getPackageName();
String filename = "";
//System.out.println(">>>" + decl.getDeclaringType() + ", " + base);
if ( packageName != null ) {
int index1 = base.lastIndexOf(Config.DIR_SEP_CHAR);
int index2 = base.lastIndexOf(".");
String currFileClass = "";
if (index1 > -1 && index2 > 0 && index1 < index2) {
currFileClass = base.substring(index1+1, index2);
}
if (currFileClass.equals(decl.getDeclaringType())) {
// !!! hack for inner class !!!
packageName = packageName.replace( '.','/' );
String newBase = "";
if ( base.lastIndexOf(Config.DIR_SEP_CHAR) > 0 ) {
newBase = base.substring(0, base.lastIndexOf(Config.DIR_SEP_CHAR));
}
filename = newBase + Config.DIR_SEP_CHAR + packageName +
Config.DIR_SEP_CHAR + currFileClass + "." +
getName(decl) + ".html";
nestedClass = true;
}
else {
packageName = packageName.replace( '.','/' ); // !!!
filename = base + packageName + Config.DIR_SEP_CHAR + getName(decl) + ".html";
}
}
else {
filename = base + getName(decl) + ".html";
}
if (!exceededNestingLevel) {
decorateHTMLFile(new File(filename));
decorateHTMLFromDecls(decl.getDeclarations(),
base + getName(decl) + ".",
docModifier,
nestedClass);
}
else {
System.out.println("Warning: can not generate documentation for nested " +
"inner class: " + getName(decl) );
}
}
}
}

static void decorateHTMLFile(File file) throws IOException {
System.out.println( "> Decorating " + file.getCanonicalPath() + "..." );
BufferedReader reader = new BufferedReader(new FileReader(file));
StringBuffer fileContents = new StringBuffer();
String line = reader.readLine();
while( line != null ) {
fileContents.append(line + "\n");
line = reader.readLine();
}

boolean isSecond = false;
int index = 0;
Declaration decl;
while ( true ) {

//---this next part is an inlined procedure that returns two values---
//---the next declaration and the index at which that declaration's---
//---DeclID sits in the .html file ---
String contents = fileContents.toString();
int start = contents.indexOf( Config.DECL_ID_STRING, index);
int end = contents.indexOf( Config.DECL_ID_TERMINATOR, index );
if ( start == -1 )
decl = null;
else if ( end == -1 )
throw new Error("Malformed DeclID.");
else {
String tid = contents.substring(start + Config.DECL_ID_STRING.length(), end);
decl = (Declaration)declIDTable.get(tid);
index = start;
}
//--- ---
//--- ---

if ( decl == null ) break;
fileContents.delete(start, end + Config.DECL_ID_TERMINATOR.length());
if ( decl.isType() ) {
isSecond = true;
goAddIntroductions(decl, fileContents, index);
goAddAdvice(decl, fileContents, index);
goAddCrosscuts(decl, fileContents, index);
}
else {
decorateMemberDocumentation(decl, fileContents, index);
}
}

// Change "Class" to "Aspect", HACK: depends on "affects:"
if (fileContents.toString().indexOf("affects: ") != -1) {
int classStartIndex = fileContents.toString().indexOf("<BR>\nClass ");
int classEndIndex = fileContents.toString().indexOf("</H2>", classStartIndex);
if (classStartIndex != -1 && classEndIndex != -1) {
String classLine = fileContents.toString().substring(classStartIndex, classEndIndex);
String aspectLine = "<BR>\n" + "Aspect" + classLine.substring(11, classLine.length());
fileContents.delete(classStartIndex, classEndIndex);
fileContents.insert(classStartIndex, aspectLine);
}
}

file.delete();
FileOutputStream fos = new FileOutputStream( file );
fos.write( fileContents.toString().getBytes() );
}

static void goAddCrosscuts(Declaration decl, StringBuffer fileBuffer, int index ) {
Declaration[] crosscuts = decl.getCrosscutDeclarations();
if ( crosscuts.length > 0 ) {
insertDeclarationsSummary(fileBuffer, crosscuts, "Pointcut Summary", index);
insertDeclarationsDetails(fileBuffer, crosscuts, "Pointcut Detail", index);
}
}

static void goAddAdvice(Declaration decl, StringBuffer fileBuffer, int index ) {
Declaration[] advice = decl.getAdviceDeclarations();
if ( advice.length > 0 ) {
insertDeclarationsSummary(fileBuffer, advice, "Advice Summary", index);
insertDeclarationsDetails(fileBuffer, advice, "Advice Detail", index);
}
}

static void goAddIntroductions(Declaration decl,
StringBuffer fileBuffer,
int index ) {
Declaration[] introductions = decl.getIntroductionDeclarations();
if ( introductions.length > 0 ) {
insertDeclarationsSummary(fileBuffer,
introductions,
"Introduction Summary",
index);
insertDeclarationsDetails(fileBuffer,
introductions,
"Introduction Detail",
index);
}
}

static void insertDeclarationsSummary(StringBuffer fileBuffer,
Declaration[] decls,
String kind,
int index) {
int insertIndex = findSummaryIndex(fileBuffer, index);

// insert the head of the table
String tableHead =
"<!-- ======== " + kind.toUpperCase() + " ======= -->\n\n" +
"<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"1\"" +
"CELLSPACING=\"0\"><TR><TD COLSPAN=2 BGCOLOR=\"#CCCCFF\">" +
"<FONT SIZE=\"+2\"><B>" + kind + "</B></FONT></TD></TR>\n";
fileBuffer.insert(insertIndex, tableHead);
insertIndex += tableHead.length();

// insert the body of the table
for ( int i = 0; i < decls.length; i++ ) {
Declaration decl = decls[i];

// insert the table row accordingly
String comment = generateSummaryComment(decl);
String entry = "";
if ( kind.equals( "Advice Summary" ) ) {
entry +=
"<TR><TD>" +
"<A HREF=\"#" + generateHREFName(decl) + "\">" +
"<TT>advice " + decl.getCrosscutDesignator() + "</TT></A><BR><TT>" +
generateAdviceSignatures(decl) + "</TT><BR>&nbsp;";
if (!comment.equals("")) {
entry += comment + "<P>";
}
entry +=
generateAffects(decl, false) + "</TD>" +
"</TR><TD>\n";
}
else if ( kind.equals( "Pointcut Summary" ) ) {
entry +=
"<TR><TD WIDTH=\"1%\">" +
"<FONT SIZE=-1><TT>" + decl.getModifiers() + "</TT></FONT>" +
"</TD>\n" +
"<TD>" +
"<TT><A HREF=\"#" + generateHREFName(decl) + "\">" +
decl.getSignature() + "</A></TT><BR>&nbsp;";
if (!comment.equals("")) {
entry += comment + "<P>";
}
entry +=
"</TR></TD>\n";
}
else if ( kind.equals( "Introduction Summary" ) ) {
entry +=
"<TR><TD WIDTH=\"1%\">" +
"<FONT SIZE=-1><TT>" + decl.getModifiers() + "</TT></FONT>" +
"</TD>" +
"<TD>" +
"<A HREF=\"#" + generateHREFName(decl) + "\">" +
"<TT>introduction " + decl.getCrosscutDesignator() + "</TT></A><P>" +
generateIntroductionSignatures(decl, false) +
generateAffects(decl, true);
}

// insert the entry
fileBuffer.insert(insertIndex, entry);
insertIndex += entry.length();
}

// insert the end of the table
String tableTail = "</TABLE><P>&nbsp;\n";
fileBuffer.insert(insertIndex, tableTail);
insertIndex += tableTail.length();
}

static void insertDeclarationsDetails(StringBuffer fileBuffer,
Declaration[] decls,
String kind,
int index) {
int insertIndex = findDetailsIndex(fileBuffer, index);

// insert the table heading
String detailsHeading
= "<P>&nbsp;\n" +
"<!-- ======== " + kind.toUpperCase() + " SUMMARY ======= -->\n\n" +
"<TABLE BORDER=\"1\" CELLPADDING=\"3\" CELLSPACING=\"0\" WIDTH=\"100%\">\n" +
"<TR BGCOLOR=\"#CCCCFF\" CLASS=\"TableHeadingColor\">\n" +
"<TD COLSPAN=1><FONT SIZE=\"+2\">\n" +
"<B>" + kind + "</B></FONT></TD>\n" +
"</TR>\n" +
"</TABLE>";
fileBuffer.insert(insertIndex, detailsHeading);
insertIndex += detailsHeading.length();

// insert the details
for ( int i = 0; i < decls.length; i++ ) {
Declaration decl = decls[i];
String entry = "";

// insert the table row accordingly
entry += "<A NAME=\"" + generateHREFName(decl) + "\"><!-- --></A>\n";
if ( kind.equals( "Advice Detail" ) ) {
String designatorHREFLink = generateDesignatorHREFLink(decl);
if (designatorHREFLink != null) {
entry +=
"<H3>advice " + designatorHREFLink + "</H3><P>";
}
else {
entry +=
"<H3>advice " + decl.getCrosscutDesignator() + "</H3><P>";
}
entry +=
"<TT>" +
generateAdviceSignatures(decl) + "</TT>\n" + "<P>" +
generateDetailsComment(decl) + "<P>" +
generateAffects(decl, false);
}
else if (kind.equals("Pointcut Detail")) {
entry +=
"<H3>" +
decl.getSignature() +
"</H3><P>" +
generateDetailsComment(decl);
}
else if (kind.equals("Introduction Detail")) {
//String designatorHREFLink = generateDesignatorHREFLink(decl);
//if (designatorHREFLink != null) {
// entry +=
// "<H3>introduction " + designatorHREFLink + "</H3><P>";
//}
//else {
entry +=
"<H3>introduction " + decl.getCrosscutDesignator() + "</H3><P>";
//}
entry +=
generateIntroductionSignatures(decl, true) +
generateAffects(decl, true) +
generateDetailsComment(decl);
}

// insert the entry
if (i != decls.length-1) {
entry += "<P><HR>\n";
}
else {
entry += "<P>";
}
fileBuffer.insert(insertIndex, entry);
insertIndex += entry.length();
}
}

/**
* TODO: don't place the summary first.
*/
static int findSummaryIndex(StringBuffer fileBuffer, int index) {
String fbs = fileBuffer.toString();
String MARKER_1 = "<!-- =========== FIELD SUMMARY =========== -->";
String MARKER_2 = "<!-- ======== CONSTRUCTOR SUMMARY ======== -->";
int index1 = fbs.indexOf(MARKER_1, index);
int index2 = fbs.indexOf(MARKER_2, index);
if (index1 < index2) {
return index1;
}
else {
return index2;
}
}

static int findDetailsIndex(StringBuffer fileBuffer, int index) {
String fbs = fileBuffer.toString();
String MARKER_1 = "<!-- ========= CONSTRUCTOR DETAIL ======== -->";
String MARKER_2 = "<!-- ============ FIELD DETAIL =========== -->";
String MARKER_3 = "<!-- ============ METHOD DETAIL ========== -->";
int index1 = fbs.indexOf(MARKER_1, index);
int index2 = fbs.indexOf(MARKER_2, index);
int index3 = fbs.indexOf(MARKER_3, index);
if (index1 < index2 && index1 < index3) {
return index1;
}
else if (index2 < index1 && index2 < index3) {
return index2;
}
else {
return index3;
}
}

static void decorateMemberDocumentation( Declaration decl,
StringBuffer fileContentsBuffer,
int index ) {
if (decl.isIntroduced()) {
// !!! HACK, THIS HAS TO BE CHANGED WITH THE SYMBOL MANAGER
String fname = decl.getFilename();
int index1 = fname.lastIndexOf('\\');
int index2 = fname.lastIndexOf(".java");
String introducingType = fname;
if (index1 != -1 && index2 != -1) {
introducingType = fname.substring(index1+1, index2);
}
//System.out.println( "decl: " + decl.getSignature() + ", ptb: " + decl.getFilename());
String hrefName = "";
if (decl.getPackageName() != null ) {
hrefName = decl.getPackageName().replace('.', '/') + Config.DIR_SEP_CHAR +
introducingType;
}
else {
hrefName = introducingType;
}
String hrefLink = generateAffectsHREFLink( hrefName );
fileContentsBuffer.insert( index,
"<BR><B><FONT COLOR=CC6699>Introduced by: </FONT></B>" +
"<A HREF=\"" + hrefLink + "\">" +
hrefName.replace('/', '.') + "</A>" ); // !!! don't replace
return;
}
Declaration[] ptb = decl.getPointedToBy();
if ( ptb.length > 0 ) {
String prevName = "";
String adviceDoc = "<BR><B><FONT COLOR=CC6699>Advised by: </FONT></B>";
for ( int i = 0; i < ptb.length; i++ ) {
Declaration currDecl = ptb[i];
String hrefName = "";
if (currDecl.getPackageName() != null ) {
hrefName = currDecl.getPackageName().replace('.', '/') + Config.DIR_SEP_CHAR +
currDecl.getDeclaringType();
}
else {
hrefName = currDecl.getDeclaringType();
}
String hrefLink = generateAffectsHREFLink( hrefName );
if (!hrefName.equals(prevName)) { // !!! eliminates dupilcates since it's ordered
//if ( currDecl.getKind().equals( "introduction" ) ) {
// fileContentsBuffer.insert( index,
// "<BR><B><FONT COLOR=CC6699>Introduced by: </FONT></B>" +
// "<A HREF=\"" + hrefLink + "\">" +
// hrefName.replace('/', '.') + "</A>" ); // !!! don't replace
// return;
//}
if ( currDecl.getKind().equals( "advice" ) ) {
if ( i > 0 ) {
adviceDoc = adviceDoc + ", ";
}
adviceDoc = adviceDoc +
"<A HREF=\"" + hrefLink + "\">"
+ hrefName.replace('/', '.') + "</A>"; // !!! don't replace
}
}
prevName = hrefName;
}
//adviceDoc += "<BR>&nbsp;";
fileContentsBuffer.insert( index, adviceDoc );
//return lineHead + adviceDoc + lineTail;
}
else {
;// nop return lineHead + lineTail;
}
}

/**
* TODO: probably want to make this the same for intros and advice.
*/
static String generateAffects( Declaration decl, boolean isIntroduction) {
Declaration[] decls = null;
if ( isIntroduction ) {
decls = decl.getTargets(); // !!!
}
else {
decls = decl.getPointsTo();
}
List addedDecls = new ArrayList();
List packageList = new ArrayList();
for ( int i = 0; i < decls.length; i++ ) {
Declaration currDecl = decls[i];
//if ( currDecl.getDeclaringType().equals( "not$found" ) ) {
// System.out.println( "!!!!!! " + currDecl.getSignature() );
//}
if ( currDecl != null ) {
String extendedName = "";
String packageName = currDecl.getPackageName();

// !!! HACK FOR INNER CLASSES, ONLY WORKS FOR 1 LEVEL OF NESTING !!!
String declaringType = currDecl.getDeclaringType();
if (packageName != null && !packageName.equals("")) {
if (currDecl.isType() && declaringType != null && !declaringType.equals("not$found")) {
extendedName = packageName.replace('.', '/') + Config.DIR_SEP_CHAR + declaringType + ".";
}
else {
extendedName = packageName.replace('.', '/') + Config.DIR_SEP_CHAR;
}
}

//System.out.println("extendedName: " + extendedName);
if ( isIntroduction ) {
if ( !addedDecls.contains(currDecl.getSignature() ) ) {
//addedDecls.add(currDecl.getPackageName() + "." + currDecl.getSignature());
addedDecls.add(extendedName + currDecl.getSignature());
}
}
else if ( !addedDecls.contains(currDecl.getDeclaringType() ) ) {
//addedDecls.add(currDecl.getPackageName() + "." + currDecl.getDeclaringType());
addedDecls.add(extendedName + currDecl.getDeclaringType());
}
}
}
Collections.sort(addedDecls,
new Comparator() {
public int compare(Object o1, Object o2) {
String s1 = (String)o1;
String s2 = (String)o2;
return s1.compareTo(s2);
}
}
);

String entry
= "<TABLE WIDTH=\"100%\" BGCOLOR=#FFFFFF><TR><TD WIDTH=\"20\">&nbsp;</TD>" +
"<TD><FONT SIZE=-1>affects: ";
String prevType = "";
for ( int j = 0; j < addedDecls.size(); j++ ) {
String currType = (String)addedDecls.get(j);
// don't add duplicates
if ( !currType.equals( prevType ) && currType.indexOf("not$found") == -1 ) { //!!!
if ( j > 0 ) {
entry += ", ";
}
if ( generateAffectsHREFLink(currType) != "" ) {
entry += "<A HREF=\"" + generateAffectsHREFLink(currType) +
"\">" + currType.replace('/', '.') + "</A>"; // !!! don't replace
}
else {
entry += currType;
}
}
prevType = currType;
}
entry += "</FONT></TD></TR></TABLE>\n</TR></TD>\n";
return entry;
}

static String generateIntroductionSignatures(Declaration decl, boolean isDetails) {
Declaration[] decls = decl.getDeclarations();
String entry = "";
for ( int j = 0; j < decls.length; j++ ) {
Declaration currDecl = decls[j];
if ( currDecl != null ) {
entry +=
"<TT><B>" +
currDecl.getSignature() +
"</B></TT><BR>";
}
if (isDetails) {
entry += generateDetailsComment(currDecl) + "<P>";
}
else {
entry += generateSummaryComment(currDecl) + "<P>";
}
}
return entry;
}

static String generateAdviceSignatures( Declaration decl ) {
return "<B>" + decl.getSignature() + "</B>";
}

static String generateSummaryComment(Declaration decl) {
String COMMENT_INDENT = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; // !!!
String formattedComment = getFormattedComment(decl);
int periodIndex = formattedComment.indexOf( '.' );
if (formattedComment.equals("")) {
return "";
}
else if ( periodIndex != -1 ) {
return COMMENT_INDENT + formattedComment.substring( 0, periodIndex+1 ) ;
}
else {
return COMMENT_INDENT + formattedComment;
}
}

static String generateDetailsComment(Declaration decl) {
return getFormattedComment(decl);
}

static String generateHREFName(Declaration decl) {
String hrefLink = decl.getSignature(); // !!!
return hrefLink;
}


/**
* Figure out the link relative to the package.
*/
static String generateAffectsHREFLink(String declaringType) {
//String offset = rootDir.getAbsolutePath() + "/" + declaringType.replace('.', '/') + ".html";
String link = rootDir.getAbsolutePath() + "/" + declaringType + ".html";
//System.out.println(">>" + link);
return link;
}

/**
* This formats a comment according to the rules in the Java Langauge Spec:
* <I>The text of a docuemntation comment consists of the characters between
* the /** that begins the comment and the 'star-slash' that ends it. The text is
* devided into one or more lines. On each of these lines, the leading *
* characters are ignored; for lines other than the first, blanks and
* tabs preceding the initial * characters are also discarded.</I>
*
* TODO: implement formatting or linking for tags.
*/
static String getFormattedComment(Declaration decl) {
String formattedComment = "";

// strip the comment markers
String comment = decl.getFormalComment();

int startIndex = comment.indexOf("/**");
int endIndex = comment.indexOf("*/");
if ( startIndex == -1 ) {
startIndex = 0;
}
else {
startIndex += 3;
}
if ( endIndex == -1 ) {
endIndex = comment.length();
}
comment = comment.substring( startIndex, endIndex );

// string the leading whitespace and '*' characters at the beginning of each line
BufferedReader reader
= new BufferedReader( new StringReader( comment ) );
try {
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
line = line.trim();
for (int i = 0; i < line.length(); i++ ) {
if ( line.charAt(0) == '*' ) {
line = line.substring(1, line.length());
}
else {
break;
}
}
// !!! remove any @see and @link tags from the line
//int seeIndex = line.indexOf("@see");
//int linkIndex = line.indexOf("@link");
//if ( seeIndex != -1 ) {
// line = line.substring(0, seeIndex) + line.substring(seeIndex);
//}
//if ( linkIndex != -1 ) {
// line = line.substring(0, linkIndex) + line.substring(linkIndex);
//}
formattedComment += line;
}
} catch ( IOException ioe ) {
throw new Error( "Couldn't format comment for declaration: " +
decl.getSignature() );
}
return formattedComment;
}

static String generateDesignatorHREFLink(Declaration decl) {
Declaration ccutDecl = decl.getCrosscutDeclaration();
if (ccutDecl != null) {
// !!! the following stuff should use ccutDecl
return
"<A HREF=" +
ccutDecl.getDeclaringType() + ".html#" + generateHREFName(ccutDecl) + ">" +
ccutDecl.getSignature() + "</A>";
}
else {
//String link = decl.getCrosscutDesignator();
//System.out.println(">> link: " + link);
//return
// "<A HREF=\"TransportAspect.html#" + generateHREFName( decl ) + "\">" +
// decl.getCrosscutDesignator() + "</A>";
//return null;
return null;
}
}


// *************************************************************************** //
// ** This stuff should be in Declaration ** //
// *************************************************************************** //

static Declaration getCrosscutDeclaration(Declaration decl) {
//String filename = "D:\\Projects\\AJDoc\\apples\\TransportAspect.java";
//Declaration[] decls = symbolManager.getDeclarations(filename);
//decls = decls[0].getDeclarations();
//return decls[decls.length-2]; !!!
return null;
}

static String getName(Declaration decl) {
return decl.getSignature();
}
}


//
// !!! this stub only guaranteed to work for classes or interfaces
//
/*
static String getFullyQualifiedName(Declaration decl) {
if ( decl.getDeclaringType() == null )
return getName(decl);
else
return getFullyQualifiedName(decl.getDeclaringType()) + "$" + getName(decl);
}
*/

+ 54
- 0
ajdoc/src/org/aspectj/tools/ajdoc/SourceLine.java View File

@@ -0,0 +1,54 @@
/* *******************************************************************
* 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
* Mik Kersten port to AspectJ 1.1+ code base
* ******************************************************************/

package org.aspectj.tools.ajdoc;
import java.io.Serializable;
import java.io.File;

public class SourceLine implements Serializable {
public int line;
public String filename;
//boolean hasBody;

public SourceLine(String filename, int line) {
this.line = line;
this.filename = filename;
}

public String getDirectory() {
return new File(filename).getParent();
}

public int hashCode() {
return filename.hashCode() ^ line;
}

public boolean equals(Object other) {
if (!(other instanceof SourceLine)) return false;

SourceLine otherLine = (SourceLine)other;

return otherLine.line == line && otherLine.filename.equals(filename);
}

public String toString() {
return filename + "::" + line;
}

/**
* @return true when the method has a corresponding signature in the source code
* @return false otherwise
*/
//public boolean hasBody() { return hasBody; }
}

+ 390
- 0
ajdoc/src/org/aspectj/tools/ajdoc/SymbolManager.java View File

@@ -0,0 +1,390 @@
/* *******************************************************************
* 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
* Mik Kersten port to AspectJ 1.1+ code base
* ******************************************************************/

package org.aspectj.tools.ajdoc;


import java.util.*;

import org.aspectj.asm.*;




public class SymbolManager {

// public static File mapFilenameToSymbolFile(String filename) {
// return mapFilenameToNewExtensionFile(filename, SYMBOL_FILE_EXTENSION);
// }
//
// public static File mapFilenameToSourceLinesFile(String filename) {
// return mapFilenameToNewExtensionFile(filename, SOURCE_LINES_FILE_EXTENSION);
// }
//
// public static File getSourceToOutputFile(String dirname) {
// return new File(dirname, ".ajsline");
// }
//
// public static File getOutputToSourceFile(String dirname) {
// return new File(dirname, ".ajoline");
// }

//
// private static File mapFilenameToNewExtensionFile(String filename, String ext) {
// int lastDot = filename.lastIndexOf('.');
// String basename = filename;
// if (lastDot != -1) {
// basename = basename.substring(0, lastDot);
// }
//
// return new File(basename+ext);
// }

private static SymbolManager INSTANCE = new SymbolManager();

public static SymbolManager getDefault() {
return INSTANCE;
}

/**
* @param filePath the full path to the preprocessed source file
* @param lineNumber line number in the preprocessed source file
* @return the <CODE>SourceLine</CODE> corresponding to the original file/line
* @see SourceLine
*/
public SourceLine mapToSourceLine(String filePath, int lineNumber) {
System.err.println("> mapping: " + filePath);
return null;
// Map map = lookupOutputToSource(filePath);
//
// if (map == null) return null;
//
// return (SourceLine)map.get(new SourceLine(filePath, lineNumber));
}


/**
* @param filePath the full path to the original source file
* @param lineNumber line number in the original source file
* @return the <CODE>SourceLine</CODE> corresponding to the preprocessed file/line
* @see SourceLine
*/
public SourceLine mapToOutputLine(String filePath, int lineNumber) {
return null;
// Map map = lookupSourceToOutput(filePath);
//
// if (map == null) return null;
//
// return (SourceLine)map.get(new SourceLine(filePath, lineNumber));
}



/****
public int mapToOutputLine(String filename, int line) {
Vector sourceLines = lookupSourceLines(filename);

// do linear search here
if (sourceLines == null) return -1;

for(int outputLine = 0; outputLine < sourceLines.size(); outputLine++) {
SourceLine sl = (SourceLine)sourceLines.elementAt(outputLine);

if (sl == null) continue;
if (sl.line == line) {
String outputRoot = new File(filename).getName();
String sourceRoot = new File(sl.filename).getName();
if (outputRoot.equals(sourceRoot)) return outputLine + 1;
}
}

return -1;
}
****/

/**
* TODO: only works for one class
*/
public Declaration[] getDeclarations(String filename) {
IProgramElement file = (IProgramElement)AsmManager.getDefault().getHierarchy().findElementForSourceFile(filename);
IProgramElement node = (IProgramElement)file.getChildren().get(0);
// Declaration[] decls = new Declaration[node.getChildren().size()+1];
final List nodes = new ArrayList();
HierarchyWalker walker = new HierarchyWalker() {
public void preProcess(IProgramElement node) {
IProgramElement p = (IProgramElement)node;
nodes.add(buildDecl(p));
}
};

file.walk(walker);
return (Declaration[])nodes.toArray(new Declaration[nodes.size()]);
// return lookupDeclarations(filename);
}

private Declaration buildDecl(IProgramElement node) {
System.err.println("> getting decs: " + node);
String modifiers = "";
for (Iterator modIt = node.getModifiers().iterator(); modIt.hasNext(); ) {
modifiers += modIt.next() + " ";
}
// Declaration dec = new Declaration(
// node.getSourceLocation().getLine(),
// node.getSourceLocation().getEndLine(),
// node.getSourceLocation().getColumn(),
// -1,
// modifiers,
// node.getName(),
// node.getFullSignature(),
// "",
// node.getDeclaringType(),
// node.getKind(),
// node.getSourceLocation().getSourceFile().getAbsolutePath(),
// node.getFormalComment(),
// node.getPackageName()
// );
// return dec;
return null;
}

// // In the unusual case that there are multiple declarations on a single line
// // This will return a random one
// public Declaration getDeclarationAtLine(String filename, int line) {
// return getDeclarationAtPoint(filename, line, -1);
// }

public Declaration getDeclarationAtPoint(String filename, int line, int column) {

Declaration[] declarations = lookupDeclarations(filename);
//System.out.println("getting "+filename+", "+line+":"+column);
//System.out.println("decs: "+declarations);
return getDeclarationAtPoint(declarations, line, column);
}

public Declaration getDeclarationAtPoint(Declaration[] declarations, int line, int column) {
//!!! when we care about the performance of this method
//!!! these should be guaranteed to be sorted and a binary search used here
//!!! for now we use the simple (and reliable) linear search
if (declarations == null) return null;

for(int i=0; i<declarations.length; i++) {
Declaration dec = declarations[i];
if (dec.getBeginLine() == line) { // && dec.getEndLine() >= line) {
if (column == -1) return dec;
if (dec.getBeginColumn() == column) { // && dec.getEndColumn() >= column) {
return dec;
}
}
Declaration[] enclosedDecs = dec.getDeclarations();
if (enclosedDecs.length == 0) continue;

Declaration dec1 = getDeclarationAtPoint(enclosedDecs, line, column);
if (dec1 != null) return dec1;
}

//??? what should be returned for no declaration found
return null;
}

// private Hashtable symbolFileEntryCache = new Hashtable();

private Declaration[] lookupDeclarations(String filename) {
System.err.println("> looking up: " + filename);
return null;
// CorrFileEntry entry = lookup(filename, mapFilenameToSymbolFile(filename),
// symbolFileEntryCache);
// return (Declaration[])entry.data;
}

// private Hashtable sourceToOutputCache = new Hashtable();
// private Hashtable outputToSourceCache = new Hashtable();

// private Map lookupSourceToOutput(String filename) {
// CorrFileEntry entry = lookup(filename,
// getSourceToOutputFile(new File(filename).getParent()),
// sourceToOutputCache);
// return (Map)entry.data;
// }

// private Map lookupOutputToSource(String filename) {
// CorrFileEntry entry = lookup(filename,
// getOutputToSourceFile(new File(filename).getParent()),
// outputToSourceCache);
// return (Map)entry.data;
// }

/* generic code for dealing with correlation files, serialization, and caching */
// private static class CorrFileEntry {
// public long lastModified;
// public Object data;
//
// public CorrFileEntry(long lastModified, Object data) {
// this.lastModified = lastModified;
// this.data = data;
// }
// }

// private CorrFileEntry lookup(String filename, File file, Hashtable cache) {
// CorrFileEntry entry = (CorrFileEntry)cache.get(filename);
// if (entry != null && entry.lastModified == file.lastModified()) {
// return entry;
// }
//
// entry = createCorrFileEntry(file);
// cache.put(filename, entry);
// return entry;
// }

// private CorrFileEntry createCorrFileEntry(File file) {
// if (!file.exists()) {
// return new CorrFileEntry(0l, null);
// }
//
// try {
// long lastModified = file.lastModified();
// ObjectInputStream stream =
// new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)));
// Object data = stream.readObject();
// stream.close();
// return new CorrFileEntry(lastModified, data);
// } catch (IOException ioe) {
// //System.err.println("ERROR!!!");
// //ioe.printStackTrace();
// return new CorrFileEntry(0l, null);
// } catch (ClassNotFoundException cce) {
// //System.err.println("ERROR!!!");
// //cce.printStackTrace();
// return new CorrFileEntry(0l, null);
// }
// }


/**
* @param methodName method name without type or parameter list
* @return method name with ajc-specific name mangling removed,
* unchanged if there's not ajc name mangling present
*/
public static String translateMethodName(String methodName) {
int firstDollar = methodName.indexOf('$');

if (firstDollar == -1) return methodName;

String baseName = methodName.substring(firstDollar);

if (methodName.indexOf("ajc") != -1) {
return "<" + baseName + " advice>";
} else {
return baseName;
}
}


/************************************************************************
The rest of the code in this file is just for testing purposes
************************************************************************/

// private static final void printIndentation(int indent, String prefix) {
// for(int i=0; i< indent; i++) System.out.print(" ");
// System.out.print(prefix);
// }
//
//
// private static final void printDeclaration(Declaration dec, int indent, String prefix) {
// printIndentation(indent, prefix);
// if (dec == null) {
// System.out.println("null");
// return;
// }
//
// System.out.println(dec.getKind()+": "+dec.getDeclaringType()+": "+
// dec.getModifiers()+": "+dec.getSignature()+": " +
// //dec.getFullSignature()+": "+
// dec.getCrosscutDesignator()+
// ": "+dec.isIntroduced()+": "+dec.getPackageName()+": "+dec.getBeginLine()+":"+dec.getBeginColumn()
// );
//
// //printIndentation(indent, "\"\"\"");
// //System.out.println(dec.getFormalComment());
// /*
// if (dec.getParentDeclaration() != null) {
// printDeclaration(dec.getParentDeclaration(), indent+INDENT, "PARENT ");
// }
// if (dec.getCrosscutDeclaration() != null) {
// printDeclaration(dec.getCrosscutDeclaration(), indent+INDENT, "XC ");
// }
// */
// if (prefix.equals("")) {
// printDeclarations(dec.getTargets(), indent+INDENT, "T> ");
// printDeclarations(dec.getPointsTo(), indent+INDENT, ">> ");
// printDeclarations(dec.getPointedToBy(), indent+INDENT, "<< ");
// printDeclarations(dec.getDeclarations(), indent+INDENT, "");
// }
// }

// private static final void printDeclarations(Declaration[] decs, int indent, String prefix) {
// for(int i=0; i<decs.length; i++) {
// printDeclaration(decs[i], indent, prefix);
// }
// }

// private static final int INDENT = 2;

// static void printLines(String filename, Map baseMap) throws IOException {
// if (baseMap == null) return;
//
// String fullName = new File(filename).getCanonicalPath();
// java.util.TreeMap map = new java.util.TreeMap();
//
// for (Iterator i = baseMap.entrySet().iterator(); i.hasNext(); ) {
// Map.Entry entry = (Map.Entry)i.next();
// SourceLine keyLine = (SourceLine)entry.getKey();
// if (!keyLine.filename.equals(fullName)) continue;
//
// map.put(new Integer(keyLine.line), entry.getValue());
// }
//
// for (java.util.Iterator j = map.entrySet().iterator(); j.hasNext(); ) {
// java.util.Map.Entry entry = (java.util.Map.Entry)j.next();
//
// System.out.println(entry.getKey() + ":\t" + entry.getValue());
// }
// }

// public static void main(String[] args) throws IOException {
// for(int i=0; i<args.length; i++) {
// String filename = args[i];
// System.out.println(filename);
//
// System.out.println("declaration mappings");
// System.out.println("kind: declaringType: modifiers: signature: fullSignature: crosscutDesignator: isIntroduced: packageName: parentDeclaration");
//
// Declaration[] declarations = getSymbolManager().getDeclarations(filename);
// if (declarations != null) {
// printDeclarations(declarations, INDENT, "");
// }
//
// System.out.println("source to output");
// printLines(filename, getSymbolManager().lookupSourceToOutput(filename));
// System.out.println("output to source");
// printLines(filename, getSymbolManager().lookupOutputToSource(filename));
// }
// }
}

+ 1
- 0
ajdoc/testdata/figures-demo/.cvsignore View File

@@ -0,0 +1 @@
figures-demo-all.ajsym

+ 3
- 0
ajdoc/testdata/figures-demo/figures.lst View File

@@ -0,0 +1,3 @@
figures/*.java
figures/support/*.java
figures/gui/*.java

+ 55
- 0
ajdoc/testdata/figures-demo/figures/Box.java View File

@@ -0,0 +1,55 @@
/*
Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved.
*/

package figures;

import java.awt.*;
import java.awt.geom.*;

public class Box extends ShapeFigureElement {
private Point _p0;
private Point _p1;
private Point _p2;
private Point _p3;

public Box(int x0, int y0, int width, int height) {
_p0 = new Point(x0, y0);
_p1 = new Point(x0+width, y0);
_p2 = new Point(x0+width, y0+height);
_p3 = new Point(x0, y0+height);
}

public Point getP0() { return _p0; }
public Point getP1() { return _p1; }
public Point getP2() { return _p2; }
public Point getP3() { return _p3; }

public void move(int dx, int dy) {
_p0.move(dx, dy);
_p1.move(dx, dy);
_p2.move(dx, dy);
_p3.move(dx, dy);
}

public void checkBoxness() {
if ((_p0.getX() == _p3.getX()) &&
(_p1.getX() == _p2.getX()) &&
(_p0.getY() == _p1.getY()) &&
(_p2.getY() == _p3.getY()))
return;
throw new IllegalStateException("This is not a square.");
}

public String toString() {
return "Box(" + _p0 + ", " + _p1 + ", " + _p2 + ", " + _p3 + ")";
}

public Shape getShape() {
return new Rectangle(getP1().getX(),
getP1().getY(),
getP3().getX() - getP1().getX(),
getP3().getY() - getP1().getY());
}
}


+ 11
- 0
ajdoc/testdata/figures-demo/figures/Canvas.java View File

@@ -0,0 +1,11 @@
/*
Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved.
*/
package figures;

public class Canvas {
public static void updateHistory() {
// not implemented
}
}

+ 20
- 0
ajdoc/testdata/figures-demo/figures/ColorControl.java View File

@@ -0,0 +1,20 @@
/*
Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved.
*/

package figures;

import java.awt.Color;
import figures.FigureElement;

public aspect ColorControl {
public static void setFillColor(FigureElement fe, Color color) {
// fill in here
}

public static void setLineColor(FigureElement fe, Color color) {
// fill in here
}

// fill in here
}

+ 65
- 0
ajdoc/testdata/figures-demo/figures/Enforcement.java View File

@@ -0,0 +1,65 @@
/*
* (c) Copyright 2001 MyCorporation.
* All Rights Reserved.
*/
package figures;

public aspect Enforcement {

before(int newValue): set(int Point.*) && args(newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("> val: " + newValue + " is too small");
}
}

declare warning: call(void Canvas.updateHistory(..)) && !within(Enforcement): "";

after() returning: call(void FigureElement+.set*(..)) {
//Canvas.updateHistory();
}

declare error:
set(private * FigureElement+.*) &&
!(withincode(* FigureElement+.set*(..)) || withincode(FigureElement+.new(..))):
"should only assign to fileds from set methods";

}





















// before(int newValue): set(int Point.*) && args(newValue) {
// if (newValue < 0) {
// throw new IllegalArgumentException("> value: " + newValue + " too small");
// }
// }
//
// declare warning: call(void Canvas.updateHistory(..)) && !within(Enforcement):
// "found call";
//
// after() returning: call(void FigureElement+.set*(..)) {
// Canvas.updateHistory();
// }
//
// declare error:
// set(private * FigureElement+.*) &&
// !(withincode(* FigureElement+.set*(..)) || withincode(FigureElement+.new(..))):
// "should only assign to fields from set methods";

+ 21
- 0
ajdoc/testdata/figures-demo/figures/FigureElement.java View File

@@ -0,0 +1,21 @@
/*
Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved.
*/

package figures;

import java.awt.*;
import java.awt.geom.*;

public interface FigureElement {
public static final int MIN_VALUE = 0;
public static final int MAX_VALUE = 500;

public abstract void move(int dx, int dy);

public abstract Rectangle getBounds();

public abstract boolean contains(Point2D p);

public abstract void paint(Graphics2D g2);
}

+ 88
- 0
ajdoc/testdata/figures-demo/figures/Group.java View File

@@ -0,0 +1,88 @@
/*
Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved.
*/

package figures;

import java.util.*;
import java.awt.*;
import java.awt.geom.*;

public class Group implements FigureElement {
private Collection _members;
private String _identifier;

public Group(FigureElement first) {
this._members = new ArrayList();
add(first);
}

public void add(FigureElement fe) {
_members.add(fe);
}

public Iterator members() {
return _members.iterator();
}

public void move(int dx, int dy) {
for (Iterator i = _members.iterator(); i.hasNext(); ) {
FigureElement fe = (FigureElement)i.next();
fe.move(dx, dy);
}
}

public void resetIdentifier(String identifier) {
resetIdentifier(identifier);
}

public String toString() {
if (_identifier != null) {
return _identifier;
}

StringBuffer buf = new StringBuffer("Group(");
for (Iterator i = _members.iterator(); i.hasNext(); ) {
buf.append(i.next().toString());
if (i.hasNext()) {
buf.append(", ");
}
}
buf.append(")");
return buf.toString();
}

public Rectangle getBounds() {
Rectangle previous = null;
for (Iterator i = _members.iterator(); i.hasNext(); ) {
FigureElement fe = (FigureElement)i.next();
Rectangle rect = fe.getBounds();
if (previous != null) {
previous = previous.union(rect);
} else {
previous = rect;
}
}
return previous;
}

public boolean contains(Point2D p) {
for (Iterator i = _members.iterator(); i.hasNext(); ) {
FigureElement fe = (FigureElement)i.next();
if (fe.contains(p)) return true;
}
return false;
}

public void paint(Graphics2D g2) {
for (Iterator i = _members.iterator(); i.hasNext(); ) {
FigureElement fe = (FigureElement)i.next();
fe.paint(g2);
}
}

public int size() {
return _members.size();
}
}


+ 73
- 0
ajdoc/testdata/figures-demo/figures/Line.java View File

@@ -0,0 +1,73 @@
/*
Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved.
*/

package figures;

import java.awt.*;
import java.awt.geom.*;

public class Line extends ShapeFigureElement {
private Point _p1;
private Point _p2;

public Line(Point p1, Point p2) {
_p1 = p1;
_p2 = p2;
}

public Point getP1() {
return _p1;
}

public void setP1(Point p1) {
_p1 = p1;
Canvas.updateHistory();
}
public Point getP2() {
return _p2;
}

public void setP2(Point p2) {
_p2 = p2;
Canvas.updateHistory();
}

public void move(int dx, int dy) {
//_x = dx;
//_y = dy;

//_p1.move(dx, dy);
//_p2.move(dx, dy);
}

public String toString() {
return "Line(" + _p1 + ", " + _p2 + ")";
}

/**
* Used to determine if this line {@link contains(Point2D)} a point.
*/
final static int THRESHHOLD = 5;

/**
* Returns <code>true</code> if the point segment distance is less than
* {@link THRESHHOLD}.
*/
public boolean contains(Point2D p) {
return getLine2D().ptLineDist(p) < THRESHHOLD;
}

private Line2D getLine2D() {
return new Line2D.Float((float)getP1().getX(),
(float)getP1().getY(),
(float)getP2().getX(),
(float)getP2().getY());
}

public Shape getShape() {
return getLine2D();
}
}


+ 34
- 0
ajdoc/testdata/figures-demo/figures/Log.java View File

@@ -0,0 +1,34 @@
/*
Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved.
*/

public class Log {
private static StringBuffer data = new StringBuffer();

public static void traceObject(Object o) {
throw new UnsupportedOperationException();
}

public static void log(String s) {
data.append(s);
data.append(';');
}

public static void logClassName(Class _class) {
String name = _class.getName();
int dot = name.lastIndexOf('.');
if (dot == -1) {
log(name);
} else {
log(name.substring(dot+1, name.length()));
}
}

public static String getString() {
return data.toString();
}

public static void clear() {
data.setLength(0);
}
}

+ 59
- 0
ajdoc/testdata/figures-demo/figures/Point.java View File

@@ -0,0 +1,59 @@
/*
Copyright (c) 2001-2002 Palo Alto Research Center Incorporated. All Rights Reserved.
*/

package figures;

import java.awt.*;
import java.awt.geom.*;

public class Point extends ShapeFigureElement {
private int _x;
private int _y;

public Point(int x, int y) {
_x = x;
_y = y;
}

public int getX() {
return _x;
}

public void setX(int x) {
_x = x;
//Canvas.updateHistory();
}

public int getY() {
return _y;
}

public void setY(int y) {
_y = y;
//Canvas.updateHistory();
}

public void move(int dx, int dy) {
setX(_x + dx);
setY(_y + dy);
}

public String toString() {
return "Point(" + _x + ", " + _y + ")";
}

/** The height of displayed {@link Point}s. */
private final static int HEIGHT = 10;

/** The width of displayed {@link Point}s. -- same as {@link HEIGHT}. */
private final static int WIDTH = Point.HEIGHT;

public Shape getShape() {
return new Ellipse2D.Float((float)getX()-Point.WIDTH/2,
(float)getY()-Point.HEIGHT/2,
(float)Point.HEIGHT,
(float)Point.WIDTH);
}
}


+ 38
- 0
ajdoc/testdata/figures-demo/figures/ShapeFigureElement.java View File

@@ -0,0 +1,38 @@
/*
Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved.
*/

package figures;

import java.awt.*;
import java.awt.geom.*;

public abstract class ShapeFigureElement implements FigureElement {
public abstract void move(int dx, int dy);

public abstract Shape getShape();

public Rectangle getBounds() {
return getShape().getBounds();
}

public boolean contains(Point2D p) {
return getShape().contains(p);
}

public Color getLineColor() {
return Color.black;
}

public Color getFillColor() {
return Color.red;
}

public final void paint(Graphics2D g2) {
Shape shape = getShape();
g2.setPaint(getFillColor());
g2.fill(shape);
g2.setPaint(getLineColor());
g2.draw(shape);
}
}

+ 42
- 0
ajdoc/testdata/figures-demo/figures/SlothfulPoint.java View File

@@ -0,0 +1,42 @@
/*
Copyright (c) 2002 Palo Alto Research Center Incorporated. All Rights Reserved.
*/

package figures;

import java.awt.*;
import java.awt.geom.*;

/**
* This class makes mistakes to be caught by invariant checkers.
*/
public class SlothfulPoint extends ShapeFigureElement {
private int _x;
private int _y;

public SlothfulPoint(int x, int y) {
}

public void setX(int x) {
_x = x;
}
public void setY(int y) {
_y = y;
}

public void move(int dx, int dy) {
//_x += dx;
//_y += dy;
}

public String toString() {
return "SlothfulPoint";
}

public Shape getShape() {
return new Ellipse2D.Float((float)_x,
(float)_y, 1.0f, 1.0f);
}
}


Loading…
Cancel
Save