mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 10:34:38 +02:00
Initial load
This commit is contained in:
parent
686d76f772
commit
f57b87e8f6
2973 changed files with 295817 additions and 0 deletions
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
* Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javadoc;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.comp.*;
|
||||
import com.sun.tools.javac.jvm.ClassReader;
|
||||
import com.sun.tools.javac.jvm.ClassWriter;
|
||||
import com.sun.tools.javac.parser.DocCommentScanner;
|
||||
import com.sun.tools.javac.util.Paths;
|
||||
import com.sun.tools.javac.tree.*;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
|
||||
import com.sun.javadoc.LanguageVersion;
|
||||
import static com.sun.javadoc.LanguageVersion.*;
|
||||
|
||||
/**
|
||||
* This class could be the main entry point for Javadoc when Javadoc is used as a
|
||||
* component in a larger software system. It provides operations to
|
||||
* construct a new javadoc processor, and to run it on a set of source
|
||||
* files.
|
||||
* @author Neal Gafter
|
||||
*/
|
||||
public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
|
||||
DocEnv docenv;
|
||||
|
||||
final Context context;
|
||||
final Messager messager;
|
||||
final JavadocClassReader reader;
|
||||
final JavadocEnter enter;
|
||||
final Annotate annotate;
|
||||
private final Paths paths;
|
||||
|
||||
/**
|
||||
* Construct a new JavaCompiler processor, using appropriately
|
||||
* extended phases of the underlying compiler.
|
||||
*/
|
||||
protected JavadocTool(Context context) {
|
||||
super(context);
|
||||
this.context = context;
|
||||
messager = Messager.instance0(context);
|
||||
reader = JavadocClassReader.instance0(context);
|
||||
enter = JavadocEnter.instance0(context);
|
||||
annotate = Annotate.instance(context);
|
||||
paths = Paths.instance(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* For javadoc, the parser needs to keep comments. Overrides method from JavaCompiler.
|
||||
*/
|
||||
protected boolean keepComments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new javadoc tool.
|
||||
*/
|
||||
public static JavadocTool make0(Context context) {
|
||||
Messager messager = null;
|
||||
try {
|
||||
// force the use of Javadoc's class reader
|
||||
JavadocClassReader.preRegister(context);
|
||||
|
||||
// force the use of Javadoc's own enter phase
|
||||
JavadocEnter.preRegister(context);
|
||||
|
||||
// force the use of Javadoc's own member enter phase
|
||||
JavadocMemberEnter.preRegister(context);
|
||||
|
||||
// force the use of Javadoc's own todo phase
|
||||
JavadocTodo.preRegister(context);
|
||||
|
||||
// force the use of Messager as a Log
|
||||
messager = Messager.instance0(context);
|
||||
|
||||
// force the use of the scanner that captures Javadoc comments
|
||||
DocCommentScanner.Factory.preRegister(context);
|
||||
|
||||
return new JavadocTool(context);
|
||||
} catch (CompletionFailure ex) {
|
||||
messager.error(Position.NOPOS, ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public RootDocImpl getRootDocImpl(String doclocale,
|
||||
String encoding,
|
||||
ModifierFilter filter,
|
||||
List<String> javaNames,
|
||||
List<String[]> options,
|
||||
boolean breakiterator,
|
||||
List<String> subPackages,
|
||||
List<String> excludedPackages,
|
||||
boolean docClasses,
|
||||
boolean legacyDoclet,
|
||||
boolean quiet) throws IOException {
|
||||
docenv = DocEnv.instance(context);
|
||||
docenv.showAccess = filter;
|
||||
docenv.quiet = quiet;
|
||||
docenv.breakiterator = breakiterator;
|
||||
docenv.setLocale(doclocale);
|
||||
docenv.setEncoding(encoding);
|
||||
docenv.docClasses = docClasses;
|
||||
docenv.legacyDoclet = legacyDoclet;
|
||||
reader.sourceCompleter = docClasses ? null : this;
|
||||
|
||||
ListBuffer<String> names = new ListBuffer<String>();
|
||||
ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<JCCompilationUnit>();
|
||||
ListBuffer<JCCompilationUnit> packTrees = new ListBuffer<JCCompilationUnit>();
|
||||
|
||||
try {
|
||||
for (List<String> it = javaNames; it.nonEmpty(); it = it.tail) {
|
||||
String name = it.head;
|
||||
if (!docClasses && name.endsWith(".java") && new File(name).exists()) {
|
||||
docenv.notice("main.Loading_source_file", name);
|
||||
JCCompilationUnit tree = parse(name);
|
||||
classTrees.append(tree);
|
||||
} else if (isValidPackageName(name)) {
|
||||
names = names.append(name);
|
||||
} else if (name.endsWith(".java")) {
|
||||
docenv.error(null, "main.file_not_found", name);;
|
||||
} else {
|
||||
docenv.error(null, "main.illegal_package_name", name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!docClasses) {
|
||||
// Recursively search given subpackages. If any packages
|
||||
//are found, add them to the list.
|
||||
searchSubPackages(subPackages, names, excludedPackages);
|
||||
|
||||
// Parse the packages
|
||||
for (List<String> packs = names.toList(); packs.nonEmpty(); packs = packs.tail) {
|
||||
// Parse sources ostensibly belonging to package.
|
||||
parsePackageClasses(packs.head, packTrees, excludedPackages);
|
||||
}
|
||||
|
||||
if (messager.nerrors() != 0) return null;
|
||||
|
||||
// Enter symbols for all files
|
||||
docenv.notice("main.Building_tree");
|
||||
enter.main(classTrees.toList().appendList(packTrees.toList()));
|
||||
}
|
||||
} catch (Abort ex) {}
|
||||
|
||||
if (messager.nerrors() != 0) return null;
|
||||
|
||||
if (docClasses)
|
||||
return new RootDocImpl(docenv, javaNames, options);
|
||||
else
|
||||
return new RootDocImpl(docenv, listClasses(classTrees.toList()), names.toList(), options);
|
||||
}
|
||||
|
||||
/** Is the given string a valid package name? */
|
||||
boolean isValidPackageName(String s) {
|
||||
int index;
|
||||
while ((index = s.indexOf('.')) != -1) {
|
||||
if (!isValidClassName(s.substring(0, index))) return false;
|
||||
s = s.substring(index+1);
|
||||
}
|
||||
return isValidClassName(s);
|
||||
}
|
||||
|
||||
|
||||
private final static char pathSep = File.pathSeparatorChar;
|
||||
|
||||
/**
|
||||
* search all directories in path for subdirectory name. Add all
|
||||
* .java files found in such a directory to args.
|
||||
*/
|
||||
private void parsePackageClasses(String name,
|
||||
ListBuffer<JCCompilationUnit> trees,
|
||||
List<String> excludedPackages)
|
||||
throws IOException {
|
||||
if (excludedPackages.contains(name)) {
|
||||
return;
|
||||
}
|
||||
boolean hasFiles = false;
|
||||
docenv.notice("main.Loading_source_files_for_package", name);
|
||||
name = name.replace('.', File.separatorChar);
|
||||
for (File pathname : paths.sourceSearchPath()) {
|
||||
File f = new File(pathname, name);
|
||||
String names[] = f.list();
|
||||
// if names not null, then found directory with source files
|
||||
if (names != null) {
|
||||
String dir = f.getAbsolutePath();
|
||||
if (!dir.endsWith(File.separator))
|
||||
dir = dir + File.separator;
|
||||
for (int j = 0; j < names.length; j++) {
|
||||
if (isValidJavaSourceFile(names[j])) {
|
||||
String fn = dir + names[j];
|
||||
// messager.notice("main.Loading_source_file", fn);
|
||||
trees.append(parse(fn));
|
||||
hasFiles = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasFiles)
|
||||
messager.warning(null, "main.no_source_files_for_package",
|
||||
name.replace(File.separatorChar, '.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively search all directories in path for subdirectory name.
|
||||
* Add all packages found in such a directory to packages list.
|
||||
*/
|
||||
private void searchSubPackages(List<String> subPackages,
|
||||
ListBuffer<String> packages,
|
||||
List<String> excludedPackages) {
|
||||
// FIXME: This search path is bogus.
|
||||
// Only the effective source path should be searched for sources.
|
||||
// Only the effective class path should be searched for classes.
|
||||
// Should the bootclasspath/extdirs also be searched for classes?
|
||||
java.util.List<File> pathnames = new java.util.ArrayList<File>();
|
||||
if (paths.sourcePath() != null)
|
||||
for (File elt : paths.sourcePath())
|
||||
pathnames.add(elt);
|
||||
for (File elt : paths.userClassPath())
|
||||
pathnames.add(elt);
|
||||
|
||||
for (String subPackage : subPackages)
|
||||
searchSubPackage(subPackage, packages, excludedPackages, pathnames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively search all directories in path for subdirectory name.
|
||||
* Add all packages found in such a directory to packages list.
|
||||
*/
|
||||
private void searchSubPackage(String packageName,
|
||||
ListBuffer<String> packages,
|
||||
List<String> excludedPackages,
|
||||
Collection<File> pathnames) {
|
||||
if (excludedPackages.contains(packageName))
|
||||
return;
|
||||
|
||||
String packageFilename = packageName.replace('.', File.separatorChar);
|
||||
boolean addedPackage = false;
|
||||
for (File pathname : pathnames) {
|
||||
File f = new File(pathname, packageFilename);
|
||||
String filenames[] = f.list();
|
||||
// if filenames not null, then found directory
|
||||
if (filenames != null) {
|
||||
for (String filename : filenames) {
|
||||
if (!addedPackage
|
||||
&& (isValidJavaSourceFile(filename) ||
|
||||
isValidJavaClassFile(filename))
|
||||
&& !packages.contains(packageName)) {
|
||||
packages.append(packageName);
|
||||
addedPackage = true;
|
||||
} else if (isValidClassName(filename) &&
|
||||
(new File(f, filename)).isDirectory()) {
|
||||
searchSubPackage(packageName + "." + filename,
|
||||
packages, excludedPackages, pathnames);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if given file name is a valid class file name.
|
||||
* @param file the name of the file to check.
|
||||
* @return true if given file name is a valid class file name
|
||||
* and false otherwise.
|
||||
*/
|
||||
private static boolean isValidJavaClassFile(String file) {
|
||||
if (!file.endsWith(".class")) return false;
|
||||
String clazzName = file.substring(0, file.length() - ".class".length());
|
||||
return isValidClassName(clazzName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if given file name is a valid Java source file name.
|
||||
* @param file the name of the file to check.
|
||||
* @return true if given file name is a valid Java source file name
|
||||
* and false otherwise.
|
||||
*/
|
||||
private static boolean isValidJavaSourceFile(String file) {
|
||||
if (!file.endsWith(".java")) return false;
|
||||
String clazzName = file.substring(0, file.length() - ".java".length());
|
||||
return isValidClassName(clazzName);
|
||||
}
|
||||
|
||||
/** Are surrogates supported?
|
||||
*/
|
||||
final static boolean surrogatesSupported = surrogatesSupported();
|
||||
private static boolean surrogatesSupported() {
|
||||
try {
|
||||
boolean b = Character.isHighSurrogate('a');
|
||||
return true;
|
||||
} catch (NoSuchMethodError ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if given file name is a valid class name
|
||||
* (including "package-info").
|
||||
* @param clazzname the name of the class to check.
|
||||
* @return true if given class name is a valid class name
|
||||
* and false otherwise.
|
||||
*/
|
||||
public static boolean isValidClassName(String s) {
|
||||
if (s.length() < 1) return false;
|
||||
if (s.equals("package-info")) return true;
|
||||
if (surrogatesSupported) {
|
||||
int cp = s.codePointAt(0);
|
||||
if (!Character.isJavaIdentifierStart(cp))
|
||||
return false;
|
||||
for (int j=Character.charCount(cp); j<s.length(); j+=Character.charCount(cp)) {
|
||||
cp = s.codePointAt(j);
|
||||
if (!Character.isJavaIdentifierPart(cp))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!Character.isJavaIdentifierStart(s.charAt(0)))
|
||||
return false;
|
||||
for (int j=1; j<s.length(); j++)
|
||||
if (!Character.isJavaIdentifierPart(s.charAt(j)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* From a list of top level trees, return the list of contained class definitions
|
||||
*/
|
||||
List<JCClassDecl> listClasses(List<JCCompilationUnit> trees) {
|
||||
ListBuffer<JCClassDecl> result = new ListBuffer<JCClassDecl>();
|
||||
for (JCCompilationUnit t : trees) {
|
||||
for (JCTree def : t.defs) {
|
||||
if (def.getTag() == JCTree.CLASSDEF)
|
||||
result.append((JCClassDecl)def);
|
||||
}
|
||||
}
|
||||
return result.toList();
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue