--- 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