@@ -1,302 +0,0 @@ | |||
/* ******************************************************************* | |||
* 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.IOException; | |||
import java.io.ObjectOutputStream; | |||
import java.io.Serializable; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Iterator; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import org.aspectj.asm.IProgramElement; | |||
/** | |||
* @author Mik Kersten | |||
* @deprecated org.aspectj.asm.IProgramElement should be used instead | |||
*/ | |||
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; | |||
private IProgramElement node; | |||
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, | |||
IProgramElement node) | |||
{ | |||
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]; | |||
this.node = node; | |||
} | |||
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") || getKind().equals("aspect") || getKind().equals("enum"); | |||
} | |||
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); | |||
} | |||
} | |||
public IProgramElement getNode() { | |||
return node; | |||
} | |||
} |
@@ -28,6 +28,7 @@ import java.util.List; | |||
import java.util.StringTokenizer; | |||
import org.aspectj.asm.AsmManager; | |||
import org.aspectj.asm.HierarchyWalker; | |||
import org.aspectj.asm.IProgramElement; | |||
import org.aspectj.asm.IRelationship; | |||
import org.aspectj.util.TypeSafeEnum; | |||
@@ -49,32 +50,29 @@ class HtmlDecorator { | |||
static List visibleFileList = new ArrayList(); | |||
static Hashtable declIDTable = null; | |||
static SymbolManager symbolManager = null; | |||
static File rootDir = null; | |||
static String docVisibilityModifier; | |||
static void decorateHTMLFromInputFiles(Hashtable table, | |||
File newRootDir, | |||
SymbolManager sm, | |||
File[] inputFiles, | |||
String docModifier ) throws IOException { | |||
rootDir = newRootDir; | |||
declIDTable = table; | |||
symbolManager = sm; | |||
docVisibilityModifier = docModifier; | |||
for (int i = 0; i < inputFiles.length; i++) { | |||
decorateHTMLFromDecls(symbolManager.getDeclarations(inputFiles[i].getCanonicalPath()), | |||
rootDir.getCanonicalPath() + Config.DIR_SEP_CHAR, | |||
docModifier, | |||
false); | |||
decorateHTMLFromIPEs(getProgramElements(inputFiles[i].getCanonicalPath()), | |||
rootDir.getCanonicalPath() + Config.DIR_SEP_CHAR, | |||
docModifier, | |||
false); | |||
} | |||
} | |||
static void decorateHTMLFromDecls(Declaration[] decls, String base, String docModifier, boolean exceededNestingLevel) throws IOException { | |||
static void decorateHTMLFromIPEs(IProgramElement[] 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); | |||
IProgramElement decl = decls[i]; | |||
decorateHTMLFromIPE(decl, base, docModifier, exceededNestingLevel); | |||
} | |||
} | |||
} | |||
@@ -89,63 +87,57 @@ class HtmlDecorator { | |||
* - 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 (isAboveVisibility(decl.getNode())) { | |||
visibleFileList.add(decl.getSignature()); | |||
String packageName = decl.getPackageName(); | |||
String filename = ""; | |||
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); | |||
} | |||
// XXX only one level of nexting | |||
if (currFileClass.equals(decl.getDeclaringType())) { | |||
nestedClass = true; | |||
packageName = packageName.replace( '.','/' ); | |||
String newBase = ""; | |||
if ( base.lastIndexOf(Config.DIR_SEP_CHAR) > 0 ) { | |||
newBase = base.substring(0, base.lastIndexOf(Config.DIR_SEP_CHAR)); | |||
} | |||
String signature = constructNestedTypeName(decl.getNode()); | |||
filename = newBase + Config.DIR_SEP_CHAR + packageName + | |||
Config.DIR_SEP_CHAR + currFileClass + //"." + | |||
signature + ".html"; | |||
} else { | |||
packageName = packageName.replace( '.','/' ); | |||
filename = base + packageName + Config.DIR_SEP_CHAR + decl.getSignature() + ".html"; | |||
} | |||
} | |||
else { | |||
filename = base + decl.getSignature() + ".html"; | |||
} | |||
if (!exceededNestingLevel) { | |||
decorateHTMLFile(new File(filename)); | |||
decorateHTMLFromDecls(decl.getDeclarations(), | |||
base + decl.getSignature() + ".", | |||
docModifier, | |||
nestedClass); | |||
} | |||
else { | |||
System.out.println("Warning: can not generate documentation for nested " + | |||
"inner class: " + decl.getSignature() ); | |||
} | |||
} | |||
} | |||
} | |||
static void decorateHTMLFromIPE(IProgramElement decl, | |||
String base, | |||
String docModifier, | |||
boolean exceededNestingLevel ) throws IOException { | |||
boolean nestedClass = false; | |||
if ( decl.getKind().isType() ) { | |||
boolean decorateFile = true; | |||
if (isAboveVisibility(decl)) { | |||
visibleFileList.add(decl.toSignatureString()); | |||
String packageName = decl.getPackageName(); | |||
String filename = ""; | |||
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); | |||
} | |||
// XXX only one level of nexting | |||
if (currFileClass.equals(decl.getDeclaringType())) { | |||
nestedClass = true; | |||
packageName = packageName.replace( '.','/' ); | |||
String newBase = ""; | |||
if ( base.lastIndexOf(Config.DIR_SEP_CHAR) > 0 ) { | |||
newBase = base.substring(0, base.lastIndexOf(Config.DIR_SEP_CHAR)); | |||
} | |||
String signature = constructNestedTypeName(decl); | |||
filename = newBase + Config.DIR_SEP_CHAR + packageName + | |||
Config.DIR_SEP_CHAR + currFileClass + //"." + | |||
signature + ".html"; | |||
} else { | |||
packageName = packageName.replace( '.','/' ); | |||
filename = base + packageName + Config.DIR_SEP_CHAR + decl.toSignatureString() + ".html"; | |||
} | |||
} | |||
else { | |||
filename = base + decl.toSignatureString() + ".html"; | |||
} | |||
if (!exceededNestingLevel) { | |||
decorateHTMLFile(new File(filename)); | |||
} | |||
else { | |||
System.out.println("Warning: can not generate documentation for nested " + | |||
"inner class: " + decl.toSignatureString() ); | |||
} | |||
} | |||
} | |||
} | |||
private static String constructNestedTypeName(IProgramElement node) { | |||
if (node.getParent().getKind().isSourceFile()) { | |||
@@ -201,9 +193,6 @@ class HtmlDecorator { | |||
fileContents.delete(start, end + Config.DECL_ID_TERMINATOR.length()); | |||
if ( decl.getKind().isType() ) { | |||
isSecond = true; | |||
// addIntroductionDocumentation(decl, fileContents, index); | |||
// addAdviceDocumentation(decl, fileContents, index); | |||
// addPointcutDocumentation(decl, fileContents, index); | |||
String fullname = ""; | |||
if (decl.getParent().getKind().equals(IProgramElement.Kind.ASPECT) | |||
|| decl.getParent().getKind().equals(IProgramElement.Kind.CLASS)) { | |||
@@ -336,22 +325,6 @@ class HtmlDecorator { | |||
decorateDocWithRel(node,fileBuffer,index,advisedBy,HtmlRelationshipKind.ADVISED_BY); | |||
} | |||
} | |||
// static void addIntroductionDocumentation(IProgramElement 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, | |||
List decls, | |||
@@ -626,7 +599,6 @@ class HtmlDecorator { | |||
if (currDecl.getPackageName() != null ) { | |||
hrefName = currDecl.getPackageName().replace('.', '/'); | |||
// hrefLink = "";//+ currDecl.getPackageName() + Config.DIR_SEP_CHAR; | |||
} | |||
// in the case of nested classes, in order for the links to work, | |||
@@ -869,24 +841,6 @@ class HtmlDecorator { | |||
static String generateIntroductionSignatures(IProgramElement decl, boolean isDetails) { | |||
return "<not implemented>"; | |||
// 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 generateSignatures(IProgramElement decl ) { | |||
@@ -913,7 +867,6 @@ class HtmlDecorator { | |||
} | |||
static String generateHREFName(IProgramElement decl) { | |||
//String hrefLink = decl.toLabelString().replace("\"", "quot;"); // !!! | |||
StringBuffer hrefLinkBuffer = new StringBuffer(); | |||
char[] declChars = decl.toLabelString().toCharArray(); | |||
for (int i = 0; i < declChars.length; i++) { | |||
@@ -999,6 +952,34 @@ class HtmlDecorator { | |||
return formattedComment; | |||
} | |||
static public IProgramElement[] getProgramElements(String filename) { | |||
IProgramElement file = (IProgramElement)AsmManager.getDefault().getHierarchy().findElementForSourceFile(filename); | |||
final List nodes = new ArrayList(); | |||
HierarchyWalker walker = new HierarchyWalker() { | |||
public void preProcess(IProgramElement node) { | |||
IProgramElement p = (IProgramElement)node; | |||
if (accept(node)) nodes.add(p); | |||
} | |||
}; | |||
file.walk(walker); | |||
return (IProgramElement[])nodes.toArray(new IProgramElement[nodes.size()]); | |||
} | |||
/** | |||
* Rejects anonymous kinds by checking if their name is an integer | |||
*/ | |||
static private boolean accept(IProgramElement node) { | |||
if (node.getKind().isType()) { | |||
boolean isAnonymous = StructureUtil.isAnonymous(node); | |||
return !node.getParent().getKind().equals(IProgramElement.Kind.METHOD) | |||
&& !isAnonymous; | |||
} else { | |||
return !node.getKind().equals(IProgramElement.Kind.IMPORT_REFERENCE); | |||
} | |||
} | |||
/** | |||
* TypeSafeEnum for the entries which need to be put in the html doc | |||
*/ |
@@ -32,8 +32,6 @@ import org.aspectj.util.FileUtil; | |||
public class Main implements Config { | |||
private static final String FAIL_MESSAGE = "> compile failed, exiting ajdoc"; | |||
static SymbolManager symbolManager = null; | |||
/** Command line options. */ | |||
static Vector options; | |||
@@ -72,7 +70,6 @@ public class Main implements Config { | |||
private static String outputWorkingDir = Config.WORKING_DIR; | |||
public static void clearState() { | |||
symbolManager = null; | |||
options = new Vector(); | |||
ajcOptions = new Vector(); | |||
filenames = new Vector(); | |||
@@ -101,7 +98,6 @@ public class Main implements Config { | |||
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 { | |||
@@ -158,7 +154,7 @@ public class Main implements Config { | |||
// PHASE 1: generate Signature files (Java with DeclIDs and no bodies). | |||
System.out.println( "> Building signature files..." ); | |||
try{ | |||
StubFileGenerator.doFiles(declIDTable, symbolManager, inputFiles, signatureFiles); | |||
StubFileGenerator.doFiles(declIDTable, inputFiles, signatureFiles); | |||
} catch (DocException d){ | |||
System.err.println(d.getMessage()); | |||
// d.printStackTrace(); | |||
@@ -219,7 +215,6 @@ public class Main implements Config { | |||
System.out.println( "> Decorating html files..." ); | |||
HtmlDecorator.decorateHTMLFromInputFiles(declIDTable, | |||
rootDir, | |||
symbolManager, | |||
inputFiles, | |||
docModifier); | |||
@@ -586,7 +581,7 @@ public class Main implements Config { | |||
else { | |||
// check if this is a file or a package | |||
// System.err.println(">>>>>>>> " + ); | |||
String entryName = arg.substring(arg.lastIndexOf(File.separator)+1); | |||
// String entryName = arg.substring(arg.lastIndexOf(File.separator)+1); | |||
if (FileUtil.hasSourceSuffix(arg) | |||
|| arg.endsWith(".lst") | |||
&& arg != null ) { |
@@ -30,17 +30,16 @@ class StubFileGenerator{ | |||
static Hashtable declIDTable = null; | |||
static void doFiles (Hashtable table, | |||
SymbolManager symbolManager, | |||
File[] inputFiles, | |||
File[] signatureFiles) throws DocException { | |||
declIDTable = table; | |||
for (int i = 0; i < inputFiles.length; i++) { | |||
processFile(symbolManager, inputFiles[i], signatureFiles[i]); | |||
processFile(inputFiles[i], signatureFiles[i]); | |||
} | |||
} | |||
static void processFile(SymbolManager symbolManager, File inputFile, File signatureFile) throws DocException { | |||
static void processFile(File inputFile, File signatureFile) throws DocException { | |||
try { | |||
String path = StructureUtil.translateAjPathName(signatureFile.getCanonicalPath()); | |||
PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(path))); | |||
@@ -193,11 +192,11 @@ class StubFileGenerator{ | |||
* replaced. | |||
*/ | |||
static String addToFormal(String formalComment, String string) { | |||
boolean appendPeriod = true; | |||
//boolean appendPeriod = true; | |||
if ( (formalComment == null) || formalComment.equals("")) { | |||
//formalComment = "/**\n * . \n */\n"; | |||
formalComment = "/**\n * \n */\n"; | |||
appendPeriod = false; | |||
//appendPeriod = false; | |||
} | |||
formalComment = formalComment.trim(); | |||
@@ -1,359 +0,0 @@ | |||
/* ******************************************************************* | |||
* 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.*; | |||
/** | |||
* @author Mik Kersten | |||
*/ | |||
public class SymbolManager { | |||
private static SymbolManager INSTANCE = new SymbolManager(); | |||
public static SymbolManager getDefault() { | |||
return INSTANCE; | |||
} | |||
/** | |||
* 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; | |||
if (accept(node)) nodes.add(buildDecl(p)); | |||
} | |||
}; | |||
file.walk(walker); | |||
return (Declaration[])nodes.toArray(new Declaration[nodes.size()]); | |||
} | |||
/** | |||
* Rejects anonymous kinds by checking if their name is an integer | |||
*/ | |||
private boolean accept(IProgramElement node) { | |||
if (node.getKind().isType()) { | |||
boolean isAnonymous = StructureUtil.isAnonymous(node); | |||
return !node.getParent().getKind().equals(IProgramElement.Kind.METHOD) | |||
&& !isAnonymous; | |||
} else { | |||
return !node.getKind().equals(IProgramElement.Kind.IMPORT_REFERENCE); | |||
} | |||
// && !(node.getKind().isType() && | |||
// node.getParent().getKind().equals(IProgramElement.Kind.METHOD)); | |||
} | |||
private Declaration buildDecl(IProgramElement node) { | |||
String signature = ""; | |||
String accessibility = node.getAccessibility().toString(); | |||
if (!accessibility.equals("package")) signature = accessibility.toString() + " "; | |||
String modifiers = ""; | |||
if (!node.getAccessibility().equals(IProgramElement.Accessibility.PACKAGE)) modifiers += node.getAccessibility() + " "; | |||
for (Iterator modIt = node.getModifiers().iterator(); modIt.hasNext(); ) { | |||
modifiers += modIt.next() + " "; | |||
} | |||
if (node.getKind().equals(IProgramElement.Kind.METHOD) || | |||
node.getKind().equals(IProgramElement.Kind.FIELD)) { | |||
signature += node.getCorrespondingType() + " "; | |||
} | |||
if (node.getKind().equals(IProgramElement.Kind.CLASS) || | |||
node.getKind().equals(IProgramElement.Kind.METHOD)) { | |||
signature += "class "; | |||
} else if (node.getKind().equals(IProgramElement.Kind.INTERFACE) || | |||
node.getKind().equals(IProgramElement.Kind.METHOD)) { | |||
signature += "interface "; | |||
} | |||
signature += node.toSignatureString(); | |||
String name = node.getName(); | |||
if (node.getKind().isType()) { | |||
name = genPartiallyQualifiedName(node, node.getName()); | |||
} | |||
String declaringType = node.getParent().getName(); | |||
// if (!node.getKind().isType()) { | |||
// declaringType = node.getParent().getName(); | |||
// } | |||
Declaration dec = new Declaration( | |||
node.getSourceLocation().getLine(), | |||
node.getSourceLocation().getEndLine(), | |||
node.getSourceLocation().getColumn(), | |||
-1, | |||
modifiers, | |||
name, | |||
signature, | |||
"", // crosscut designator | |||
node.getDeclaringType(), | |||
node.getKind().toString(), | |||
node.getSourceLocation().getSourceFile().getAbsolutePath(), | |||
node.getFormalComment(), | |||
node.getPackageName(), | |||
node | |||
); | |||
return dec; | |||
} | |||
// // 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); | |||
// } | |||
private String genPartiallyQualifiedName(IProgramElement node, String name) { | |||
// if (node.getParent() != null) System.err.println("%%% " + node.getParent()); | |||
if (node.getParent() != null && node.getParent().getKind().isType()) { | |||
name = node.getParent().getName() + '.' + name; | |||
genPartiallyQualifiedName(node.getParent(), name); | |||
} | |||
return name; | |||
} | |||
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)); | |||
// } | |||
// } | |||
} |