123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605 |
- /* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This file is part of the debugger and core tools for the AspectJ(tm)
- * programming language; see http://aspectj.org
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is AspectJ.
- *
- * The Initial Developer of the Original Code is Xerox Corporation. Portions
- * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
- * All Rights Reserved.
- */
- package org.aspectj.tools.ajdoc;
-
- import org.aspectj.compiler.base.AbstractCompilerPass;
- import org.aspectj.compiler.base.ErrorHandler;
- import org.aspectj.compiler.base.ast.CompilationUnit;
- import org.aspectj.compiler.base.ast.Dec;
- import org.aspectj.compiler.base.ast.Decs;
- import org.aspectj.compiler.base.ast.TypeDec;
- import org.aspectj.compiler.base.ast.World;
- import org.aspectj.compiler.crosscuts.AspectJCompiler;
-
- import com.sun.javadoc.DocErrorReporter;
- import com.sun.javadoc.RootDoc;
-
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileFilter;
- import java.io.FileReader;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import java.util.StringTokenizer;
-
- /**
- * Extension of the AspectJCompiler to provide
- * functionality for creating documentation.
- *
- * @author Jeff Palm
- */
- public class AjdocCompiler extends AspectJCompiler implements RootDocMaker {
-
- /** The name of the program. */
- protected final String programName;
-
- /** The error printer we use. */
- protected final ErrPrinter err;
-
- /**
- * Construct a new ajdoc compile with the
- * error handler <code>errorHandler</code> and
- * name <code>programName</code>
- *
- * @param errorHandler the error handler.
- * @param programName the name of the program.
- */
- public AjdocCompiler(ErrorHandler errorHandler, String programName) {
- super(errorHandler);
- getOptions().preprocess = true;
- getOptions().nocomments = true;
- (errorHandler = err =
- new ErrPrinter(this.programName = programName)).
- setCompiler(this);
- }
-
- /**
- * Construct a new ajdoc compile with the
- * name <code>programName</code>.
- *
- * @param programName the name of the program.
- */
- public AjdocCompiler(String programName) {
- this(null, programName);
- }
-
- /**
- * Returns the ErrPrinter currently used.
- *
- * @return the ErrPrinter currently used.
- */
- public ErrPrinter err() {
- return err;
- }
-
- /** The packages found on the command line. */
- private Set pkgnames = new HashSet();
-
- /** The classes found on the command line and from files. */
- private Set classnames = new HashSet();
-
- /** The source files on the command line. */
- private Set files = new HashSet();
-
- /** The list of source files to compile. */
- protected final List srcfiles = new ArrayList();
-
- /** The list of filenames that came from user-specified source files. */
- protected List srcSrcfilenames = new ArrayList();
-
- /** The list of filenames that came from user-specified packages. */
- protected List pkgSrcfilenames = new ArrayList();
-
- /** The list of filenames that came from user-specified classes. */
- protected List clsSrcfilenames = new ArrayList();
-
- /** The source path with which to search. */
- protected final List sourcepaths = new ArrayList();
- {
- sourcepaths.add(new File("."));
- }
- /** The list of filenames that came from user-specified classes. */
- protected AccessChecker filter;
-
- /**
- * Create the RootDoc.
- */
- public RootDoc makeRootDoc(String sourcepath,
- String classpath,
- String bootclasspath,
- String extdirs,
- long flags,
- String encoding,
- String locale,
- String source,
- List filenamesAndPackages,
- List options,
- DocErrorReporter err,
- String programName,
- AccessChecker filter)
- throws CannotMakeRootDocException {
- if ((null != filter) && (this.filter != filter)) {
- this.filter = filter;
- }
- if (null == this.filter) {
- this.filter = AccessChecker.PROTECTED;
- }
- if (classpath != null) {
- getOptions().classpath = classpath;
- }
- if (bootclasspath != null) {
- getOptions().bootclasspath = bootclasspath;
- }
- if (extdirs != null) {
- getOptions().extdirs = extdirs;
- }
- if (source != null) {
- getOptions().source = source;
- }
- resolveSourcePath(sourcepath);
- resolveFilesAndPackages(filenamesAndPackages);
-
- Collections.sort(pkgSrcfilenames);
- Collections.sort(clsSrcfilenames);
- Collections.sort(srcSrcfilenames);
-
- srcfiles.addAll(pkgSrcfilenames);
- srcfiles.addAll(clsSrcfilenames);
- srcfiles.addAll(srcSrcfilenames);
-
- err().notice("starting_internal_compile");
-
- for (Iterator i = options.iterator(); i.hasNext();) {
- String[] opts = (String[])i.next();
- if (opts.length == 1) {
- if (opts[0].equals("-verbose")) {
- getOptions().verbose = true;
- }
- } else if (opts.length == 2) {
- if (opts[0].equals("-classpath")) {
- getOptions().classpath = opts[1];
- } else if (opts[1].equals("-bootclasspath")) {
- getOptions().bootclasspath = opts[1];
- } else if (opts[1].equals("-extdirs")) {
- getOptions().extdirs = opts[1];
- }
- }
- }
-
- // Compile the srcfiles - have to add passes first
- addPasses();
- internalCompile(srcfiles);
-
- // This is the world with which we create the root
- World world = getWorld();
-
- // Add all the classes found in the source files
- // to the list of specified classnames
- for (Iterator i = world.getCompilationUnits().iterator();
- i.hasNext();) {
- Decs decs = ((CompilationUnit)i.next()).getDecs();
- for (int j = 0, N = decs.size(); j < N; j++) {
- Dec dec = decs.get(j);
- if (dec instanceof TypeDec) {
- classnames.add(((TypeDec)dec).getFullName());
- }
- }
- }
-
- // Initialize and return the root created
- // from the our world
- err().notice("creating_root");
- RootDoc result = init(this, (String[][])options.toArray
- (new String[options.size()][]));
-
- // do another pass at RootDoc after constructed
- com.sun.javadoc.ClassDoc[] cds = result.classes();
- for (int i = 0; i < cds.length; i++) {
- if (cds[i] instanceof ClassDocImpl) {
- ClassDocImpl cd = (ClassDocImpl) cds[i];
- cd.postProcess();
- }
- }
- return result;
- }
-
-
- private static AjdocCompiler instance;
- { instance = this; }
-
- public static AjdocCompiler instance() {
- return instance;
- }
-
- /**
- * The entry point to initialize a world created
- * from an AspectJCompiler.
- *
- * @param ajc the compiler.
- * @param options the ajdoc options.
- * @return a RootDocImpl representing the
- * documentation tree.
- */
- public static RootDocImpl init(AspectJCompiler ajc, String[][] options) {
-
- if (ajc == null) return null; //TODO: make empty
-
- World world = ajc.getWorld();
-
- Collection classnames = null;
- Collection pkgnames = null;
- if (ajc instanceof AjdocCompiler) {
- AjdocCompiler ajdoc = (AjdocCompiler)ajc;
- pkgnames = ajdoc.pkgnames;
- classnames = ajdoc.classnames;
- }
-
- PackageDocImpl.init(ajc);
-
- AccessChecker filter = AccessChecker.PUBLIC;
- if (ajc instanceof AjdocCompiler) {
- filter = ((AjdocCompiler) ajc).getFilter();
- }
- RootDocImpl root = new RootDocImpl(world,
- options,
- pkgnames,
- classnames,
- filter);
- return root;
- }
-
- /** set filter associated with this compiler */
- protected void setFilter(AccessChecker filter, String arg) {
- this.filter = filter;
- }
-
- /** get filter associated with this compiler */
- public final AccessChecker getFilter() {
- return filter;
- }
-
- protected final void expandAtFile(String filename,
- List args) throws IOException {
- BufferedReader in = new BufferedReader(new FileReader(filename));
- String dirfile = new File(filename).getParent();
- File basedir = new File(null == dirfile ? "." : dirfile ) ;
- String line;
- while ((line = in.readLine()) != null) {
- if (line == null || line.length() < 1) continue;
- line = line.trim();
- if (line.startsWith("//")) continue;
- if (line.startsWith("#")) continue;
- if (line.startsWith("@")) {
- line = line.substring(1);
- File newfile = new File(line);
- newfile = newfile.isAbsolute() ?
- newfile : new File(basedir, line);
- expandAtFile(newfile.getPath(), args);
- } else {
- File newfile = new File(line);
- newfile = newfile.isAbsolute() ?
- newfile : new File(basedir, line);
- if (newfile.exists()) {
- boolean result = maybeAdd(newfile, args);
- if (!result) {
- // we only support valid filenames, not options
- cantResolve(newfile);
- }
- } else {
- boolean addedFile = false;
- FileFilter filter = null;
- String name = newfile.getName().trim();
- if (name.equals("*.java")) {
- filter = new FileFilter() {
- public boolean accept(File f) {
- return f != null &&
- f.getName().endsWith(".java");
- }
- };
- } else if (name.equals("*.aj")) {
- filter = new FileFilter() {
- public boolean accept(File f) {
- return f != null &&
- f.getName().endsWith(".java");
- }
- };
- } else if (name.equals("*")) {
- filter = new FileFilter() {
- public boolean accept(File f) {
- return f != null &&
- (f.getName().endsWith(".java")
- || f.getName().endsWith(".aj"));
- }
- };
- }
- if (null != filter) {
- File parentDir = newfile.getParentFile();
- File[] javafiles = parentDir.listFiles(filter);
- if (javafiles != null) {
- for (int i = 0; i < javafiles.length; i++) {
- if (maybeAdd(javafiles[i], args)) {
- if (!addedFile) addedFile = true;
- } else {
- cantResolve(javafiles[i]);
- }
- }
- }
- }
- if (!addedFile) {
- if (isValidPkg(line)) {
- args.add(line);
- } else {
- cantResolve(newfile);
- }
- }
- }
- }
- }
- in.close();
- }
-
- protected final void cantResolve(File f) {
- err().error("cant_resolve_file", f.getAbsolutePath());
- }
-
- private void resolveSourcePath(String sourcepath) {
- if (sourcepath != null) {
- sourcepaths.remove(0);
- for (StringTokenizer t = new StringTokenizer(sourcepath,
- File.pathSeparator);
- t.hasMoreTokens();) {
- File path = new File(t.nextToken().trim());
- if (path.exists() && path.isDirectory()) {
- sourcepaths.add(path);
- }
- }
- // TODO: don't want this, I think ????
- //sourcepaths.add(new File("."));
- }
- }
-
- private void resolveFilesAndPackages(List filenamesAndPackages) {
- Collection pkgnamesFromCmd = new HashSet();
- for (Iterator i = filenamesAndPackages.iterator(); i.hasNext();) {
- String str = (String)i.next();
- File file = new File(str);
- if (/*file.isAbsolute() &&*/ maybeAdd(file, srcSrcfilenames)) {
- addFile(file);
- continue;
- } else {
- for (Iterator j = sourcepaths.iterator(); j.hasNext();) {
- File sourcepath = (File)j.next();
- file = new File(sourcepath, str);
- if (maybeAdd(file, srcSrcfilenames)) {
- addFile(file);
- continue;
- }
- }
- }
- pkgnamesFromCmd.add(str);
- }
- for (Iterator i = pkgnamesFromCmd.iterator(); i.hasNext();) {
- resolvePackageOrClass((String)i.next());
- }
- }
-
- private void resolvePackageOrClass(String pkgOrClassName) {
- boolean recurse;
- String pkgOrClass =
- (recurse = (pkgOrClassName.endsWith(".*"))) ?
- pkgOrClassName.substring(0, pkgOrClassName.length()-2) :
- pkgOrClassName;
- for (Iterator i = sourcepaths.iterator(); i.hasNext();) {
- File sourcepath = (File)i.next();
- File possiblePkg = new File(sourcepath,
- pkgOrClass.replace
- ('.', File.separatorChar));
- if (possiblePkg.exists() && possiblePkg.isDirectory()) {
- if (recurse) {
- File[] dirs = possiblePkg.listFiles
- (new FileFilter() {
- public boolean accept(File f) {
- return f != null && f.isDirectory();
- }
- });
- for (int j = 0; j < dirs.length; j++) {
- String pkgname = pkgOrClass + '.' + dirs[j].getName();
- resolvePackageOrClass(pkgname + ".*");
- }
- }
- File[] javafiles = possiblePkg.listFiles
- (new FileFilter() {
- public boolean accept(File f) {
- return f != null && !f.isDirectory();
- }
- });
- if (javafiles.length > 0) {
- pkgnames.add(pkgOrClass);
- }
- boolean addedPkg = false;
- for (int j = 0; j < javafiles.length; j++) {
- if (maybeAdd(javafiles[j], pkgSrcfilenames) && !addedPkg) {
- addPkg(pkgOrClass, javafiles[j]);
- addedPkg = true;
- }
- }
- break;
- } else {
- String pkgname = "";
- String classname = pkgOrClass;
- int ilastdot = pkgOrClass.lastIndexOf('.');
- if (ilastdot != -1) {
- pkgname = pkgOrClass.substring(0, ilastdot).
- replace('.', File.separatorChar) + File.separatorChar;
- classname = pkgOrClass.substring(ilastdot+1);
- }
- File file = new File(sourcepath,
- pkgname + classname + ".java");
- if (maybeAdd(file, clsSrcfilenames)) {
- addClass(pkgOrClass, file);
- break;
- }
- }
- }
- }
-
- protected final File findFile(String filename, boolean isDir) {
- for (Iterator i = sourcepaths.iterator(); i.hasNext();) {
- File sourcepath = (File)i.next();
- File file = new File(sourcepath, filename);
- if (file.exists() && !(isDir ^ file.isDirectory())) {
- return file;
- }
- }
- return null;
- }
-
- protected static boolean maybeAddPkg(String pkgname,
- Collection pkgnames) {
- if (isValidPkg(pkgname)) {
- pkgnames.add(pkgname);
- return true;
- }
- return false;
- }
-
- protected final Map filesToClassnames = new HashMap();
- protected final void addClass(String classname, File file) {
- if (!(maybeAddClass(classname))) {
- err().error("invalid_class_name", classname);
- } else {
- filesToClassnames.put(file.getAbsoluteFile(), classname);
- }
- }
-
- protected final boolean maybeAddClass(String classname) {
- return maybeAddClass(classname, classnames);
- }
-
- protected static boolean maybeAddClass(String classname,
- Collection classnames) {
- if (isValidClass(classname)) {
- classnames.add(classname);
- return true;
- }
- return false;
- }
-
- protected final static boolean isValidClass(String classname) {
- return isValidPkg(classname);
- }
-
- protected final Map filesToPkgnames = new HashMap();
- protected final void addPkg(String pkgname, File file) {
- if (!maybeAddPkg(pkgname)) {
- err().error("invalid_package_name", pkgname);
- } else {
- filesToPkgnames.put(file.getAbsoluteFile(), pkgname);
- }
- }
-
- protected final boolean maybeAddPkg(String pkgname) {
- return maybeAddPkg(pkgname, pkgnames);
- }
-
- protected final Map filesToFilenames = new HashMap();
- protected final void addFile(File file) {
- files.add(file);
- filesToFilenames.put(file.getAbsoluteFile(), file.getAbsolutePath());
- }
-
- protected static boolean maybeAdd(File file, Collection files) {
- if (isValidJavaFile(file)) {
- files.add(file.getAbsolutePath());
- return true;
- }
- return false;
- }
-
- protected final static boolean isValidJavaFile(File file) {
- return file != null && file.exists() && !file.isDirectory()
- && (file.getName().endsWith(".java")
- || file.getName().endsWith(".aj")) ;
- }
-
- protected final static boolean isValidPkg(String pkgname) {
- if (pkgname == null) {
- return false;
- }
- if (pkgname.length() < 1) {
- return true;
- }
- if (!Character.isJavaIdentifierStart(pkgname.charAt(0))) {
- return false;
- }
- for (int i = 1; i < pkgname.length(); i++) {
- char c = pkgname.charAt(i);
- if (c == '.' && i == pkgname.length()-1) {
- return false;
- }
- if (!(c == '.' || Character.isJavaIdentifierPart(c))) {
- return false;
- }
- }
- return true;
- }
-
- protected void loading(CompilationUnit cu) {
- File srcfile = cu.getSourceFile().getAbsoluteFile();
- String pkgname, classname, filename;
- if ((pkgname = (String)filesToPkgnames.get(srcfile))!= null) {
- AjdocCompiler.this.err().notice
- ("Loading_source_files_for_package", pkgname);
- } else if ((classname = (String)filesToClassnames.get(srcfile)) != null) {
- AjdocCompiler.this.err().notice
- ("Loading_source_file_for_class", classname);
- } else if ((filename = (String)filesToFilenames.get(srcfile)) != null) {
- AjdocCompiler.this.err().notice
- ("Loading_source_file", filename);
- }
- }
-
- protected AbstractCompilerPass createParserPass() {
- return new PrintingParserPass(this);
- }
-
- protected static class PrintingParserPass extends AspectJCompiler.ParserPass {
- public PrintingParserPass(AjdocCompiler jc) { super(jc); }
- public void transform(CompilationUnit cu) {
- ((AjdocCompiler)getCompiler()).loading(cu);
- super.transform(cu);
- }
- }
-
- protected void addPasses() {
- passes = new ArrayList();
- addPreSymbolPasses();
- }
- }
|