📄 classreader.java
字号:
*/ void readClassAttrs(ClassSymbol c) { char ac = nextChar(); for (int i = 0; i < ac; i++) { Name attrName = readName(nextChar()); int attrLen = nextInt(); readClassAttr(c, attrName, attrLen); } } /** Read code block. */ Code readCode(Symbol owner) { nextChar(); // max_stack nextChar(); // max_locals final int code_length = nextInt(); bp += code_length; final char exception_table_length = nextChar(); bp += exception_table_length * 8; readMemberAttrs(owner); return null; }/************************************************************************ * Reading Java-language annotations ***********************************************************************/ /** Attach annotations. */ void attachAnnotations(final Symbol sym) { int numAttributes = nextChar(); if (numAttributes != 0) { ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<CompoundAnnotationProxy>(); for (int i = 0; i<numAttributes; i++) { CompoundAnnotationProxy proxy = readCompoundAnnotation(); if (proxy.type.tsym == syms.proprietaryType.tsym) sym.flags_field |= PROPRIETARY; else proxies.append(proxy); } annotate.later(new AnnotationCompleter(sym, proxies.toList())); } } /** Attach parameter annotations. */ void attachParameterAnnotations(final Symbol method) { final MethodSymbol meth = (MethodSymbol)method; int numParameters = buf[bp++] & 0xFF; List<VarSymbol> parameters = meth.params(); int pnum = 0; while (parameters.tail != null) { attachAnnotations(parameters.head); parameters = parameters.tail; pnum++; } if (pnum != numParameters) { throw badClassFile("bad.runtime.invisible.param.annotations", meth); } } /** Attach the default value for an annotation element. */ void attachAnnotationDefault(final Symbol sym) { final MethodSymbol meth = (MethodSymbol)sym; // only on methods final Attribute value = readAttributeValue(); annotate.later(new AnnotationDefaultCompleter(meth, value)); } Type readTypeOrClassSymbol(int i) { // support preliminary jsr175-format class files if (buf[poolIdx[i]] == CONSTANT_Class) return readClassSymbol(i).type; return readType(i); } Type readEnumType(int i) { // support preliminary jsr175-format class files int index = poolIdx[i]; int length = getChar(index + 1); if (buf[index + length + 2] != ';') return enterClass(readName(i)).type; return readType(i); } CompoundAnnotationProxy readCompoundAnnotation() { Type t = readTypeOrClassSymbol(nextChar()); int numFields = nextChar(); ListBuffer<Pair<Name,Attribute>> pairs = new ListBuffer<Pair<Name,Attribute>>(); for (int i=0; i<numFields; i++) { Name name = readName(nextChar()); Attribute value = readAttributeValue(); pairs.append(new Pair<Name,Attribute>(name, value)); } return new CompoundAnnotationProxy(t, pairs.toList()); } Attribute readAttributeValue() { char c = (char) buf[bp++]; switch (c) { case 'B': return new Attribute.Constant(syms.byteType, readPool(nextChar())); case 'C': return new Attribute.Constant(syms.charType, readPool(nextChar())); case 'D': return new Attribute.Constant(syms.doubleType, readPool(nextChar())); case 'F': return new Attribute.Constant(syms.floatType, readPool(nextChar())); case 'I': return new Attribute.Constant(syms.intType, readPool(nextChar())); case 'J': return new Attribute.Constant(syms.longType, readPool(nextChar())); case 'S': return new Attribute.Constant(syms.shortType, readPool(nextChar())); case 'Z': return new Attribute.Constant(syms.booleanType, readPool(nextChar())); case 's': return new Attribute.Constant(syms.stringType, readPool(nextChar()).toString()); case 'e': return new EnumAttributeProxy(readEnumType(nextChar()), readName(nextChar())); case 'c': return new Attribute.Class(types, readTypeOrClassSymbol(nextChar())); case '[': { int n = nextChar(); ListBuffer<Attribute> l = new ListBuffer<Attribute>(); for (int i=0; i<n; i++) l.append(readAttributeValue()); return new ArrayAttributeProxy(l.toList()); } case '@': return readCompoundAnnotation(); default: throw new AssertionError("unknown annotation tag '" + c + "'"); } } interface ProxyVisitor extends Attribute.Visitor { void visitEnumAttributeProxy(EnumAttributeProxy proxy); void visitArrayAttributeProxy(ArrayAttributeProxy proxy); void visitCompoundAnnotationProxy(CompoundAnnotationProxy proxy); } static class EnumAttributeProxy extends Attribute { Type enumType; Name enumerator; public EnumAttributeProxy(Type enumType, Name enumerator) { super(null); this.enumType = enumType; this.enumerator = enumerator; } public void accept(Visitor v) { ((ProxyVisitor)v).visitEnumAttributeProxy(this); } public String toString() { return "/*proxy enum*/" + enumType + "." + enumerator; } } static class ArrayAttributeProxy extends Attribute { List<Attribute> values; ArrayAttributeProxy(List<Attribute> values) { super(null); this.values = values; } public void accept(Visitor v) { ((ProxyVisitor)v).visitArrayAttributeProxy(this); } public String toString() { return "{" + values + "}"; } } /** A temporary proxy representing a compound attribute. */ static class CompoundAnnotationProxy extends Attribute { final List<Pair<Name,Attribute>> values; public CompoundAnnotationProxy(Type type, List<Pair<Name,Attribute>> values) { super(type); this.values = values; } public void accept(Visitor v) { ((ProxyVisitor)v).visitCompoundAnnotationProxy(this); } public String toString() { StringBuffer buf = new StringBuffer(); buf.append("@"); buf.append(type.tsym.getQualifiedName()); buf.append("/*proxy*/{"); boolean first = true; for (List<Pair<Name,Attribute>> v = values; v.nonEmpty(); v = v.tail) { Pair<Name,Attribute> value = v.head; if (!first) buf.append(","); first = false; buf.append(value.fst); buf.append("="); buf.append(value.snd); } buf.append("}"); return buf.toString(); } } class AnnotationDeproxy implements ProxyVisitor { private ClassSymbol requestingOwner = currentOwner.kind == MTH ? currentOwner.enclClass() : (ClassSymbol)currentOwner; List<Attribute.Compound> deproxyCompoundList(List<CompoundAnnotationProxy> pl) { // also must fill in types!!!! ListBuffer<Attribute.Compound> buf = new ListBuffer<Attribute.Compound>(); for (List<CompoundAnnotationProxy> l = pl; l.nonEmpty(); l=l.tail) { buf.append(deproxyCompound(l.head)); } return buf.toList(); } Attribute.Compound deproxyCompound(CompoundAnnotationProxy a) { ListBuffer<Pair<Symbol.MethodSymbol,Attribute>> buf = new ListBuffer<Pair<Symbol.MethodSymbol,Attribute>>(); for (List<Pair<Name,Attribute>> l = a.values; l.nonEmpty(); l = l.tail) { MethodSymbol meth = findAccessMethod(a.type, l.head.fst); buf.append(new Pair<Symbol.MethodSymbol,Attribute> (meth, deproxy(meth.type.getReturnType(), l.head.snd))); } return new Attribute.Compound(a.type, buf.toList()); } MethodSymbol findAccessMethod(Type container, Name name) { CompletionFailure failure = null; try { for (Scope.Entry e = container.tsym.members().lookup(name); e.scope != null; e = e.next()) { Symbol sym = e.sym; if (sym.kind == MTH && sym.type.getParameterTypes().length() == 0) return (MethodSymbol) sym; } } catch (CompletionFailure ex) { failure = ex; } // The method wasn't found: emit a warning and recover JavaFileObject prevSource = log.useSource(requestingOwner.classfile); try { if (failure == null) { log.warning("annotation.method.not.found", container, name); } else { log.warning("annotation.method.not.found.reason", container, name, failure.getMessage()); } } finally { log.useSource(prevSource); } // 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. MethodType mt = new MethodType(List.<Type>nil(), syms.botType, List.<Type>nil(), syms.methodClass); return new MethodSymbol(PUBLIC | ABSTRACT, name, mt, container.tsym); } Attribute result; Type type; Attribute deproxy(Type t, Attribute a) { Type oldType = type; try { type = t; a.accept(this); return result; } finally { type = oldType; } } // implement Attribute.Visitor below public void visitConstant(Attribute.Constant value) { // assert value.type == type; result = value; } public void visitClass(Attribute.Class clazz) { result = clazz; } public void visitEnum(Attribute.Enum e) { throw new AssertionError(); // shouldn't happen } public void visitCompound(Attribute.Compound compound) { throw new AssertionError(); // shouldn't happen } public void visitArray(Attribute.Array array) { throw new AssertionError(); // shouldn't happen } public void visitError(Attribute.Error e) { throw new AssertionError(); // shouldn't happen } public void visitEnumAttributeProxy(EnumAttributeProxy proxy) { // type.tsym.flatName() should == proxy.enumFlatName TypeSymbol enumTypeSym = proxy.enumType.tsym; VarSymbol enumerator = null; for (Scope.Entry e = enumTypeSym.members().lookup(proxy.enumerator); e.scope != null; e = e.next()) { if (e.sym.kind == VAR) { enumerator = (VarSymbol)e.sym; break; } } if (enumerator == null) { log.error("unknown.enum.constant", currentClassFile, enumTypeSym, proxy.enumerator); result = new Attribute.Error(enumTypeSym.type); } else { result = new Attribute.Enum(enumTypeSym.type, enumerator); } } public void visitArrayAttributeProxy(ArrayAttributeProxy proxy) { int length = proxy.values.length(); Attribute[] ats = new Attribute[length]; Type elemtype = types.elemtype(type); int i = 0; for (List<Attribute> p = proxy.values; p.nonEmpty(); p = p.tail) { ats[i++] = deproxy(elemtype, p.head); } result = new Attribute.Array(type, ats); } public void visitCompoundAnnotationProxy(CompoundAnnotationProxy proxy) { result = deproxyCompound(proxy); } } class AnnotationDefaultCompleter extends AnnotationDeproxy implements Annotate.Annotator { final MethodSymbol sym; final Attribute value; final JavaFileObject classFile = currentClassFile; public String toString() { return " ClassReader store default for " + sym.owner + "." + sym + " is " + value; } AnnotationDefaultCompleter(MethodSymbol sym, Attribute value) { this.sym = sym; this.value = value; } // implement Annotate.Annotator.enterAnnotation() public void enterAnnotation() { JavaFileObject previousClassFile = currentClassFile; try {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -