⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classreader.java

📁 是一款用JAVA 编写的编译器 具有很强的编译功能
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                signatureBuffer[sbp++] = c;                continue;            }        }    }    /** Convert (implicit) signature to list of types     *  until `terminator' is encountered.     */    List<Type> sigToTypes(char terminator) {        List<Type> head = List.of(null);        List<Type> tail = head;        while (signature[sigp] != terminator)            tail = tail.setTail(List.of(sigToType()));        sigp++;        return head.tail;    }    /** Convert signature to type parameters, where signature is a name.     */    List<Type> sigToTypeParams(Name name) {        return sigToTypeParams(name.table.names, name.index, name.len);    }    /** Convert signature to type parameters, where signature is a byte     *  array segment.     */    List<Type> sigToTypeParams(byte[] sig, int offset, int len) {        signature = sig;        sigp = offset;        siglimit = offset + len;        return sigToTypeParams();    }    /** Convert signature to type parameters, where signature is implicit.     */    List<Type> sigToTypeParams() {        List<Type> tvars = List.nil();        if (signature[sigp] == '<') {            sigp++;            int start = sigp;            sigEnterPhase = true;            while (signature[sigp] != '>')                tvars = tvars.prepend(sigToTypeParam());            sigEnterPhase = false;            sigp = start;            while (signature[sigp] != '>')                sigToTypeParam();            sigp++;        }        return tvars.reverse();    }    /** Convert (implicit) signature to type parameter.     */    Type sigToTypeParam() {        int start = sigp;        while (signature[sigp] != ':') sigp++;        Name name = names.fromUtf(signature, start, sigp - start);        TypeVar tvar;        if (sigEnterPhase) {            tvar = new TypeVar(name, currentOwner, syms.botType);            typevars.enter(tvar.tsym);        } else {            tvar = (TypeVar)findTypeVar(name);        }        List<Type> bounds = List.nil();        Type st = null;        if (signature[sigp] == ':' && signature[sigp+1] == ':') {            sigp++;            st = syms.objectType;        }        while (signature[sigp] == ':') {            sigp++;            bounds = bounds.prepend(sigToType());        }        if (!sigEnterPhase) {            types.setBounds(tvar, bounds.reverse(), st);        }        return tvar;    }    /** Find type variable with given name in `typevars' scope.     */    Type findTypeVar(Name name) {        Scope.Entry e = typevars.lookup(name);        if (e.scope != null) {            return e.sym.type;        } 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.                TypeVar t = new TypeVar(name, currentOwner, syms.botType);                missingTypeVariables = missingTypeVariables.prepend(t);                // System.err.println("Missing type var " + name);                return t;            }            throw badClassFile("undecl.type.var", name);        }    }/************************************************************************ * Reading Attributes ***********************************************************************/    /** Report unrecognized attribute.     */    void unrecognized(Name attrName) {        if (checkClassFile)            printCCF("ccf.unrecognized.attribute", attrName);    }    /** Read member attribute.     */    void readMemberAttr(Symbol sym, Name attrName, int attrLen) {        //- System.err.println(" z " + sym + ", " + attrName + ", " + attrLen);        if (attrName == names.ConstantValue) {            Object v = readPool(nextChar());            // Ignore ConstantValue attribute if field not final.            if ((sym.flags() & FINAL) != 0)                ((VarSymbol)sym).setData(v);        } else if (attrName == names.Code) {            if (readAllOfClassFile || saveParameterNames)                ((MethodSymbol)sym).code = readCode(sym);            else                bp = bp + attrLen;        } else if (attrName == names.Exceptions) {            int nexceptions = nextChar();            List<Type> thrown = List.nil();            for (int j = 0; j < nexceptions; j++)                thrown = thrown.prepend(readClassSymbol(nextChar()).type);            if (sym.type.getThrownTypes().isEmpty())                sym.type.asMethodType().thrown = thrown.reverse();        } else if (attrName == names.Synthetic) {            // bridge methods are visible when generics not enabled            if (allowGenerics || (sym.flags_field & BRIDGE) == 0)                sym.flags_field |= SYNTHETIC;        } else if (attrName == names.Bridge) {            sym.flags_field |= BRIDGE;            if (!allowGenerics)                sym.flags_field &= ~SYNTHETIC;        } else if (attrName == names.Deprecated) {            sym.flags_field |= DEPRECATED;        } else if (attrName == names.Varargs) {            if (allowVarargs) sym.flags_field |= VARARGS;        } else if (attrName == names.Annotation) {            if (allowAnnotations) sym.flags_field |= ANNOTATION;        } else if (attrName == names.Enum) {            sym.flags_field |= ENUM;        } else if (allowGenerics && attrName == names.Signature) {            List<Type> thrown = sym.type.getThrownTypes();            sym.type = readType(nextChar());            //- System.err.println(" # " + sym.type);            if (sym.kind == MTH && sym.type.getThrownTypes().isEmpty())                sym.type.asMethodType().thrown = thrown;        } else if (attrName == names.RuntimeVisibleAnnotations) {            attachAnnotations(sym);        } else if (attrName == names.RuntimeInvisibleAnnotations) {            attachAnnotations(sym);        } else if (attrName == names.RuntimeVisibleParameterAnnotations) {            attachParameterAnnotations(sym);        } else if (attrName == names.RuntimeInvisibleParameterAnnotations) {            attachParameterAnnotations(sym);        } else if (attrName == names.LocalVariableTable) {            int newbp = bp + attrLen;            if (saveParameterNames) {                // pick up parameter names from the variable table                List<Name> parameterNames = List.nil();                int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;                int endParam = firstParam + Code.width(sym.type.getParameterTypes());                int numEntries = nextChar();                for (int i=0; i<numEntries; i++) {                    int start_pc = nextChar();                    int length = nextChar();                    int nameIndex = nextChar();                    int sigIndex = nextChar();                    int register = nextChar();                    if (start_pc == 0 &&                        firstParam <= register &&                        register < endParam) {                        int index = firstParam;                        for (Type t : sym.type.getParameterTypes()) {                            if (index == register) {                                parameterNames = parameterNames.prepend(readName(nameIndex));                                break;                            }                            index += Code.width(t);                        }                    }                }                parameterNames = parameterNames.reverse();                ((MethodSymbol)sym).savedParameterNames = parameterNames;            }            bp = newbp;        } else if (attrName == names.AnnotationDefault) {            attachAnnotationDefault(sym);        } else if (attrName == names.EnclosingMethod) {            int newbp = bp + attrLen;            readEnclosingMethodAttr(sym);            bp = newbp;        } else {            unrecognized(attrName);            bp = bp + attrLen;        }    }    void readEnclosingMethodAttr(Symbol sym) {        // 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        sym.owner.members().remove(sym);        ClassSymbol self = (ClassSymbol)sym;        ClassSymbol c = readClassSymbol(nextChar());        NameAndType nt = (NameAndType)readPool(nextChar());        MethodSymbol m = findMethod(nt, c.members_field, self.flags());        if (nt != null && m == null)            throw badClassFile("bad.enclosing.method", self);        self.name = simpleBinaryName(self.flatname, c.flatname) ;        self.owner = m != null ? m : c;        if (self.name.len == 0)            self.fullname = null;        else            self.fullname = ClassSymbol.formFullName(self.name, self.owner);        if (m != null) {            ((ClassType)sym.type).setEnclosingType(m.type);        } else if ((self.flags_field & STATIC) == 0) {            ((ClassType)sym.type).setEnclosingType(c.type);        } else {            ((ClassType)sym.type).setEnclosingType(Type.noType);        }        enterTypevars(self);        if (!missingTypeVariables.isEmpty()) {            ListBuffer<Type> typeVars =  new ListBuffer<Type>();            for (Type typevar : missingTypeVariables) {                typeVars.append(findTypeVar(typevar.tsym.name));            }            foundTypeVariables = typeVars.toList();        } else {            foundTypeVariables = List.nil();        }    }    // See java.lang.Class    private Name simpleBinaryName(Name self, Name enclosing) {        String simpleBinaryName = self.toString().substring(enclosing.toString().length());        if (simpleBinaryName.length() < 1 || simpleBinaryName.charAt(0) != '$')            throw badClassFile("bad.enclosing.method", self);        int index = 1;        while (index < simpleBinaryName.length() &&               isAsciiDigit(simpleBinaryName.charAt(index)))            index++;        return names.fromString(simpleBinaryName.substring(index));    }    private MethodSymbol findMethod(NameAndType nt, Scope scope, long flags) {        if (nt == null)            return null;        MethodType type = nt.type.asMethodType();        for (Scope.Entry e = scope.lookup(nt.name); e.scope != null; e = e.next())            if (e.sym.kind == MTH && isSameBinaryType(e.sym.type.asMethodType(), type))                return (MethodSymbol)e.sym;        if (nt.name != names.init)            // not a constructor            return null;        if ((flags & INTERFACE) != 0)            // no enclosing instance            return null;        if (nt.type.getParameterTypes().isEmpty())            // no parameters            return null;        // A constructor of an inner class.        // Remove the first argument (the enclosing instance)        nt.type = new MethodType(nt.type.getParameterTypes().tail,                                 nt.type.getReturnType(),                                 nt.type.getThrownTypes(),                                 syms.methodClass);        // Try searching again        return findMethod(nt, scope, flags);    }    /** Similar to Types.isSameType but avoids completion */    private boolean isSameBinaryType(MethodType mt1, MethodType mt2) {        List<Type> types1 = types.erasure(mt1.getParameterTypes())            .prepend(types.erasure(mt1.getReturnType()));        List<Type> types2 = mt2.getParameterTypes().prepend(mt2.getReturnType());        while (!types1.isEmpty() && !types2.isEmpty()) {            if (types1.head.tsym != types2.head.tsym)                return false;            types1 = types1.tail;            types2 = types2.tail;        }        return types1.isEmpty() && types2.isEmpty();    }    /**     * 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.     */    void readMemberAttrs(Symbol sym) {        char ac = nextChar();        for (int i = 0; i < ac; i++) {            Name attrName = readName(nextChar());            int attrLen = nextInt();            readMemberAttr(sym, attrName, attrLen);        }    }    /** Read class attribute.     */    void readClassAttr(ClassSymbol c, Name attrName, int attrLen) {        if (attrName == names.SourceFile) {            Name n = readName(nextChar());            c.sourcefile = new SourceFileObject(n);        } else if (attrName == names.InnerClasses) {            readInnerClasses(c);        } else if (allowGenerics && attrName == names.Signature) {            readingClassAttr = true;            try {                ClassType ct1 = (ClassType)c.type;                assert c == currentOwner;                ct1.typarams_field = readTypeParams(nextChar());                ct1.supertype_field = sigToType();                ListBuffer<Type> is = new ListBuffer<Type>();                while (sigp != siglimit) is.append(sigToType());                ct1.interfaces_field = is.toList();            } finally {                readingClassAttr = false;            }        } else {            readMemberAttr(c, attrName, attrLen);        }    }    private boolean readingClassAttr = false;    private List<Type> missingTypeVariables = List.nil();    private List<Type> foundTypeVariables = List.nil();    /** Read class attributes.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -