8041422: Split javac ClassReader into ClassReader+ClassFinder
Reviewed-by: jfranck
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java Sun May 18 19:59:10 2014 -0700
@@ -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);
+ }
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Sun May 18 19:59:10 2014 -0700
@@ -50,7 +50,6 @@
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 @@
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;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Sun May 18 19:59:10 2014 -0700
@@ -42,9 +42,8 @@
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 @@
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 @@
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>");
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Sun May 18 19:59:10 2014 -0700
@@ -282,7 +282,7 @@
*/
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;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Sun May 18 19:59:10 2014 -0700
@@ -96,7 +96,6 @@
Symtab syms;
Check chk;
TreeMaker make;
- ClassReader reader;
Annotate annotate;
MemberEnter memberEnter;
Types types;
@@ -118,7 +117,6 @@
context.put(enterKey, this);
log = Log.instance(context);
- reader = ClassReader.instance(context);
make = TreeMaker.instance(context);
syms = Symtab.instance(context);
chk = Check.instance(context);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Sun May 18 19:59:10 2014 -0700
@@ -67,25 +67,24 @@
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 @@
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);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Sun May 18 19:59:10 2014 -0700
@@ -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.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 @@
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 @@
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);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Sun May 18 19:59:10 2014 -0700
@@ -87,7 +87,7 @@
DeferredAttr deferredAttr;
Check chk;
Infer infer;
- ClassReader reader;
+ ClassFinder finder;
TreeInfo treeinfo;
Types types;
JCDiagnostic.Factory diags;
@@ -121,7 +121,7 @@
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 @@
*/
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;
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Sun May 18 19:59:10 2014 -0700
@@ -35,13 +35,8 @@
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.*;
@@ -120,23 +115,6 @@
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.
*/
public final Profile profile;
@@ -153,10 +131,6 @@
/** 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 @@
*/
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 @@
*/
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 @@
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 @@
* 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 @@
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 @@
}
}
- /** 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,162 +2327,39 @@
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);
+ public void readClassFile(ClassSymbol c) {
+ currentOwner = c;
+ currentClassFile = c.classfile;
+ warnedAttrs.clear();
+ filling = true;
+ try {
+ bp = 0;
+ buf = readInputStream(buf, c.classfile.openInputStream());
+ readClassBuffer(c);
+ if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) {
+ List<Type> missing = missingTypeVariables;
+ List<Type> found = foundTypeVariables;
+ missingTypeVariables = List.nil();
+ foundTypeVariables = List.nil();
+ filling = false;
+ ClassType ct = (ClassType)currentOwner.type;
+ ct.supertype_field =
+ types.subst(ct.supertype_field, missing, found);
+ ct.interfaces_field =
+ types.subst(ct.interfaces_field, missing, found);
+ } else if (missingTypeVariables.isEmpty() !=
+ foundTypeVariables.isEmpty()) {
+ Name name = missingTypeVariables.head.tsym.name;
+ throw badClassFile("undecl.type.var", name);
}
- }
- 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");
- }
- currentOwner = c;
- 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);
- if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) {
- List<Type> missing = missingTypeVariables;
- List<Type> found = foundTypeVariables;
- missingTypeVariables = List.nil();
- foundTypeVariables = List.nil();
- filling = false;
- ClassType ct = (ClassType)currentOwner.type;
- ct.supertype_field =
- types.subst(ct.supertype_field, missing, found);
- ct.interfaces_field =
- types.subst(ct.interfaces_field, missing, found);
- } else if (missingTypeVariables.isEmpty() !=
- foundTypeVariables.isEmpty()) {
- 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);
+ } catch (IOException ex) {
+ throw badClassFile("unable.to.access.file", ex.getMessage());
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ throw badClassFile("bad.class.file", c.flatname);
+ } finally {
+ missingTypeVariables = List.nil();
+ foundTypeVariables = List.nil();
+ filling = false;
}
}
// where
@@ -2590,253 +2399,39 @@
}
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;
- }
-
- /** 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) {
+ long adjustFieldFlags(long flags) {
+ return flags;
}
- 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);
+ long adjustMethodFlags(long flags) {
+ if ((flags & ACC_BRIDGE) != 0) {
+ flags &= ~ACC_BRIDGE;
+ flags |= BRIDGE;
+ if (!allowGenerics)
+ flags &= ~SYNTHETIC;
}
- verbosePath = false;
+ if ((flags & ACC_VARARGS) != 0) {
+ flags &= ~ACC_VARARGS;
+ flags |= VARARGS;
+ }
+ return flags;
}
- /**
- * 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));
- }
+ long adjustClassFlags(long flags) {
+ return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
}
- /**
- * 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);
- }
- }
- }
-
/** Output for "-checkclassfile" option.
* @param key The key to look up the correct internationalized string.
* @param arg An argument for substitution into the output string.
@@ -2845,12 +2440,6 @@
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
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Sun May 18 19:59:10 2014 -0700
@@ -219,6 +219,10 @@
*/
protected TreeMaker make;
+ /** The class finder.
+ */
+ protected ClassFinder finder;
+
/** The class reader.
*/
protected ClassReader reader;
@@ -296,13 +300,13 @@
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 @@
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 @@
} 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 @@
types = Types.instance(context);
taskListener = MultiTaskListener.instance(context);
- reader.sourceCompleter = thisCompleter;
+ finder.sourceCompleter = sourceCompleter;
options = Options.instance(context);
@@ -663,7 +668,7 @@
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 @@
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 @@
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 void close() {
rootClasses = null;
+ finder = null;
reader = null;
make = null;
writer = null;
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Sun May 18 19:59:10 2014 -0700
@@ -54,8 +54,6 @@
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 @@
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 @@
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 @@
}
@Override public void complete(Symbol sym) throws CompletionFailure {
- compiler.complete(topLevel, (ClassSymbol) sym);
+ compiler.readSourceFile(topLevel, (ClassSymbol) sym);
}
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Sun May 18 19:59:10 2014 -0700
@@ -37,11 +37,19 @@
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 @@
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 @@
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 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);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java Sun May 18 19:59:10 2014 -0700
@@ -0,0 +1,90 @@
+/*
+ * 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
+ * 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.javadoc;
+
+import java.util.EnumSet;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
+import com.sun.tools.javac.code.ClassFinder;
+import com.sun.tools.javac.util.Context;
+
+/** 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.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ *
+ * @author Neal Gafter
+ */
+public class JavadocClassFinder extends ClassFinder {
+
+ public static JavadocClassFinder instance(Context context) {
+ ClassFinder instance = context.get(classFinderKey);
+ if (instance == null)
+ instance = new JavadocClassFinder(context);
+ return (JavadocClassFinder)instance;
+ }
+
+ public static void preRegister(Context context) {
+ context.put(classFinderKey, new Context.Factory<ClassFinder>() {
+ public ClassFinder make(Context c) {
+ return new JavadocClassFinder(c);
+ }
+ });
+ }
+
+ private DocEnv docenv;
+ private EnumSet<JavaFileObject.Kind> all = EnumSet.of(JavaFileObject.Kind.CLASS,
+ JavaFileObject.Kind.SOURCE,
+ JavaFileObject.Kind.HTML);
+ private EnumSet<JavaFileObject.Kind> noSource = EnumSet.of(JavaFileObject.Kind.CLASS,
+ JavaFileObject.Kind.HTML);
+
+ public JavadocClassFinder(Context context) {
+ super(context);
+ docenv = DocEnv.instance(context);
+ preferSource = true;
+ }
+
+ /**
+ * Override getPackageFileKinds to include search for package.html
+ */
+ @Override
+ protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() {
+ return docenv.docClasses ? noSource : all;
+ }
+
+ /**
+ * Override extraFileActions to check for package documentation
+ */
+ @Override
+ protected void extraFileActions(PackageSymbol pack, JavaFileObject fo) {
+ if (fo.isNameCompatible("package", JavaFileObject.Kind.HTML))
+ docenv.getPackageDoc(pack).setDocPath(fo);
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java Fri May 16 10:52:07 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * 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
- * 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.javadoc;
-
-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.util.Context;
-
-/** Javadoc uses an extended class reader 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.
- * This code and its internal interfaces are subject to change or
- * deletion without notice.</b>
- *
- * @author Neal Gafter
- */
-public class JavadocClassReader extends ClassReader {
-
- public static JavadocClassReader instance0(Context context) {
- ClassReader instance = context.get(classReaderKey);
- if (instance == null)
- instance = new JavadocClassReader(context);
- return (JavadocClassReader)instance;
- }
-
- public static void preRegister(Context context) {
- context.put(classReaderKey, new Context.Factory<ClassReader>() {
- public ClassReader make(Context c) {
- return new JavadocClassReader(c);
- }
- });
- }
-
- private DocEnv docenv;
- private EnumSet<JavaFileObject.Kind> all = EnumSet.of(JavaFileObject.Kind.CLASS,
- JavaFileObject.Kind.SOURCE,
- JavaFileObject.Kind.HTML);
- private EnumSet<JavaFileObject.Kind> noSource = EnumSet.of(JavaFileObject.Kind.CLASS,
- JavaFileObject.Kind.HTML);
-
- public JavadocClassReader(Context context) {
- super(context);
- docenv = DocEnv.instance(context);
- preferSource = true;
- }
-
- /**
- * Override getPackageFileKinds to include search for package.html
- */
- @Override
- protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() {
- return docenv.docClasses ? noSource : all;
- }
-
- /**
- * Override extraFileActions to check for package documentation
- */
- @Override
- protected void extraFileActions(PackageSymbol pack, JavaFileObject fo) {
- if (fo.isNameCompatible("package", JavaFileObject.Kind.HTML))
- docenv.getPackageDoc(pack).setDocPath(fo);
- }
-}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java Sun May 18 19:59:10 2014 -0700
@@ -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 @@
* @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);
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Sun May 18 19:59:10 2014 -0700
@@ -33,12 +33,15 @@
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 @@
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 @@
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 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 @@
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<>();
--- a/langtools/test/tools/javac/6330997/T6330997.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/test/tools/javac/6330997/T6330997.java Sun May 18 19:59:10 2014 -0700
@@ -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.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;
--- a/langtools/test/tools/javac/MethodParametersTest.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/test/tools/javac/MethodParametersTest.java Sun May 18 19:59:10 2014 -0700
@@ -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 @@
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;
--- a/langtools/test/tools/javac/T6435291/T6435291.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/test/tools/javac/T6435291/T6435291.java Sun May 18 19:59:10 2014 -0700
@@ -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;
--- a/langtools/test/tools/javac/defaultMethods/BadClassfile.java Fri May 16 10:52:07 2014 +0200
+++ b/langtools/test/tools/javac/defaultMethods/BadClassfile.java Sun May 18 19:59:10 2014 -0700
@@ -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;