# HG changeset patch # User jjg # Date 1400468350 25200 # Node ID 7f68545b5128d357de306936ec632c954bce2736 # Parent 43e7e44d63daf2476bbf02499e1dd235ff1fec8b 8041422: Split javac ClassReader into ClassReader+ClassFinder Reviewed-by: jfranck diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java --- /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. + * + *

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. + */ +public class ClassFinder { + /** The context key for the class finder. */ + protected static final Context.Key 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 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 kinds = getPackageFileKinds(); + + Set classKinds = EnumSet.copyOf(kinds); + classKinds.remove(JavaFileObject.Kind.SOURCE); + boolean wantClassFiles = !classKinds.isEmpty(); + + Set 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 path = List.nil(); + for (File file : fm.getLocation(SOURCE_PATH)) { + path = path.prepend(file); + } + log.printVerbose("sourcepath", path.reverse().toString()); + } else if (wantSourceFiles) { + List path = List.nil(); + for (File file : fm.getLocation(CLASS_PATH)) { + path = path.prepend(file); + } + log.printVerbose("sourcepath", path.reverse().toString()); + } + if (wantClassFiles) { + List 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 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); + } + } +} diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java --- 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; diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javac/code/Types.java --- 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(""); diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javac/comp/Check.java --- 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; } diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java --- 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); diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java --- 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); diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- 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); diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java --- 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 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; diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- 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 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 missing = missingTypeVariables; + List 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 missing = missingTypeVariables; - List 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 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 kinds = getPackageFileKinds(); - - Set classKinds = EnumSet.copyOf(kinds); - classKinds.remove(JavaFileObject.Kind.SOURCE); - boolean wantClassFiles = !classKinds.isEmpty(); - - Set 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 path = List.nil(); - for (File file : fm.getLocation(SOURCE_PATH)) { - path = path.prepend(file); - } - log.printVerbose("sourcepath", path.reverse().toString()); - } else if (wantSourceFiles) { - List path = List.nil(); - for (File file : fm.getLocation(CLASS_PATH)) { - path = path.prepend(file); - } - log.printVerbose("sourcepath", path.reverse().toString()); - } - if (wantClassFiles) { - List 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 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 diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java --- 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; diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java --- 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); } } diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java --- 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); diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java --- /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 + * + *

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. + * + * @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() { + public ClassFinder make(Context c) { + return new JavadocClassFinder(c); + } + }); + } + + private DocEnv docenv; + private EnumSet all = EnumSet.of(JavaFileObject.Kind.CLASS, + JavaFileObject.Kind.SOURCE, + JavaFileObject.Kind.HTML); + private EnumSet 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 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); + } +} diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java --- 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 - * - *

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. - * - * @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() { - public ClassReader make(Context c) { - return new JavadocClassReader(c); - } - }); - } - - private DocEnv docenv; - private EnumSet all = EnumSet.of(JavaFileObject.Kind.CLASS, - JavaFileObject.Kind.SOURCE, - JavaFileObject.Kind.HTML); - private EnumSet 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 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); - } -} diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java --- 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); diff -r 43e7e44d63da -r 7f68545b5128 langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java --- 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 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 names = new ListBuffer<>(); ListBuffer classTrees = new ListBuffer<>(); diff -r 43e7e44d63da -r 7f68545b5128 langtools/test/tools/javac/6330997/T6330997.java --- 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; diff -r 43e7e44d63da -r 7f68545b5128 langtools/test/tools/javac/MethodParametersTest.java --- 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; diff -r 43e7e44d63da -r 7f68545b5128 langtools/test/tools/javac/T6435291/T6435291.java --- 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; diff -r 43e7e44d63da -r 7f68545b5128 langtools/test/tools/javac/defaultMethods/BadClassfile.java --- 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;