/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/** This class provides operations to read a classfile into an internal
* representation. The internal representation is anchored in a
* ClassSymbol which contains in its scope symbol representations
* for all other definitions in the classfile. Top-level Classes themselves
* appear as members of the scopes of PackageSymbols.
*
* <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>
*/
/** The context key for the class reader. */
/** Switch: verbose output.
*/
boolean verbose;
/** Switch: check class file for correct minor version, unrecognized
* attributes.
*/
boolean checkClassFile;
/** Switch: read constant pool and code sections. This switch is initially
* set to false but can be turned on from outside.
*/
public boolean readAllOfClassFile = false;
/** Switch: read GJ signature information.
*/
boolean allowGenerics;
/** Switch: read varargs attribute.
*/
boolean allowVarargs;
/** Switch: allow annotations.
*/
boolean allowAnnotations;
/** Switch: allow simplified varargs.
*/
boolean allowSimplifiedVarargs;
/** Lint option: warn about classfile issues
*/
boolean lintClassfile;
/** Switch: preserve parameter names from the variable table.
*/
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;
/** The log to use for verbose output
*/
/** The symbol table. */
/** The name table. */
/** Force a completion failure on this name
*/
/** Access to files
*/
/** Factory for diagnostics
*/
/** Can be reassigned from outside:
* the completer to be used for ".java" files. If this remains unassigned
* ".java" files will not be loaded.
*/
/** A hashtable containing the encountered top-level and member classes,
* indexed by flat names. The table does not contain local classes.
*/
/** A hashtable containing the encountered packages.
*/
/** The current scope where type variables are entered.
*/
/** The path name of the class file currently being read.
*/
/** The class or method currently being read.
*/
/** The buffer containing the currently read class file.
*/
/** The current input pointer.
*/
int bp;
/** The objects of the constant pool.
*/
/** For every constant pool entry, an index into buf where the
* defining section of the entry is found.
*/
int[] poolIdx;
/** The major version number of the class file being read. */
int majorVersion;
/** The minor version number of the class file being read. */
int minorVersion;
/** A table to hold the constant pool indices for method parameter
* names, as given in LocalVariableTable attributes.
*/
int[] parameterNameIndices;
/**
* Whether or not any parameter names have been found.
*/
boolean haveParameterNameIndices;
/**
* The set of attribute names for which warnings have been generated for the current class
*/
/** Get the ClassReader instance for this invocation. */
return instance;
}
/** Initialize classes and packages, treating this as the definitive classreader. */
}
/** Initialize classes and packages, optionally treating this as
* the definitive classreader.
*/
if (definitive) {
} else {
}
}
/** Construct a new class reader, optionally treated as the
* definitive classreader for this invocation.
*/
if (fileManager == null)
throw new AssertionError("FileManager initialization error");
: null;
}
/** Add member to class unless it is synthetic.
*/
}
/************************************************************************
* Error Diagnoses
***********************************************************************/
}
}
// where
? "bad.source.file.header" : "bad.class.file.header");
}
return new BadClassFile (
}
/************************************************************************
* Buffer Access
***********************************************************************/
/** Read a character.
*/
char nextChar() {
}
/** Read a byte.
*/
byte nextByte() {
}
/** Read an integer.
*/
int nextInt() {
return
}
/** Extract a character at position bp from buf.
*/
return
}
/** Extract an integer at position bp from buf.
*/
return
}
/** Extract a long integer at position bp from buf.
*/
try {
} catch (IOException e) {
throw new AssertionError(e);
}
}
/** Extract a float at position bp from buf.
*/
try {
} catch (IOException e) {
throw new AssertionError(e);
}
}
/** Extract a double at position bp from buf.
*/
try {
return bufin.readDouble();
} catch (IOException e) {
throw new AssertionError(e);
}
}
/************************************************************************
* Constant Pool Access
***********************************************************************/
/** Index all constant pool entries, writing their start addresses into
* poolIdx.
*/
void indexPool() {
int i = 1;
switch (tag) {
case CONSTANT_Utf8: case CONSTANT_Unicode: {
break;
}
case CONSTANT_Class:
case CONSTANT_String:
case CONSTANT_MethodType:
break;
case CONSTANT_MethodHandle:
break;
case CONSTANT_Fieldref:
case CONSTANT_Methodref:
case CONSTANT_NameandType:
case CONSTANT_Integer:
case CONSTANT_Float:
case CONSTANT_InvokeDynamic:
break;
case CONSTANT_Long:
case CONSTANT_Double:
i++;
break;
default:
throw badClassFile("bad.const.pool.tag.at",
}
}
}
/** Read constant pool entry at start address i, use pool as a cache.
*/
switch (tag) {
case CONSTANT_Utf8:
break;
case CONSTANT_Unicode:
throw badClassFile("unicode.str.not.supported");
case CONSTANT_Class:
break;
case CONSTANT_String:
// FIXME: (footprint) do not use toString here
break;
case CONSTANT_Fieldref: {
break;
}
case CONSTANT_Methodref:
case CONSTANT_InterfaceMethodref: {
break;
}
case CONSTANT_NameandType:
poolObj[i] = new NameAndType(
break;
case CONSTANT_Integer:
break;
case CONSTANT_Float:
break;
case CONSTANT_Long:
break;
case CONSTANT_Double:
break;
case CONSTANT_MethodHandle:
skipBytes(4);
break;
case CONSTANT_MethodType:
skipBytes(3);
break;
case CONSTANT_InvokeDynamic:
skipBytes(5);
break;
default:
}
return poolObj[i];
}
/** Read signature and convert to type.
*/
}
/** If name is an array type or class signature, return the
* corresponding type; otherwise return a ClassSymbol with given name.
*/
// by the above assertion, the following test can be
// simplified to (buf[start] == '[')
len)));
}
/** Read signature and convert to type parameters.
*/
}
/** Read class entry.
*/
return (ClassSymbol) (readPool(i));
}
/** Read name.
*/
}
/************************************************************************
* Reading Types
***********************************************************************/
/** The unread portion of the currently read type is
* signature[sigp..siglimit-1].
*/
byte[] signature;
int sigp;
int siglimit;
boolean sigEnterPhase = false;
/** Convert signature to type, where signature is a byte array segment.
*/
return sigToType();
}
/** Convert signature to type, where signature is implicit.
*/
case 'T':
sigp++;
sigp++;
return sigEnterPhase
case '+': {
sigp++;
}
case '*':
sigp++;
case '-': {
sigp++;
}
case 'B':
sigp++;
case 'C':
sigp++;
case 'D':
sigp++;
return syms.doubleType;
case 'F':
sigp++;
case 'I':
sigp++;
case 'J':
sigp++;
case 'L':
{
// int oldsigp = sigp;
Type t = classSigToType();
throw badClassFile("deprecated inner class signature syntax " +
"(please recompile from source)");
/*
System.err.println(" decoded " +
new String(signature, oldsigp, sigp-oldsigp) +
" => " + t + " outer " + t.outer());
*/
return t;
}
case 'S':
sigp++;
case 'V':
sigp++;
case 'Z':
sigp++;
return syms.booleanType;
case '[':
sigp++;
case '(':
sigp++;
sigp++;
}
return new MethodType(argtypes,
case '<':
return poly;
default:
throw badClassFile("bad.signature",
}
}
/** Convert class signature to type, where signature is implicit.
*/
throw badClassFile("bad.class.signature",
sigp++;
while (true) {
switch (c) {
case ';': { // end
else
return outer;
}
case '<': // generic arguments
boolean completed = false;
public Type getEnclosingType() {
if (!completed) {
completed = true;
super.getEnclosingType().allparams();
// no "rare" types
} else {
typeArgs));
}
} else {
}
}
return super.getEnclosingType();
}
throw new UnsupportedOperationException();
}
};
case ';':
// support old-style GJC signatures
// The signature produced was
// rather than say
3; // ".L" and "$"
break;
} else {
return outer;
}
case '.':
break;
default:
}
continue;
case '.':
continue;
case '/':
continue;
default:
signatureBuffer[sbp++] = c;
continue;
}
}
}
/** Convert (implicit) signature to list of types
* until `terminator' is encountered.
*/
sigp++;
}
/** Convert signature to type parameters, where signature is a byte
* array segment.
*/
return sigToTypeParams();
}
/** Convert signature to type parameters, where signature is implicit.
*/
sigp++;
sigEnterPhase = true;
sigEnterPhase = false;
sigp++;
}
}
/** Convert (implicit) signature to type parameter.
*/
if (sigEnterPhase) {
} else {
}
sigp++;
}
sigp++;
}
if (!sigEnterPhase) {
}
return tvar;
}
/** Find type variable with given name in `typevars' scope.
*/
} else {
if (readingClassAttr) {
// While reading the class attribute, the supertypes
// might refer to a type variable from an enclosing element
// (method or class).
// If the type variable is defined in the enclosing class,
// we can actually find it in
// currentOwner.owner.type.getTypeArguments()
// However, until we have read the enclosing method attribute
// we don't know for sure if this owner is correct. It could
// be a method and there is no way to tell before reading the
// enclosing method attribute.
// System.err.println("Missing type var " + name);
return t;
}
}
}
/************************************************************************
* Reading Attributes
***********************************************************************/
protected abstract class AttributeReader {
}
if (majorVersion > version.major || (majorVersion == version.major && minorVersion >= version.minor))
return true;
try {
} finally {
}
}
}
return false;
}
}
private void initAttributeReaders() {
AttributeReader[] readers = {
// v45.3 attributes
if (readAllOfClassFile || saveParameterNames)
else
}
},
// Ignore ConstantValue attribute if field not final.
}
},
}
},
int nexceptions = nextChar();
for (int j = 0; j < nexceptions; j++)
}
},
readInnerClasses(c);
}
},
if (saveParameterNames) {
// Pick up parameter names from the variable table.
// Parameter names are not explicitly identified as such,
// but all parameter name entries in the LocalVariableTable
// have a start_pc of 0. Therefore, we record the name
// indicies of all slots with a start_pc of zero in the
// parameterNameIndicies array.
// Note that this implicitly honors the JVMS spec that
// there may be more than one LocalVariableTable, and that
// there is no specified ordering for the entries.
int numEntries = nextChar();
for (int i = 0; i < numEntries; i++) {
if (start_pc == 0) {
// ensure array large enough
}
haveParameterNameIndices = true;
}
}
}
}
},
}
},
// bridge methods are visible when generics not enabled
}
},
// standard v49 attributes
}
},
}
readingClassAttr = true;
try {
} finally {
readingClassAttr = false;
}
} else {
//- System.err.println(" # " + sym.type);
}
}
},
// v49 annotation attributes
}
},
}
},
}
},
}
},
}
},
// additional "legacy" v49 attributes, superceded by flags
if (allowAnnotations)
}
},
if (!allowGenerics)
}
},
}
},
if (allowVarargs)
}
},
// The following attributes for a Code attribute are not currently handled
// StackMapTable
// SourceDebugExtension
// LineNumberTable
// LocalVariableTypeTable
};
for (AttributeReader r: readers)
}
/** Report unrecognized attribute.
*/
if (checkClassFile)
}
// sym is a nested class with an "Enclosing Method" attribute
// remove sym from it's current owners scope and place it in
// the scope specified by the attribute
if (c.members_field == null)
else
if (m != null) {
} else {
}
if (!missingTypeVariables.isEmpty()) {
}
} else {
}
}
// See java.lang.Class
int index = 1;
index++;
}
return null;
return (MethodSymbol)e.sym;
// not a constructor
return null;
// no enclosing instance
return null;
// no parameters
return null;
// A constructor of an inner class.
// Remove the first argument (the enclosing instance)
// Try searching again
}
/** Similar to Types.isSameType but avoids completion */
return false;
}
}
/**
* Character.isDigit answers <tt>true</tt> to some non-ascii
* digits. This one does not. <b>copied from java.lang.Class</b>
*/
private static boolean isAsciiDigit(char c) {
return '0' <= c && c <= '9';
}
/** Read member attributes.
*/
}
for (int i = 0; i < ac; i++) {
else {
}
}
}
private boolean readingClassAttr = false;
/** Read class attributes.
*/
}
/** Read code block.
*/
nextChar(); // max_stack
nextChar(); // max_locals
final int code_length = nextInt();
bp += code_length;
final char exception_table_length = nextChar();
return null;
}
/************************************************************************
* Reading Java-language annotations
***********************************************************************/
/** Attach annotations.
*/
int numAttributes = nextChar();
if (numAttributes != 0) {
new ListBuffer<CompoundAnnotationProxy>();
for (int i = 0; i<numAttributes; i++) {
else
}
}
}
}
/** Attach parameter annotations.
*/
int pnum = 0;
pnum++;
}
if (pnum != numParameters) {
}
}
/** Attach the default value for an annotation element.
*/
}
// support preliminary jsr175-format class files
return readClassSymbol(i).type;
return readType(i);
}
// support preliminary jsr175-format class files
return readType(i);
}
for (int i=0; i<numFields; i++) {
}
}
switch (c) {
case 'B':
case 'C':
case 'D':
case 'F':
case 'I':
case 'J':
case 'S':
case 'Z':
case 's':
case 'e':
case 'c':
case '[': {
int n = nextChar();
for (int i=0; i<n; i++)
l.append(readAttributeValue());
return new ArrayAttributeProxy(l.toList());
}
case '@':
return readCompoundAnnotation();
default:
}
}
}
super(null);
this.enumerator = enumerator;
}
}
}
super(null);
}
}
}
/** A temporary proxy representing a compound attribute.
*/
super(type);
}
boolean first = true;
first = false;
}
}
}
/** A temporary proxy representing a type annotation.
*/
static class TypeAnnotationProxy {
}
}
// also must fill in types!!!!
}
}
l.nonEmpty();
l = l.tail) {
}
}
try {
e = e.next()) {
return (MethodSymbol) sym;
}
} catch (CompletionFailure ex) {
}
// The method wasn't found: emit a warning and recover
try {
name);
} else {
name,
}
} finally {
}
// Construct a new method type and symbol. Use bottom
// type (typeof null) as return type because this type is
// a subtype of all reference types and can be converted
// to primitive types by unboxing.
}
try {
type = t;
a.accept(this);
return result;
} finally {
}
}
// implement Attribute.Visitor below
// assert value.type == type;
}
}
throw new AssertionError(); // shouldn't happen
}
throw new AssertionError(); // shouldn't happen
}
throw new AssertionError(); // shouldn't happen
}
throw new AssertionError(); // shouldn't happen
}
// type.tsym.flatName() should == proxy.enumFlatName
try {
e = e.next()) {
break;
}
}
}
catch (CompletionFailure ex) {
}
if (enumerator == null) {
failure.getDiagnostic());
} else {
}
} else {
}
}
int i = 0;
}
}
}
}
}
}
// implement Annotate.Annotator.enterAnnotation()
public void enterAnnotation() {
try {
} finally {
}
}
}
final List<CompoundAnnotationProxy> l;
}
this.l = l;
this.classFile = currentClassFile;
}
// implement Annotate.Annotator.enterAnnotation()
public void enterAnnotation() {
try {
? newList
} finally {
}
}
}
/************************************************************************
* Reading Symbols
***********************************************************************/
/** Read a field.
*/
readMemberAttrs(v);
return v;
}
/** Read a method.
*/
// Sometimes anonymous classes don't have an outer
// instance, however, there is no reliable way to tell so
// we never strip this$n
}
if (saveParameterNames)
currentOwner = m;
try {
readMemberAttrs(m);
} finally {
}
if (saveParameterNames)
setParameterNames(m, type);
return m;
}
if (isVarargs) {
t :
((ArrayType)t).makeVarargs());
}
}
}
/**
* Init the parameter names array.
* Parameter names are currently inferred from the names in the
* LocalVariableTable attributes of a Code attribute.
* (Note: this means parameter names are currently not available for
* methods without a Code attribute.)
* This method initializes an array in which to store the name indexes
* of parameter names found in LocalVariableTable attributes. It is
* slightly supersized to allow for additional slots with a start_pc of 0.
*/
// make allowance for synthetic parameters.
final int excessSlots = 4;
int expectedParameterSlots =
if (parameterNameIndices == null
parameterNameIndices = new int[expectedParameterSlots];
} else
haveParameterNameIndices = false;
}
/**
* Set the parameter names for a symbol from the name index in the
* parameterNameIndicies array. The type of the symbol may have changed
* while reading the method attributes (see the Signature attribute).
* This may be because of generic information or because anonymous
* synthetic parameters were added. The original type (as read from
* the method descriptor) is used to help guess the existence of
* anonymous synthetic parameters.
* On completion, sym.savedParameter names will either be null (if
* no parameter names were found in the class file) or will be set to a
* list of names, one per entry in sym.type.getParameterTypes, with
* any missing names represented by the empty name.
*/
// if no names were found in the class file, there's nothing more to do
if (!haveParameterNameIndices)
return;
// the code in readMethod may have skipped the first parameter when
// setting up the MethodType. If so, we make a corresponding allowance
// here for the position of the first parameter. Note that this
// assumes the skipped parameter has a width of 1 -- i.e. it is not
// a double width type (long or double.)
// Sometimes anonymous classes don't have an outer
// instance, however, there is no reliable way to tell so
// we never strip this$n
firstParam += 1;
}
// reading the method attributes has caused the symbol's type to
// be changed. (i.e. the Signature attribute.) This may happen if
// there are hidden (synthetic) parameters in the descriptor, but
// not in the Signature. The position of these hidden parameters
// is unspecified; for now, assume they are at the beginning, and
// so skip over them. The primary case for this is two hidden
// parameters passed into Enum constructors.
firstParam += skip;
}
int index = firstParam;
}
}
/**
* skip n bytes
*/
void skipBytes(int n) {
}
/** Skip a field or method
*/
void skipMember() {
for (int i = 0; i < ac; i++) {
}
}
/** Enter type variables of this classtype and all enclosing ones in
* `typevars'.
*/
}
}
}
/** Read contents of a given class symbol `c'. Both external and internal
* versions of an inner class are read.
*/
// allocate scope for members
c.members_field = new Scope(c);
// prepare type variable table
// read flags, or skip if this is an inner class
// read own class name and check that it matches
if (c != self)
throw badClassFile("class.file.wrong.class",
// class attributes must be read before class
// skip ahead to read class attributes
nextChar();
char interfaceCount = nextChar();
char fieldCount = nextChar();
char methodCount = nextChar();
readClassAttrs(c);
if (readAllOfClassFile) {
}
// reset and read rest of classinfo
int n = nextChar();
n = nextChar();
for (int i = 0; i < n; i++) {
}
}
* member class.
*/
int n = nextChar();
for (int i = 0; i < n; i++) {
nextChar(); // skip inner class symbol
}
if (c == outer) {
enterMember(c, member);
}
}
}
}
/** Read a class file.
*/
if (magic != JAVA_MAGIC)
throw badClassFile("illegal.start.of.class.file");
minorVersion = nextChar();
majorVersion = nextChar();
if (majorVersion > maxMajor ||
{
maxMajor);
else
throw badClassFile("wrong.version",
}
else if (checkClassFile &&
majorVersion == maxMajor &&
{
printCCF("found.later.version",
}
indexPool();
signatureBuffer = new byte[ns];
}
readClass(c);
}
/************************************************************************
* Adjusting flags
***********************************************************************/
return flags;
}
flags &= ~ACC_BRIDGE;
if (!allowGenerics)
}
flags &= ~ACC_VARARGS;
}
return flags;
}
}
/************************************************************************
* Loading Classes
***********************************************************************/
/** Define a new class given its name and owner.
*/
c.completer = this;
return c;
}
/** Create a new toplevel or member class symbol with given name
* and owner and enter in `classes' unless already there.
*/
if (c == null) {
// reassign fields of classes that might have been loaded with
// their flat names.
}
return c;
}
/**
* Creates a new toplevel class symbol with given flat name and
* given class (or source) file.
*
* @param flatName a fully qualified binary class name
* @param classFile the class file or compilation unit defining
* the class (may be {@code null})
* @return a newly created class symbol
* @throws AssertionError if the class symbol already exists
*/
cs.sourcefile);
throw new AssertionError(msg);
}
return cs;
}
/** Create a new member or toplevel class symbol with given flat name
* and enter in `classes' unless already there.
*/
if (c == null)
else
return c;
}
private boolean suppressFlush = false;
/** Completion for classes to be loaded. Before a class is loaded
* we make sure its enclosing class (if any) is loaded.
*/
boolean saveSuppressFlush = suppressFlush;
suppressFlush = true;
try {
completeOwners(c.owner);
} finally {
}
fillIn(c);
try {
fillIn(p);
} catch (IOException ex) {
}
}
if (!filling && !suppressFlush)
}
/** complete up through the enclosing package. */
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.*.
*/
}
}
}
/** 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.
*/
if (completionFailureName == c.fullname) {
throw new CompletionFailure(c, "user-selected completion failure by class name");
}
currentOwner = c;
warnedAttrs.clear();
try {
if (filling) {
}
if (verbose) {
}
filling = true;
try {
bp = 0;
readClassFile(c);
filling = false;
} else if (missingTypeVariables.isEmpty() !=
}
} finally {
filling = false;
}
} else {
if (sourceCompleter != null) {
} else {
throw new IllegalStateException("Source completer required to read "
}
}
return;
} catch (IOException ex) {
} finally {
}
} else {
throw
newCompletionFailure(c, diag);
}
}
// where
try {
int bp = 0;
while (r != -1) {
bp += r;
}
return buf;
} finally {
try {
s.close();
} catch (IOException e) {
/* Ignore any errors, as this stream may have already
* thrown a related exception which is the one that
* should be reported.
*/
}
}
}
/*
* ensureCapacity will increase the buffer as needed, taking note that
* the new buffer will always be greater than the needed and never
* exactly equal to the needed size or bp. If equal then the read (above)
* will infinitely loop as buf.length - bp == 0.
*/
}
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.
*/
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 {
return result;
}
}
{
}
/** Load a toplevel class with given fully qualified name
* The class is entered into `classes' only if load was successful.
*/
try {
c.complete();
} catch (CompletionFailure ex) {
throw ex;
}
}
return c;
}
/************************************************************************
* Loading Packages
***********************************************************************/
/** Check to see if a package exists, given its fully qualified name.
*/
}
/** Make a package, given its fully qualified name.
*/
if (p == null) {
p = new PackageSymbol(
p.completer = this;
}
return p;
}
/** Make a package, given its unqualified name and enclosing package.
*/
}
/** 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.
*/
q.flags_field |= EXISTS;
int seen;
seen = CLASS_SEEN;
else
seen = SOURCE_SEEN;
ClassSymbol c = isPkgInfo
? p.package_info
if (c == null) {
c = enterClass(classname, p);
if (isPkgInfo) {
p.package_info = c;
} else {
if (c.owner == p) // it might be an inner class
p.members_field.enter(c);
}
// 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.
}
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.
*/
JavaFileObject b) {
if (preferSource)
else {
long adate = a.getLastModified();
long bdate = b.getLastModified();
// 6449326: policy for bad lastModifiedTime in ClassReader
//assert adate >= 0 && bdate >= 0;
}
}
/**
* specifies types of files to be read when filling in a package symbol
*/
}
/**
* this is used to support javadoc
*/
}
private boolean verbosePath = true;
/** Load directory of package into members scope.
*/
false));
if (verbose && verbosePath) {
if (fileManager instanceof StandardJavaFileManager) {
if (haveSourcePath && wantSourceFiles) {
}
} else if (wantSourceFiles) {
}
}
if (wantClassFiles) {
}
}
}
}
}
if (wantSourceFiles && !haveSourcePath) {
fillIn(p, CLASS_PATH,
false));
} else {
if (wantClassFiles)
fillIn(p, CLASS_PATH,
false));
if (wantSourceFiles)
fillIn(p, SOURCE_PATH,
false));
}
verbosePath = false;
}
// where
{
case CLASS:
case SOURCE: {
// TODO pass binaryName to includeClassFile
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.
*/
}
public interface SourceCompleter {
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
* to be valid as is, so operations other than those to access the name throw
* UnsupportedOperationException
*/
/** The file's name.
*/
super(null); // no file manager; never referenced for this file object
}
try {
} catch (URISyntaxException e) {
}
}
}
return getName();
}
}
throw new UnsupportedOperationException();
}
throw new UnsupportedOperationException();
}
throw new UnsupportedOperationException();
}
throw new UnsupportedOperationException();
}
throw new UnsupportedOperationException();
}
public long getLastModified() {
throw new UnsupportedOperationException();
}
public boolean delete() {
throw new UnsupportedOperationException();
}
}
return true; // fail-safe mode
}
/**
* Check if two file objects are equal.
* SourceFileObjects are just placeholder objects for the value of a
* SourceFile attribute, and do not directly represent specific files.
* Two SourceFileObjects are equal if their names are equal.
*/
if (this == other)
return true;
if (!(other instanceof SourceFileObject))
return false;
}
public int hashCode() {
}
}
}