📄 classreader.java
字号:
currentClassFile = classFile; sym.defaultValue = deproxy(sym.type.getReturnType(), value); } finally { currentClassFile = previousClassFile; } } } class AnnotationCompleter extends AnnotationDeproxy implements Annotate.Annotator { final Symbol sym; final List<CompoundAnnotationProxy> l; final JavaFileObject classFile; public String toString() { return " ClassReader annotate " + sym.owner + "." + sym + " with " + l; } AnnotationCompleter(Symbol sym, List<CompoundAnnotationProxy> l) { this.sym = sym; this.l = l; this.classFile = currentClassFile; } // implement Annotate.Annotator.enterAnnotation() public void enterAnnotation() { JavaFileObject previousClassFile = currentClassFile; try { currentClassFile = classFile; List<Attribute.Compound> newList = deproxyCompoundList(l); sym.attributes_field = ((sym.attributes_field == null) ? newList : newList.prependList(sym.attributes_field)); } finally { currentClassFile = previousClassFile; } } }/************************************************************************ * Reading Symbols ***********************************************************************/ /** Read a field. */ VarSymbol readField() { long flags = adjustFieldFlags(nextChar()); Name name = readName(nextChar()); Type type = readType(nextChar()); VarSymbol v = new VarSymbol(flags, name, type, currentOwner); readMemberAttrs(v); return v; } /** Read a method. */ MethodSymbol readMethod() { long flags = adjustMethodFlags(nextChar()); Name name = readName(nextChar()); Type type = readType(nextChar()); if (name == names.init && currentOwner.hasOuterInstance()) { // Sometimes anonymous classes don't have an outer // instance, however, there is no reliable way to tell so // we never strip this$n if (currentOwner.name.len != 0) type = new MethodType(type.getParameterTypes().tail, type.getReturnType(), type.getThrownTypes(), syms.methodClass); } MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner); Symbol prevOwner = currentOwner; currentOwner = m; try { readMemberAttrs(m); } finally { currentOwner = prevOwner; } return m; } /** Skip a field or method */ void skipMember() { bp = bp + 6; char ac = nextChar(); for (int i = 0; i < ac; i++) { bp = bp + 2; int attrLen = nextInt(); bp = bp + attrLen; } } /** Enter type variables of this classtype and all enclosing ones in * `typevars'. */ protected void enterTypevars(Type t) { if (t.getEnclosingType() != null && t.getEnclosingType().tag == CLASS) enterTypevars(t.getEnclosingType()); for (List<Type> xs = t.getTypeArguments(); xs.nonEmpty(); xs = xs.tail) typevars.enter(xs.head.tsym); } protected void enterTypevars(Symbol sym) { if (sym.owner.kind == MTH) { enterTypevars(sym.owner); enterTypevars(sym.owner.owner); } enterTypevars(sym.type); } /** Read contents of a given class symbol `c'. Both external and internal * versions of an inner class are read. */ void readClass(ClassSymbol c) { ClassType ct = (ClassType)c.type; // allocate scope for members c.members_field = new Scope(c); // prepare type variable table typevars = typevars.dup(currentOwner); if (ct.getEnclosingType().tag == CLASS) enterTypevars(ct.getEnclosingType()); // read flags, or skip if this is an inner class long flags = adjustClassFlags(nextChar()); if (c.owner.kind == PCK) c.flags_field = flags; // read own class name and check that it matches ClassSymbol self = readClassSymbol(nextChar()); if (c != self) throw badClassFile("class.file.wrong.class", self.flatname); // class attributes must be read before class // skip ahead to read class attributes int startbp = bp; nextChar(); char interfaceCount = nextChar(); bp += interfaceCount * 2; char fieldCount = nextChar(); for (int i = 0; i < fieldCount; i++) skipMember(); char methodCount = nextChar(); for (int i = 0; i < methodCount; i++) skipMember(); readClassAttrs(c); if (readAllOfClassFile) { for (int i = 1; i < poolObj.length; i++) readPool(i); c.pool = new Pool(poolObj.length, poolObj); } // reset and read rest of classinfo bp = startbp; int n = nextChar(); if (ct.supertype_field == null) ct.supertype_field = (n == 0) ? Type.noType : readClassSymbol(n).erasure(types); n = nextChar(); List<Type> is = List.nil(); for (int i = 0; i < n; i++) { Type _inter = readClassSymbol(nextChar()).erasure(types); is = is.prepend(_inter); } if (ct.interfaces_field == null) ct.interfaces_field = is.reverse(); if (fieldCount != nextChar()) assert false; for (int i = 0; i < fieldCount; i++) enterMember(c, readField()); if (methodCount != nextChar()) assert false; for (int i = 0; i < methodCount; i++) enterMember(c, readMethod()); typevars = typevars.leave(); } /** Read inner class info. For each inner/outer pair allocate a * member class. */ void readInnerClasses(ClassSymbol c) { int n = nextChar(); for (int i = 0; i < n; i++) { nextChar(); // skip inner class symbol ClassSymbol outer = readClassSymbol(nextChar()); Name name = readName(nextChar()); if (name == null) name = names.empty; long flags = adjustClassFlags(nextChar()); if (outer != null) { // we have a member class if (name == names.empty) name = names.one; ClassSymbol member = enterClass(name, outer); if ((flags & STATIC) == 0) { ((ClassType)member.type).setEnclosingType(outer.type); if (member.erasure_field != null) ((ClassType)member.erasure_field).setEnclosingType(types.erasure(outer.type)); } if (c == outer) { member.flags_field = flags; enterMember(c, member); } } } } /** Read a class file. */ private void readClassFile(ClassSymbol c) throws IOException { int magic = nextInt(); if (magic != JAVA_MAGIC) throw badClassFile("illegal.start.of.class.file"); int minorVersion = nextChar(); int majorVersion = nextChar(); int maxMajor = Target.MAX().majorVersion; int maxMinor = Target.MAX().minorVersion; if (majorVersion > maxMajor || majorVersion * 1000 + minorVersion < Target.MIN().majorVersion * 1000 + Target.MIN().minorVersion) { if (majorVersion == (maxMajor + 1)) log.warning("big.major.version", currentClassFile, majorVersion, maxMajor); else throw badClassFile("wrong.version", Integer.toString(majorVersion), Integer.toString(minorVersion), Integer.toString(maxMajor), Integer.toString(maxMinor)); } else if (checkClassFile && majorVersion == maxMajor && minorVersion > maxMinor) { printCCF("found.later.version", Integer.toString(minorVersion)); } indexPool(); if (signatureBuffer.length < bp) { int ns = Integer.highestOneBit(bp) << 1; signatureBuffer = new byte[ns]; } 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 ***********************************************************************/ /** Define a new class given its name and owner. */ public ClassSymbol defineClass(Name name, Symbol owner) { ClassSymbol c = new ClassSymbol(0, name, owner); if (owner.kind == PCK) assert classes.get(c.flatname) == null : c; 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. */ public ClassSymbol enterClass(Name name, TypeSymbol owner) { Name flatname = TypeSymbol.formFlatName(name, owner); ClassSymbol c = classes.get(flatname); if (c == null) { c = defineClass(name, owner); classes.put(flatname, c); } else if ((c.name != name || c.owner != owner) && owner.kind == TYP && c.owner.kind == PCK) { // reassign fields of classes that might have been loaded with // their flat names. c.owner.members().remove(c); c.name = name; c.owner = owner; c.fullname = ClassSymbol.formFullName(name, owner); } 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 */ public ClassSymbol enterClass(Name flatName, JavaFileObject classFile) { ClassSymbol cs = classes.get(flatName); if (cs != null) { String msg = Log.format("%s: completer = %s; class file = %s; source file = %s", cs.fullname, cs.completer, cs.classfile, cs.sourcefile); throw new AssertionError(msg); } Name packageName = Convert.packagePart(flatName); PackageSymbol owner = packageName.isEmpty() ? syms.unnamedPackage : enterPackage(packageName); cs = defineClass(Convert.shortName(flatName), owner); cs.classfile = classFile; classes.put(flatName, cs); return cs; } /** Create a new member or toplevel class symbol with given flat name * and enter in `classes' unless already there. */ public ClassSymbol enterClass(Name flatname) { ClassSymbol c = classes.get(flatname); if (c == null) return enterClass(flatname, (JavaFileObject)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. */ public 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 boolean suppressFlush = this.suppressFlush; this.suppressFlush = true; try { completeOwners(c.owner); completeEnclosing(c); } finally {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -