8041422: Split javac ClassReader into ClassReader+ClassFinder

Reviewed-by: jfranck
This commit is contained in:
Jonathan Gibbons 2014-05-18 19:59:10 -07:00
parent 911a9fcf97
commit 31e6340f54
19 changed files with 696 additions and 568 deletions

View file

@ -0,0 +1,537 @@
/*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.code;
import java.io.*;
import java.util.EnumSet;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.StandardJavaFileManager;
import static javax.tools.StandardLocation.*;
import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.jvm.ClassReader;
import com.sun.tools.javac.util.*;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.main.Option.*;
/**
* This class provides operations to locate class definitions
* from the source and class files on the paths provided to javac.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class ClassFinder {
/** The context key for the class finder. */
protected static final Context.Key<ClassFinder> classFinderKey = new Context.Key<>();
ClassReader reader;
Annotate annotate;
/** Switch: verbose output.
*/
boolean verbose;
/**
* Switch: cache completion failures unless -XDdev is used
*/
private boolean cacheCompletionFailure;
/**
* Switch: prefer source files instead of newer when both source
* and class are available
**/
protected boolean preferSource;
/**
* Switch: Search classpath and sourcepath for classes before the
* bootclasspath
*/
protected boolean userPathsFirst;
/** The log to use for verbose output
*/
final Log log;
/** The symbol table. */
Symtab syms;
/** The name table. */
final Names names;
/** Force a completion failure on this name
*/
final Name completionFailureName;
/** Access to files
*/
private final JavaFileManager fileManager;
/** Factory for diagnostics
*/
JCDiagnostic.Factory diagFactory;
/** Can be reassigned from outside:
* the completer to be used for ".java" files. If this remains unassigned
* ".java" files will not be loaded.
*/
public Completer sourceCompleter = null;
/** The path name of the class file currently being read.
*/
protected JavaFileObject currentClassFile = null;
/** The class or method currently being read.
*/
protected Symbol currentOwner = null;
/**
* Completer that delegates to the complete-method of this class.
*/
private final Completer thisCompleter = new Completer() {
@Override
public void complete(Symbol sym) throws CompletionFailure {
ClassFinder.this.complete(sym);
}
};
public Completer getCompleter() {
return thisCompleter;
}
/** Get the ClassFinder instance for this invocation. */
public static ClassFinder instance(Context context) {
ClassFinder instance = context.get(classFinderKey);
if (instance == null)
instance = new ClassFinder(context);
return instance;
}
/** Construct a new class reader. */
protected ClassFinder(Context context) {
context.put(classFinderKey, this);
reader = ClassReader.instance(context);
names = Names.instance(context);
syms = Symtab.instance(context);
fileManager = context.get(JavaFileManager.class);
if (fileManager == null)
throw new AssertionError("FileManager initialization error");
diagFactory = JCDiagnostic.Factory.instance(context);
log = Log.instance(context);
annotate = Annotate.instance(context);
Options options = Options.instance(context);
verbose = options.isSet(VERBOSE);
cacheCompletionFailure = options.isUnset("dev");
preferSource = "source".equals(options.get("-Xprefer"));
userPathsFirst = options.isSet(XXUSERPATHSFIRST);
completionFailureName =
options.isSet("failcomplete")
? names.fromString(options.get("failcomplete"))
: null;
}
/************************************************************************
* Loading Classes
***********************************************************************/
/** Completion for classes to be loaded. Before a class is loaded
* we make sure its enclosing class (if any) is loaded.
*/
private void complete(Symbol sym) throws CompletionFailure {
if (sym.kind == TYP) {
ClassSymbol c = (ClassSymbol)sym;
c.members_field = new Scope.ErrorScope(c); // make sure it's always defined
annotate.enterStart();
try {
completeOwners(c.owner);
completeEnclosing(c);
} finally {
// The flush needs to happen only after annotations
// are filled in.
annotate.enterDoneWithoutFlush();
}
fillIn(c);
} else if (sym.kind == PCK) {
PackageSymbol p = (PackageSymbol)sym;
try {
fillIn(p);
} catch (IOException ex) {
throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex);
}
}
if (!reader.filling)
annotate.flush(); // finish attaching annotations
}
/** complete up through the enclosing package. */
private void completeOwners(Symbol o) {
if (o.kind != PCK) completeOwners(o.owner);
o.complete();
}
/**
* Tries to complete lexically enclosing classes if c looks like a
* nested class. This is similar to completeOwners but handles
* the situation when a nested class is accessed directly as it is
* possible with the Tree API or javax.lang.model.*.
*/
private void completeEnclosing(ClassSymbol c) {
if (c.owner.kind == PCK) {
Symbol owner = c.owner;
for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) {
Symbol encl = owner.members().lookup(name).sym;
if (encl == null)
encl = syms.classes.get(TypeSymbol.formFlatName(name, owner));
if (encl != null)
encl.complete();
}
}
}
/** Fill in definition of class `c' from corresponding class or
* source file.
*/
private void fillIn(ClassSymbol c) {
if (completionFailureName == c.fullname) {
throw new CompletionFailure(c, "user-selected completion failure by class name");
}
currentOwner = c;
JavaFileObject classfile = c.classfile;
if (classfile != null) {
JavaFileObject previousClassFile = currentClassFile;
try {
if (reader.filling) {
Assert.error("Filling " + classfile.toUri() + " during " + previousClassFile);
}
currentClassFile = classfile;
if (verbose) {
log.printVerbose("loading", currentClassFile.toString());
}
if (classfile.getKind() == JavaFileObject.Kind.CLASS) {
reader.readClassFile(c);
} else {
if (sourceCompleter != null) {
sourceCompleter.complete(c);
} else {
throw new IllegalStateException("Source completer required to read "
+ classfile.toUri());
}
}
return;
} finally {
currentClassFile = previousClassFile;
}
} else {
JCDiagnostic diag =
diagFactory.fragment("class.file.not.found", c.flatname);
throw
newCompletionFailure(c, diag);
}
}
// where
/** Static factory for CompletionFailure objects.
* In practice, only one can be used at a time, so we share one
* to reduce the expense of allocating new exception objects.
*/
private CompletionFailure newCompletionFailure(TypeSymbol c,
JCDiagnostic diag) {
if (!cacheCompletionFailure) {
// log.warning("proc.messager",
// Log.getLocalizedString("class.file.not.found", c.flatname));
// c.debug.printStackTrace();
return new CompletionFailure(c, diag);
} else {
CompletionFailure result = cachedCompletionFailure;
result.sym = c;
result.diag = diag;
return result;
}
}
private CompletionFailure cachedCompletionFailure =
new CompletionFailure(null, (JCDiagnostic) null);
{
cachedCompletionFailure.setStackTrace(new StackTraceElement[0]);
}
/** Load a toplevel class with given fully qualified name
* The class is entered into `classes' only if load was successful.
*/
public ClassSymbol loadClass(Name flatname) throws CompletionFailure {
boolean absent = syms.classes.get(flatname) == null;
ClassSymbol c = syms.enterClass(flatname);
if (c.members_field == null && c.completer != null) {
try {
c.complete();
} catch (CompletionFailure ex) {
if (absent) syms.classes.remove(flatname);
throw ex;
}
}
return c;
}
/************************************************************************
* Loading Packages
***********************************************************************/
/** Include class corresponding to given class file in package,
* unless (1) we already have one the same kind (.class or .java), or
* (2) we have one of the other kind, and the given class file
* is older.
*/
protected void includeClassFile(PackageSymbol p, JavaFileObject file) {
if ((p.flags_field & EXISTS) == 0)
for (Symbol q = p; q != null && q.kind == PCK; q = q.owner)
q.flags_field |= EXISTS;
JavaFileObject.Kind kind = file.getKind();
int seen;
if (kind == JavaFileObject.Kind.CLASS)
seen = CLASS_SEEN;
else
seen = SOURCE_SEEN;
String binaryName = fileManager.inferBinaryName(currentLoc, file);
int lastDot = binaryName.lastIndexOf(".");
Name classname = names.fromString(binaryName.substring(lastDot + 1));
boolean isPkgInfo = classname == names.package_info;
ClassSymbol c = isPkgInfo
? p.package_info
: (ClassSymbol) p.members_field.lookup(classname).sym;
if (c == null) {
c = syms.enterClass(classname, p);
if (c.classfile == null) // only update the file if's it's newly created
c.classfile = file;
if (isPkgInfo) {
p.package_info = c;
} else {
if (c.owner == p) // it might be an inner class
p.members_field.enter(c);
}
} else if (!preferCurrent && c.classfile != null && (c.flags_field & seen) == 0) {
// if c.classfile == null, we are currently compiling this class
// and no further action is necessary.
// if (c.flags_field & seen) != 0, we have already encountered
// a file of the same kind; again no further action is necessary.
if ((c.flags_field & (CLASS_SEEN | SOURCE_SEEN)) != 0)
c.classfile = preferredFileObject(file, c.classfile);
}
c.flags_field |= seen;
}
/** Implement policy to choose to derive information from a source
* file or a class file when both are present. May be overridden
* by subclasses.
*/
protected JavaFileObject preferredFileObject(JavaFileObject a,
JavaFileObject b) {
if (preferSource)
return (a.getKind() == JavaFileObject.Kind.SOURCE) ? a : b;
else {
long adate = a.getLastModified();
long bdate = b.getLastModified();
// 6449326: policy for bad lastModifiedTime in ClassReader
//assert adate >= 0 && bdate >= 0;
return (adate > bdate) ? a : b;
}
}
/**
* specifies types of files to be read when filling in a package symbol
*/
protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() {
return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE);
}
/**
* this is used to support javadoc
*/
protected void extraFileActions(PackageSymbol pack, JavaFileObject fe) {
}
protected Location currentLoc; // FIXME
private boolean verbosePath = true;
// Set to true when the currently selected file should be kept
private boolean preferCurrent;
/** Load directory of package into members scope.
*/
private void fillIn(PackageSymbol p) throws IOException {
if (p.members_field == null)
p.members_field = new Scope(p);
preferCurrent = false;
if (userPathsFirst) {
scanUserPaths(p);
preferCurrent = true;
scanPlatformPath(p);
} else {
scanPlatformPath(p);
scanUserPaths(p);
}
verbosePath = false;
}
/**
* Scans class path and source path for files in given package.
*/
private void scanUserPaths(PackageSymbol p) throws IOException {
Set<JavaFileObject.Kind> kinds = getPackageFileKinds();
Set<JavaFileObject.Kind> classKinds = EnumSet.copyOf(kinds);
classKinds.remove(JavaFileObject.Kind.SOURCE);
boolean wantClassFiles = !classKinds.isEmpty();
Set<JavaFileObject.Kind> sourceKinds = EnumSet.copyOf(kinds);
sourceKinds.remove(JavaFileObject.Kind.CLASS);
boolean wantSourceFiles = !sourceKinds.isEmpty();
boolean haveSourcePath = fileManager.hasLocation(SOURCE_PATH);
if (verbose && verbosePath) {
if (fileManager instanceof StandardJavaFileManager) {
StandardJavaFileManager fm = (StandardJavaFileManager)fileManager;
if (haveSourcePath && wantSourceFiles) {
List<File> path = List.nil();
for (File file : fm.getLocation(SOURCE_PATH)) {
path = path.prepend(file);
}
log.printVerbose("sourcepath", path.reverse().toString());
} else if (wantSourceFiles) {
List<File> path = List.nil();
for (File file : fm.getLocation(CLASS_PATH)) {
path = path.prepend(file);
}
log.printVerbose("sourcepath", path.reverse().toString());
}
if (wantClassFiles) {
List<File> path = List.nil();
for (File file : fm.getLocation(PLATFORM_CLASS_PATH)) {
path = path.prepend(file);
}
for (File file : fm.getLocation(CLASS_PATH)) {
path = path.prepend(file);
}
log.printVerbose("classpath", path.reverse().toString());
}
}
}
String packageName = p.fullname.toString();
if (wantSourceFiles && !haveSourcePath) {
fillIn(p, CLASS_PATH,
fileManager.list(CLASS_PATH,
packageName,
kinds,
false));
} else {
if (wantClassFiles)
fillIn(p, CLASS_PATH,
fileManager.list(CLASS_PATH,
packageName,
classKinds,
false));
if (wantSourceFiles)
fillIn(p, SOURCE_PATH,
fileManager.list(SOURCE_PATH,
packageName,
sourceKinds,
false));
}
}
/**
* Scans platform class path for files in given package.
*/
private void scanPlatformPath(PackageSymbol p) throws IOException {
fillIn(p, PLATFORM_CLASS_PATH,
fileManager.list(PLATFORM_CLASS_PATH,
p.fullname.toString(),
EnumSet.of(JavaFileObject.Kind.CLASS),
false));
}
// where
private void fillIn(PackageSymbol p,
Location location,
Iterable<JavaFileObject> files)
{
currentLoc = location;
for (JavaFileObject fo : files) {
switch (fo.getKind()) {
case CLASS:
case SOURCE: {
// TODO pass binaryName to includeClassFile
String binaryName = fileManager.inferBinaryName(currentLoc, fo);
String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1);
if (SourceVersion.isIdentifier(simpleName) ||
simpleName.equals("package-info"))
includeClassFile(p, fo);
break;
}
default:
extraFileActions(p, fo);
}
}
}
/**
* Used for bad class definition files, such as bad .class files or
* for .java files with unexpected package or class names.
*/
public static class BadClassFile extends CompletionFailure {
private static final long serialVersionUID = 0;
public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag,
JCDiagnostic.Factory diagFactory) {
super(sym, createBadClassFileDiagnostic(file, diag, diagFactory));
}
// where
private static JCDiagnostic createBadClassFileDiagnostic(
JavaFileObject file, JCDiagnostic diag, JCDiagnostic.Factory diagFactory) {
String key = (file.getKind() == JavaFileObject.Kind.SOURCE
? "bad.source.file.header" : "bad.class.file.header");
return diagFactory.fragment(key, file, diag);
}
}
}

View file

@ -50,7 +50,6 @@ import com.sun.tools.javac.code.Type.JCVoidType;
import com.sun.tools.javac.code.Type.MethodType;
import com.sun.tools.javac.code.Type.UnknownType;
import com.sun.tools.javac.jvm.ByteCodes;
import com.sun.tools.javac.jvm.ClassReader;
import com.sun.tools.javac.jvm.Target;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
@ -470,8 +469,8 @@ public class Symtab {
Scope scope = new Scope(predefClass);
predefClass.members_field = scope;
// Get the initial completer for Symbols from the ClassReader
initialCompleter = ClassReader.instance(context).getCompleter();
// Get the initial completer for Symbols from the ClassFinder
initialCompleter = ClassFinder.instance(context).getCompleter();
rootPackage.completer = initialCompleter;
unnamedPackage.completer = initialCompleter;

View file

@ -42,9 +42,8 @@ import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.jvm.ClassReader;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.*;
import static com.sun.tools.javac.code.BoundKind.*;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Scope.*;
@ -84,7 +83,6 @@ public class Types {
final boolean allowBoxing;
final boolean allowCovariantReturns;
final boolean allowObjectToPrimitiveCast;
final ClassReader reader;
final Check chk;
final Enter enter;
JCDiagnostic.Factory diags;
@ -110,7 +108,6 @@ public class Types {
allowBoxing = source.allowBoxing();
allowCovariantReturns = source.allowCovariantReturns();
allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
reader = ClassReader.instance(context);
chk = Check.instance(context);
enter = Enter.instance(context);
capturedName = names.fromString("<captured wildcard>");

View file

@ -282,7 +282,7 @@ public class Check {
*/
public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, "cant.access", ex.sym, ex.getDetailValue());
if (ex instanceof ClassReader.BadClassFile
if (ex instanceof ClassFinder.BadClassFile
&& !suppressAbortOnBadClassFile) throw new Abort();
else return syms.errType;
}

View file

@ -96,7 +96,6 @@ public class Enter extends JCTree.Visitor {
Symtab syms;
Check chk;
TreeMaker make;
ClassReader reader;
Annotate annotate;
MemberEnter memberEnter;
Types types;
@ -118,7 +117,6 @@ public class Enter extends JCTree.Visitor {
context.put(enterKey, this);
log = Log.instance(context);
reader = ClassReader.instance(context);
make = TreeMaker.instance(context);
syms = Symtab.instance(context);
chk = Check.instance(context);

View file

@ -67,25 +67,24 @@ public class Lower extends TreeTranslator {
return instance;
}
private Names names;
private Log log;
private Symtab syms;
private Resolve rs;
private Check chk;
private Attr attr;
private final Names names;
private final Log log;
private final Symtab syms;
private final Resolve rs;
private final Check chk;
private final Attr attr;
private TreeMaker make;
private DiagnosticPosition make_pos;
private ClassWriter writer;
private ClassReader reader;
private ConstFold cfolder;
private Target target;
private Source source;
private boolean allowEnums;
private final ClassWriter writer;
private final ConstFold cfolder;
private final Target target;
private final Source source;
private final boolean allowEnums;
private final Name dollarAssertionsDisabled;
private final Name classDollar;
private Types types;
private boolean debugLower;
private PkgInfo pkginfoOpt;
private final Types types;
private final boolean debugLower;
private final PkgInfo pkginfoOpt;
protected Lower(Context context) {
context.put(lowerKey, this);
@ -97,7 +96,6 @@ public class Lower extends TreeTranslator {
attr = Attr.instance(context);
make = TreeMaker.instance(context);
writer = ClassWriter.instance(context);
reader = ClassReader.instance(context);
cfolder = ConstFold.instance(context);
target = Target.instance(context);
source = Source.instance(context);

View file

@ -25,10 +25,7 @@
package com.sun.tools.javac.comp;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.tools.JavaFileObject;
@ -49,6 +46,7 @@ import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.code.TypeTag.ERROR;
import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@ -75,7 +73,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
private final Attr attr;
private final Symtab syms;
private final TreeMaker make;
private final ClassReader reader;
private final Todo todo;
private final Annotate annotate;
private final TypeAnnotations typeAnnotations;
@ -102,7 +99,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
attr = Attr.instance(context);
syms = Symtab.instance(context);
make = TreeMaker.instance(context);
reader = ClassReader.instance(context);
todo = Todo.instance(context);
annotate = Annotate.instance(context);
typeAnnotations = TypeAnnotations.instance(context);

View file

@ -87,7 +87,7 @@ public class Resolve {
DeferredAttr deferredAttr;
Check chk;
Infer infer;
ClassReader reader;
ClassFinder finder;
TreeInfo treeinfo;
Types types;
JCDiagnostic.Factory diags;
@ -121,7 +121,7 @@ public class Resolve {
deferredAttr = DeferredAttr.instance(context);
chk = Check.instance(context);
infer = Infer.instance(context);
reader = ClassReader.instance(context);
finder = ClassFinder.instance(context);
treeinfo = TreeInfo.instance(context);
types = Types.instance(context);
diags = JCDiagnostic.Factory.instance(context);
@ -1886,9 +1886,9 @@ public class Resolve {
*/
Symbol loadClass(Env<AttrContext> env, Name name) {
try {
ClassSymbol c = reader.loadClass(name);
ClassSymbol c = finder.loadClass(name);
return isAccessible(env, c) ? c : new AccessError(c);
} catch (ClassReader.BadClassFile err) {
} catch (ClassFinder.BadClassFile err) {
throw err;
} catch (CompletionFailure ex) {
return typeNotFound;

View file

@ -35,13 +35,8 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.StandardJavaFileManager;
import static javax.tools.StandardLocation.*;
import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.code.*;
@ -119,23 +114,6 @@ public class ClassReader {
*/
public boolean saveParameterNames;
/**
* Switch: cache completion failures unless -XDdev is used
*/
private boolean cacheCompletionFailure;
/**
* Switch: prefer source files instead of newer when both source
* and class are available
**/
public boolean preferSource;
/**
* Switch: Search classpath and sourcepath for classes before the
* bootclasspath
*/
public boolean userPathsFirst;
/**
* The currently selected profile.
*/
@ -153,10 +131,6 @@ public class ClassReader {
/** The name table. */
final Names names;
/** Force a completion failure on this name
*/
final Name completionFailureName;
/** Access to files
*/
private final JavaFileManager fileManager;
@ -165,12 +139,6 @@ public class ClassReader {
*/
JCDiagnostic.Factory diagFactory;
/** Can be reassigned from outside:
* the completer to be used for ".java" files. If this remains unassigned
* ".java" files will not be loaded.
*/
public SourceCompleter sourceCompleter = null;
/** The current scope where type variables are entered.
*/
protected Scope typevars;
@ -227,20 +195,6 @@ public class ClassReader {
*/
Set<Name> warnedAttrs = new HashSet<>();
/**
* Completer that delegates to the complete-method of this class.
*/
private final Completer thisCompleter = new Completer() {
@Override
public void complete(Symbol sym) throws CompletionFailure {
ClassReader.this.complete(sym);
}
};
public Completer getCompleter() {
return thisCompleter;
}
/** Get the ClassReader instance for this invocation. */
public static ClassReader instance(Context context) {
ClassReader instance = context.get(classReaderKey);
@ -274,17 +228,9 @@ public class ClassReader {
allowSimplifiedVarargs = source.allowSimplifiedVarargs();
saveParameterNames = options.isSet("save-parameter-names");
cacheCompletionFailure = options.isUnset("dev");
preferSource = "source".equals(options.get("-Xprefer"));
userPathsFirst = options.isSet(XXUSERPATHSFIRST);
profile = Profile.instance(context);
completionFailureName =
options.isSet("failcomplete")
? names.fromString(options.get("failcomplete"))
: null;
typevars = new Scope(syms.noSymbol);
lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
@ -305,26 +251,12 @@ public class ClassReader {
* Error Diagnoses
***********************************************************************/
public class BadClassFile extends CompletionFailure {
private static final long serialVersionUID = 0;
public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag) {
super(sym, createBadClassFileDiagnostic(file, diag));
}
}
// where
private JCDiagnostic createBadClassFileDiagnostic(JavaFileObject file, JCDiagnostic diag) {
String key = (file.getKind() == JavaFileObject.Kind.SOURCE
? "bad.source.file.header" : "bad.class.file.header");
return diagFactory.fragment(key, file, diag);
}
public BadClassFile badClassFile(String key, Object... args) {
return new BadClassFile (
public ClassFinder.BadClassFile badClassFile(String key, Object... args) {
return new ClassFinder.BadClassFile (
currentOwner.enclClass(),
currentClassFile,
diagFactory.fragment(key, args));
diagFactory.fragment(key, args),
diagFactory);
}
/************************************************************************
@ -1501,7 +1433,7 @@ public class ClassReader {
int tag = nextByte(); // TargetType tag is a byte
if (!TargetType.isValidTargetTypeValue(tag))
throw this.badClassFile("bad.type.annotation.value", String.format("0x%02X", tag));
throw badClassFile("bad.type.annotation.value", String.format("0x%02X", tag));
TargetType type = TargetType.fromTargetTypeValue(tag);
@ -2353,9 +2285,9 @@ public class ClassReader {
}
}
/** Read a class file.
/** Read a class definition from the bytes in buf.
*/
private void readClassFile(ClassSymbol c) throws IOException {
private void readClassBuffer(ClassSymbol c) throws IOException {
int magic = nextInt();
if (magic != JAVA_MAGIC)
throw badClassFile("illegal.start.of.class.file");
@ -2395,120 +2327,15 @@ public class ClassReader {
readClass(c);
}
/************************************************************************
* Adjusting flags
***********************************************************************/
long adjustFieldFlags(long flags) {
return flags;
}
long adjustMethodFlags(long flags) {
if ((flags & ACC_BRIDGE) != 0) {
flags &= ~ACC_BRIDGE;
flags |= BRIDGE;
if (!allowGenerics)
flags &= ~SYNTHETIC;
}
if ((flags & ACC_VARARGS) != 0) {
flags &= ~ACC_VARARGS;
flags |= VARARGS;
}
return flags;
}
long adjustClassFlags(long flags) {
return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
}
/************************************************************************
* Loading Classes
***********************************************************************/
/** Completion for classes to be loaded. Before a class is loaded
* we make sure its enclosing class (if any) is loaded.
*/
private void complete(Symbol sym) throws CompletionFailure {
if (sym.kind == TYP) {
ClassSymbol c = (ClassSymbol)sym;
c.members_field = new Scope.ErrorScope(c); // make sure it's always defined
annotate.enterStart();
try {
completeOwners(c.owner);
completeEnclosing(c);
} finally {
// The flush needs to happen only after annotations
// are filled in.
annotate.enterDoneWithoutFlush();
}
fillIn(c);
} else if (sym.kind == PCK) {
PackageSymbol p = (PackageSymbol)sym;
try {
fillIn(p);
} catch (IOException ex) {
throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex);
}
}
if (!filling)
annotate.flush(); // finish attaching annotations
}
/** complete up through the enclosing package. */
private void completeOwners(Symbol o) {
if (o.kind != PCK) completeOwners(o.owner);
o.complete();
}
/**
* Tries to complete lexically enclosing classes if c looks like a
* nested class. This is similar to completeOwners but handles
* the situation when a nested class is accessed directly as it is
* possible with the Tree API or javax.lang.model.*.
*/
private void completeEnclosing(ClassSymbol c) {
if (c.owner.kind == PCK) {
Symbol owner = c.owner;
for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) {
Symbol encl = owner.members().lookup(name).sym;
if (encl == null)
encl = syms.classes.get(TypeSymbol.formFlatName(name, owner));
if (encl != null)
encl.complete();
}
}
}
/** We can only read a single class file at a time; this
* flag keeps track of when we are currently reading a class
* file.
*/
private boolean filling = false;
/** Fill in definition of class `c' from corresponding class or
* source file.
*/
private void fillIn(ClassSymbol c) {
if (completionFailureName == c.fullname) {
throw new CompletionFailure(c, "user-selected completion failure by class name");
}
public void readClassFile(ClassSymbol c) {
currentOwner = c;
currentClassFile = c.classfile;
warnedAttrs.clear();
JavaFileObject classfile = c.classfile;
if (classfile != null) {
JavaFileObject previousClassFile = currentClassFile;
try {
if (filling) {
Assert.error("Filling " + classfile.toUri() + " during " + previousClassFile);
}
currentClassFile = classfile;
if (verbose) {
log.printVerbose("loading", currentClassFile.toString());
}
if (classfile.getKind() == JavaFileObject.Kind.CLASS) {
filling = true;
try {
bp = 0;
buf = readInputStream(buf, classfile.openInputStream());
readClassFile(c);
buf = readInputStream(buf, c.classfile.openInputStream());
readClassBuffer(c);
if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) {
List<Type> missing = missingTypeVariables;
List<Type> found = foundTypeVariables;
@ -2525,32 +2352,14 @@ public class ClassReader {
Name name = missingTypeVariables.head.tsym.name;
throw badClassFile("undecl.type.var", name);
}
} finally {
missingTypeVariables = List.nil();
foundTypeVariables = List.nil();
filling = false;
}
} else {
if (sourceCompleter != null) {
sourceCompleter.complete(c);
} else {
throw new IllegalStateException("Source completer required to read "
+ classfile.toUri());
}
}
return;
} catch (IOException ex) {
throw badClassFile("unable.to.access.file", ex.getMessage());
} catch (ArrayIndexOutOfBoundsException ex) {
throw badClassFile("bad.class.file", c.flatname);
} finally {
currentClassFile = previousClassFile;
}
} else {
JCDiagnostic diag =
diagFactory.fragment("class.file.not.found", c.flatname);
throw
newCompletionFailure(c, diag);
missingTypeVariables = List.nil();
foundTypeVariables = List.nil();
filling = false;
}
}
// where
@ -2590,251 +2399,37 @@ public class ClassReader {
}
return buf;
}
/** Static factory for CompletionFailure objects.
* In practice, only one can be used at a time, so we share one
* to reduce the expense of allocating new exception objects.
*/
private CompletionFailure newCompletionFailure(TypeSymbol c,
JCDiagnostic diag) {
if (!cacheCompletionFailure) {
// log.warning("proc.messager",
// Log.getLocalizedString("class.file.not.found", c.flatname));
// c.debug.printStackTrace();
return new CompletionFailure(c, diag);
} else {
CompletionFailure result = cachedCompletionFailure;
result.sym = c;
result.diag = diag;
return result;
}
}
private CompletionFailure cachedCompletionFailure =
new CompletionFailure(null, (JCDiagnostic) null);
{
cachedCompletionFailure.setStackTrace(new StackTraceElement[0]);
}
/** Load a toplevel class with given fully qualified name
* The class is entered into `classes' only if load was successful.
/** We can only read a single class file at a time; this
* flag keeps track of when we are currently reading a class
* file.
*/
public ClassSymbol loadClass(Name flatname) throws CompletionFailure {
boolean absent = syms.classes.get(flatname) == null;
ClassSymbol c = syms.enterClass(flatname);
if (c.members_field == null && c.completer != null) {
try {
c.complete();
} catch (CompletionFailure ex) {
if (absent) syms.classes.remove(flatname);
throw ex;
}
}
return c;
}
public boolean filling = false;
/************************************************************************
* Loading Packages
* Adjusting flags
***********************************************************************/
/** Include class corresponding to given class file in package,
* unless (1) we already have one the same kind (.class or .java), or
* (2) we have one of the other kind, and the given class file
* is older.
*/
protected void includeClassFile(PackageSymbol p, JavaFileObject file) {
if ((p.flags_field & EXISTS) == 0)
for (Symbol q = p; q != null && q.kind == PCK; q = q.owner)
q.flags_field |= EXISTS;
JavaFileObject.Kind kind = file.getKind();
int seen;
if (kind == JavaFileObject.Kind.CLASS)
seen = CLASS_SEEN;
else
seen = SOURCE_SEEN;
String binaryName = fileManager.inferBinaryName(currentLoc, file);
int lastDot = binaryName.lastIndexOf(".");
Name classname = names.fromString(binaryName.substring(lastDot + 1));
boolean isPkgInfo = classname == names.package_info;
ClassSymbol c = isPkgInfo
? p.package_info
: (ClassSymbol) p.members_field.lookup(classname).sym;
if (c == null) {
c = syms.enterClass(classname, p);
if (c.classfile == null) // only update the file if's it's newly created
c.classfile = file;
if (isPkgInfo) {
p.package_info = c;
} else {
if (c.owner == p) // it might be an inner class
p.members_field.enter(c);
}
} else if (!preferCurrent && c.classfile != null && (c.flags_field & seen) == 0) {
// if c.classfile == null, we are currently compiling this class
// and no further action is necessary.
// if (c.flags_field & seen) != 0, we have already encountered
// a file of the same kind; again no further action is necessary.
if ((c.flags_field & (CLASS_SEEN | SOURCE_SEEN)) != 0)
c.classfile = preferredFileObject(file, c.classfile);
}
c.flags_field |= seen;
long adjustFieldFlags(long flags) {
return flags;
}
/** Implement policy to choose to derive information from a source
* file or a class file when both are present. May be overridden
* by subclasses.
*/
protected JavaFileObject preferredFileObject(JavaFileObject a,
JavaFileObject b) {
if (preferSource)
return (a.getKind() == JavaFileObject.Kind.SOURCE) ? a : b;
else {
long adate = a.getLastModified();
long bdate = b.getLastModified();
// 6449326: policy for bad lastModifiedTime in ClassReader
//assert adate >= 0 && bdate >= 0;
return (adate > bdate) ? a : b;
long adjustMethodFlags(long flags) {
if ((flags & ACC_BRIDGE) != 0) {
flags &= ~ACC_BRIDGE;
flags |= BRIDGE;
if (!allowGenerics)
flags &= ~SYNTHETIC;
}
if ((flags & ACC_VARARGS) != 0) {
flags &= ~ACC_VARARGS;
flags |= VARARGS;
}
return flags;
}
/**
* specifies types of files to be read when filling in a package symbol
*/
protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() {
return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE);
}
/**
* this is used to support javadoc
*/
protected void extraFileActions(PackageSymbol pack, JavaFileObject fe) {
}
protected Location currentLoc; // FIXME
private boolean verbosePath = true;
// Set to true when the currently selected file should be kept
private boolean preferCurrent;
/** Load directory of package into members scope.
*/
private void fillIn(PackageSymbol p) throws IOException {
if (p.members_field == null)
p.members_field = new Scope(p);
preferCurrent = false;
if (userPathsFirst) {
scanUserPaths(p);
preferCurrent = true;
scanPlatformPath(p);
} else {
scanPlatformPath(p);
scanUserPaths(p);
}
verbosePath = false;
}
/**
* Scans class path and source path for files in given package.
*/
private void scanUserPaths(PackageSymbol p) throws IOException {
Set<JavaFileObject.Kind> kinds = getPackageFileKinds();
Set<JavaFileObject.Kind> classKinds = EnumSet.copyOf(kinds);
classKinds.remove(JavaFileObject.Kind.SOURCE);
boolean wantClassFiles = !classKinds.isEmpty();
Set<JavaFileObject.Kind> sourceKinds = EnumSet.copyOf(kinds);
sourceKinds.remove(JavaFileObject.Kind.CLASS);
boolean wantSourceFiles = !sourceKinds.isEmpty();
boolean haveSourcePath = fileManager.hasLocation(SOURCE_PATH);
if (verbose && verbosePath) {
if (fileManager instanceof StandardJavaFileManager) {
StandardJavaFileManager fm = (StandardJavaFileManager)fileManager;
if (haveSourcePath && wantSourceFiles) {
List<File> path = List.nil();
for (File file : fm.getLocation(SOURCE_PATH)) {
path = path.prepend(file);
}
log.printVerbose("sourcepath", path.reverse().toString());
} else if (wantSourceFiles) {
List<File> path = List.nil();
for (File file : fm.getLocation(CLASS_PATH)) {
path = path.prepend(file);
}
log.printVerbose("sourcepath", path.reverse().toString());
}
if (wantClassFiles) {
List<File> path = List.nil();
for (File file : fm.getLocation(PLATFORM_CLASS_PATH)) {
path = path.prepend(file);
}
for (File file : fm.getLocation(CLASS_PATH)) {
path = path.prepend(file);
}
log.printVerbose("classpath", path.reverse().toString());
}
}
}
String packageName = p.fullname.toString();
if (wantSourceFiles && !haveSourcePath) {
fillIn(p, CLASS_PATH,
fileManager.list(CLASS_PATH,
packageName,
kinds,
false));
} else {
if (wantClassFiles)
fillIn(p, CLASS_PATH,
fileManager.list(CLASS_PATH,
packageName,
classKinds,
false));
if (wantSourceFiles)
fillIn(p, SOURCE_PATH,
fileManager.list(SOURCE_PATH,
packageName,
sourceKinds,
false));
}
}
/**
* Scans platform class path for files in given package.
*/
private void scanPlatformPath(PackageSymbol p) throws IOException {
fillIn(p, PLATFORM_CLASS_PATH,
fileManager.list(PLATFORM_CLASS_PATH,
p.fullname.toString(),
EnumSet.of(JavaFileObject.Kind.CLASS),
false));
}
// where
private void fillIn(PackageSymbol p,
Location location,
Iterable<JavaFileObject> files)
{
currentLoc = location;
for (JavaFileObject fo : files) {
switch (fo.getKind()) {
case CLASS:
case SOURCE: {
// TODO pass binaryName to includeClassFile
String binaryName = fileManager.inferBinaryName(currentLoc, fo);
String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1);
if (SourceVersion.isIdentifier(simpleName) ||
simpleName.equals("package-info"))
includeClassFile(p, fo);
break;
}
default:
extraFileActions(p, fo);
}
}
long adjustClassFlags(long flags) {
return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
}
/** Output for "-checkclassfile" option.
@ -2845,12 +2440,6 @@ public class ClassReader {
log.printLines(key, arg);
}
public interface SourceCompleter {
void complete(ClassSymbol sym)
throws CompletionFailure;
}
/**
* A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
* The attribute is only the last component of the original filename, so is unlikely

View file

@ -219,6 +219,10 @@ public class JavaCompiler {
*/
protected TreeMaker make;
/** The class finder.
*/
protected ClassFinder finder;
/** The class reader.
*/
protected ClassReader reader;
@ -296,13 +300,13 @@ public class JavaCompiler {
protected MultiTaskListener taskListener;
/**
* SourceCompleter that delegates to the complete-method of this class.
* SourceCompleter that delegates to the readSourceFile method of this class.
*/
protected final ClassReader.SourceCompleter thisCompleter =
new ClassReader.SourceCompleter() {
protected final Symbol.Completer sourceCompleter =
new Symbol.Completer() {
@Override
public void complete(ClassSymbol sym) throws CompletionFailure {
JavaCompiler.this.complete(sym);
public void complete(Symbol sym) throws CompletionFailure {
readSourceFile((ClassSymbol) sym);
}
};
@ -338,6 +342,7 @@ public class JavaCompiler {
names = Names.instance(context);
log = Log.instance(context);
diagFactory = JCDiagnostic.Factory.instance(context);
finder = ClassFinder.instance(context);
reader = ClassReader.instance(context);
make = TreeMaker.instance(context);
writer = ClassWriter.instance(context);
@ -355,7 +360,7 @@ public class JavaCompiler {
} catch (CompletionFailure ex) {
// inlined Check.completionError as it is not initialized yet
log.error("cant.access", ex.sym, ex.getDetailValue());
if (ex instanceof ClassReader.BadClassFile)
if (ex instanceof ClassFinder.BadClassFile)
throw new Abort();
}
source = Source.instance(context);
@ -370,7 +375,7 @@ public class JavaCompiler {
types = Types.instance(context);
taskListener = MultiTaskListener.instance(context);
reader.sourceCompleter = thisCompleter;
finder.sourceCompleter = sourceCompleter;
options = Options.instance(context);
@ -663,7 +668,7 @@ public class JavaCompiler {
public Symbol resolveBinaryNameOrIdent(String name) {
try {
Name flatname = names.fromString(name.replace("/", "."));
return reader.loadClass(flatname);
return finder.loadClass(flatname);
} catch (CompletionFailure ignore) {
return resolveIdent(name);
}
@ -737,22 +742,20 @@ public class JavaCompiler {
return null;
}
/** Complete compiling a source file that has been accessed
* by the class file reader.
/** Compile a source file that has been accessed by the class finder.
* @param c The class the source file of which needs to be compiled.
*/
public void complete(ClassSymbol c) throws CompletionFailure {
complete(null, c);
private void readSourceFile(ClassSymbol c) throws CompletionFailure {
readSourceFile(null, c);
}
/** Complete a ClassSymbol from source, optionally using the given compilation unit as
/** Compile a ClassSymbol from source, optionally using the given compilation unit as
* the source tree.
* @param tree the compilation unit int which the given ClassSymbol resides,
* @param tree the compilation unit in which the given ClassSymbol resides,
* or null if should be parsed from source
* @param c the ClassSymbol to complete
*/
public void complete(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure {
// System.err.println("completing " + c);//DEBUG
public void readSourceFile(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure {
if (completionFailureName == c.fullname) {
throw new CompletionFailure(c, "user-selected completion failure by class name");
}
@ -791,13 +794,13 @@ public class JavaCompiler {
JCDiagnostic diag =
diagFactory.fragment("file.does.not.contain.package",
c.location());
throw reader.new BadClassFile(c, filename, diag);
throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
}
} else {
JCDiagnostic diag =
diagFactory.fragment("file.doesnt.contain.class",
c.getQualifiedName());
throw reader.new BadClassFile(c, filename, diag);
throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
}
}
@ -1663,6 +1666,7 @@ public class JavaCompiler {
*/
public void close() {
rootClasses = null;
finder = null;
reader = null;
make = null;
writer = null;

View file

@ -54,8 +54,6 @@ import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.jvm.ClassReader.BadClassFile;
import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.model.JavacTypes;
@ -203,7 +201,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
symtab = Symtab.instance(context);
names = Names.instance(context);
enter = Enter.instance(context);
initialCompleter = ClassReader.instance(context).getCompleter();
initialCompleter = ClassFinder.instance(context).getCompleter();
chk = Check.instance(context);
initProcessorClassLoader();
}
@ -799,7 +797,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
RoundEnvironment renv) {
try {
return proc.process(tes, renv);
} catch (BadClassFile ex) {
} catch (ClassFinder.BadClassFile ex) {
log.error("proc.cant.access.1", ex.sym, ex.getDetailValue());
return false;
} catch (CompletionFailure ex) {
@ -1308,7 +1306,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
}
@Override public void complete(Symbol sym) throws CompletionFailure {
compiler.complete(topLevel, (ClassSymbol) sym);
compiler.readSourceFile(topLevel, (ClassSymbol) sym);
}
}

View file

@ -37,11 +37,19 @@ import com.sun.tools.doclint.DocLint;
import com.sun.tools.javac.api.BasicJavacTask;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Names;
@ -71,21 +79,21 @@ public class DocEnv {
return instance;
}
private Messager messager;
DocLocale doclocale;
private final Messager messager;
/** Predefined symbols known to the compiler. */
Symtab syms;
final Symtab syms;
/** Referenced directly in RootDocImpl. */
JavadocClassReader reader;
private final ClassFinder finder;
/** Javadoc's own version of the compiler's enter phase. */
JavadocEnter enter;
final Enter enter;
/** The name table. */
Names names;
private Names names;
/** The encoding name. */
private String encoding;
@ -139,8 +147,8 @@ public class DocEnv {
messager = Messager.instance0(context);
syms = Symtab.instance(context);
reader = JavadocClassReader.instance0(context);
enter = JavadocEnter.instance0(context);
finder = JavadocClassFinder.instance(context);
enter = JavadocEnter.instance(context);
names = Names.instance(context);
externalizableSym = syms.enterClass(names.fromString("java.io.Externalizable"));
chk = Check.instance(context);
@ -176,7 +184,7 @@ public class DocEnv {
*/
public ClassDocImpl loadClass(String name) {
try {
ClassSymbol c = reader.loadClass(names.fromString(name));
ClassSymbol c = finder.loadClass(names.fromString(name));
return getClassDoc(c);
} catch (CompletionFailure ex) {
chk.completionError(null, ex);

View file

@ -29,10 +29,10 @@ import java.util.EnumSet;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.jvm.ClassReader;
import com.sun.tools.javac.code.ClassFinder;
import com.sun.tools.javac.util.Context;
/** Javadoc uses an extended class reader that records package.html entries
/** Javadoc uses an extended class finder that records package.html entries
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
@ -41,19 +41,19 @@ import com.sun.tools.javac.util.Context;
*
* @author Neal Gafter
*/
public class JavadocClassReader extends ClassReader {
public class JavadocClassFinder extends ClassFinder {
public static JavadocClassReader instance0(Context context) {
ClassReader instance = context.get(classReaderKey);
public static JavadocClassFinder instance(Context context) {
ClassFinder instance = context.get(classFinderKey);
if (instance == null)
instance = new JavadocClassReader(context);
return (JavadocClassReader)instance;
instance = new JavadocClassFinder(context);
return (JavadocClassFinder)instance;
}
public static void preRegister(Context context) {
context.put(classReaderKey, new Context.Factory<ClassReader>() {
public ClassReader make(Context c) {
return new JavadocClassReader(c);
context.put(classFinderKey, new Context.Factory<ClassFinder>() {
public ClassFinder make(Context c) {
return new JavadocClassFinder(c);
}
});
}
@ -65,7 +65,7 @@ public class JavadocClassReader extends ClassReader {
private EnumSet<JavaFileObject.Kind> noSource = EnumSet.of(JavaFileObject.Kind.CLASS,
JavaFileObject.Kind.HTML);
public JavadocClassReader(Context context) {
public JavadocClassFinder(Context context) {
super(context);
docenv = DocEnv.instance(context);
preferSource = true;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. 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
@ -48,7 +48,7 @@ import com.sun.tools.javac.util.List;
* @author Neal Gafter
*/
public class JavadocEnter extends Enter {
public static JavadocEnter instance0(Context context) {
public static JavadocEnter instance(Context context) {
Enter instance = context.get(enterKey);
if (instance == null)
instance = new JavadocEnter(context);

View file

@ -33,12 +33,15 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import com.sun.tools.javac.code.ClassFinder;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
@ -66,8 +69,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
DocEnv docenv;
final Messager messager;
final JavadocClassReader javadocReader;
final JavadocEnter javadocEnter;
final ClassFinder javadocFinder;
final Enter javadocEnter;
final Set<JavaFileObject> uniquefiles;
/**
@ -77,8 +80,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
protected JavadocTool(Context context) {
super(context);
messager = Messager.instance0(context);
javadocReader = JavadocClassReader.instance0(context);
javadocEnter = JavadocEnter.instance0(context);
javadocFinder = JavadocClassFinder.instance(context);
javadocEnter = JavadocEnter.instance(context);
uniquefiles = new HashSet<>();
}
@ -95,8 +98,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
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 class finder
JavadocClassFinder.preRegister(context);
// force the use of Javadoc's own enter phase
JavadocEnter.preRegister(context);
@ -137,7 +140,8 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
docenv.setEncoding(encoding);
docenv.docClasses = docClasses;
docenv.legacyDoclet = legacyDoclet;
javadocReader.sourceCompleter = docClasses ? null : thisCompleter;
javadocFinder.sourceCompleter = docClasses ? null : sourceCompleter;
ListBuffer<String> names = new ListBuffer<>();
ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<>();

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2014, Oracle and/or its affiliates. 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
@ -36,7 +36,7 @@ import java.nio.*;
import java.io.*;
import java.nio.channels.*;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.jvm.ClassReader.BadClassFile;
import com.sun.tools.javac.code.ClassFinder.BadClassFile;
import com.sun.tools.javac.main.JavaCompiler;
import javax.tools.ToolProvider;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. 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
@ -129,14 +129,14 @@ public class MethodParametersTest {
if (out.length() > 0)
System.err.println(out);
// Now get the class reader, construct a name for Baz, and load it.
com.sun.tools.javac.jvm.ClassReader cr =
com.sun.tools.javac.jvm.ClassReader.instance(context);
// Now get the class finder, construct a name for Baz, and load it.
com.sun.tools.javac.code.ClassFinder cf =
com.sun.tools.javac.code.ClassFinder.instance(context);
Name name = Names.instance(context).fromString(Baz_name);
// Now walk down the language model and check the name of the
// parameter.
final Element baz = cr.loadClass(name);
final Element baz = cf.loadClass(name);
for (Element e : baz.getEnclosedElements()) {
if (e instanceof ExecutableElement) {
final ExecutableElement ee = (ExecutableElement) e;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2014, Oracle and/or its affiliates. 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
@ -30,7 +30,7 @@
*/
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.jvm.ClassReader.BadClassFile;
import com.sun.tools.javac.code.ClassFinder.BadClassFile;
import com.sun.tools.javac.main.JavaCompiler;
import javax.tools.ToolProvider;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. 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
@ -32,8 +32,8 @@
import com.sun.tools.classfile.*;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.code.ClassFinder.BadClassFile;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.jvm.ClassReader.BadClassFile;
import com.sun.tools.javac.jvm.Target;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.JCDiagnostic;