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

📄 classwriter.java

📁 这是实现Javac功能的GJC的最新源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            return sym.name;    }    /**      * Given a symbol, return its name-and-type.      */    NameAndType nameType(Symbol sym) {        return new NameAndType(fieldName(sym),                retrofit ? sym.erasure() : sym.externalType());    }    /**      * Write header for an attribute to data buffer and return      *  position past attribute length index.      */    int writeAttr(Name attrName) {        databuf.appendChar(pool.put(attrName));        databuf.appendInt(0);        return databuf.length;    }    /**      * Fill in attribute length.      */    void endAttr(int index) {        putInt(databuf, index - 4, databuf.length - index);    }    /**      * Leave space for attribute count and return index for      *  number of attributes field.      */    int beginAttrs() {        databuf.appendChar(0);        return databuf.length;    }    /**      * Fill in number of attributes.      */    void endAttrs(int index, int count) {        putChar(databuf, index - 2, count);    }    /**      * Write flag attributes; return number of attributes written.      */    int writeFlagAttrs(long flags) {        int acount = 0;        if ((flags & DEPRECATED) != 0) {            int alenIdx = writeAttr(names.Deprecated);            endAttr(alenIdx);            acount++;        }        if ((flags & SYNTHETIC) != 0) {            int alenIdx = writeAttr(names.Synthetic);            endAttr(alenIdx);            acount++;        }        return acount;    }    /**      * Write member (field or method) attributes;      *  return number of attributes written.      */    int writeMemberAttrs(Symbol sym) {        int acount = writeFlagAttrs(sym.flags());        return acount;    }    /**      * Enter an inner class into the `innerClasses' set/queue.      */    void enterInner(ClassSymbol c) {        assert (c.flags() & COMPOUND) == 0;        if (c.type.tag != CLASS)            return;        if (pool != null && c.owner.kind != PCK &&                (innerClasses == null || !innerClasses.contains(c))) {            if (c.owner.kind == TYP)                enterInner((ClassSymbol) c.owner);            pool.put(c);            pool.put(c.name);            if (innerClasses == null) {                innerClasses = Set.make();                innerClassesQueue = new ListBuffer();                pool.put(names.InnerClasses);            }            innerClasses.put(c);            innerClassesQueue.append(c);        }    }    /**      * Write "inner classes" attribute.      */    void writeInnerClasses() {        int alenIdx = writeAttr(names.InnerClasses);        databuf.appendChar(innerClassesQueue.length());        for (List l = innerClassesQueue.toList(); l.nonEmpty(); l = l.tail) {            ClassSymbol inner = (ClassSymbol) l.head;            if (dumpInnerClassModifiers) {                log.errWriter.println("INNERCLASS  " + inner.name);                log.errWriter.println("---" + flagNames(inner.flags_field));            }            databuf.appendChar(pool.get(inner));            databuf.appendChar(inner.owner.kind == TYP ? pool.get(inner.owner) : 0);            databuf.appendChar(inner.name.len != 0 ? pool.get(inner.name) : 0);            databuf.appendChar((int) inner.flags_field);        }        endAttr(alenIdx);    }    /**      * Write field symbol, entering all references into constant pool.      */    void writeField(VarSymbol v) {        databuf.appendChar((int) v.flags());        if (dumpFieldModifiers) {            log.errWriter.println("FIELD  " + fieldName(v));            log.errWriter.println("---" + flagNames(v.flags()));        }        databuf.appendChar(pool.put(fieldName(v)));        databuf.appendChar(pool.put(typeSig(v.erasure())));        int acountIdx = beginAttrs();        int acount = 0;        if (v.constValue != null) {            int alenIdx = writeAttr(names.ConstantValue);            databuf.appendChar(pool.put(v.constValue));            endAttr(alenIdx);            acount++;        }        acount += writeMemberAttrs(v);        endAttrs(acountIdx, acount);    }    /**      * Write method symbol, entering all references into constant pool.      */    void writeMethod(MethodSymbol m) {        databuf.appendChar((int) m.flags());        if (dumpMethodModifiers) {            log.errWriter.println("METHOD  " + fieldName(m));            log.errWriter.println("---" + flagNames(m.flags()));        }        databuf.appendChar(pool.put(fieldName(m)));        databuf.appendChar(pool.put(typeSig(m.externalType())));        int acountIdx = beginAttrs();        int acount = 0;        if (m.code != null) {            int alenIdx = writeAttr(names.Code);            writeCode(m.code);            m.code = null;            endAttr(alenIdx);            acount++;        }        List thrown = m.erasure().thrown();        if (thrown.nonEmpty()) {            int alenIdx = writeAttr(names.Exceptions);            databuf.appendChar(thrown.length());            for (List l = thrown; l.nonEmpty(); l = l.tail)                databuf.appendChar(pool.put(((Type) l.head).tsym));            endAttr(alenIdx);            acount++;        }        acount += writeMemberAttrs(m);        endAttrs(acountIdx, acount);    }    /**      * Write code attribute of method.      */    void writeCode(Code code) {        databuf.appendChar(code.max_stack);        databuf.appendChar(code.max_locals);        databuf.appendInt(code.cp);        databuf.appendBytes(code.code, 0, code.cp);        databuf.appendChar(code.catchInfo.length());        for (List l = code.catchInfo.toList(); l.nonEmpty(); l = l.tail) {            for (int i = 0; i < ((char[]) l.head).length; i++)                databuf.appendChar(((char[]) l.head)[i]);        }        int acountIdx = beginAttrs();        int acount = 0;        if (code.lineInfo.nonEmpty()) {            int alenIdx = writeAttr(names.LineNumberTable);            databuf.appendChar(code.lineInfo.length());            for (List l = code.lineInfo.reverse(); l.nonEmpty(); l = l.tail)                for (int i = 0; i < ((char[]) l.head).length; i++)                    databuf.appendChar(((char[]) l.head)[i]);            endAttr(alenIdx);            acount++;        }        if (genCrt && (code.crt != null)) {            CRTable crt = code.crt;            int alenIdx = writeAttr(names.CharacterRangeTable);            int crtIdx = beginAttrs();            int crtEntries = crt.writeCRT(databuf);            endAttrs(crtIdx, crtEntries);            endAttr(alenIdx);            acount++;        }        if (code.varBufferSize > 0) {            int alenIdx = writeAttr(names.LocalVariableTable);            int nvars = code.varBufferSize;            databuf.appendChar(nvars);            for (int i = 0; i < nvars; i++) {                Code.LocalVar var = code.varBuffer[i];                assert var.start_pc >= 0;                assert var.start_pc <= code.cp;                databuf.appendChar(var.start_pc);                assert var.length >= 0;                assert (var.start_pc + var.length) <= code.cp;                databuf.appendChar(var.length);                VarSymbol sym = var.var;                databuf.appendChar(pool.put(sym.name));                databuf.appendChar(pool.put(typeSig(sym.erasure())));                databuf.appendChar(var.reg);            }            endAttr(alenIdx);            acount++;        }        endAttrs(acountIdx, acount);    }    void writeFields(Scope.Entry e) {        List vars = List.make();        for (Scope.Entry i = e; i != null; i = i.sibling) {            if (i.sym.kind == VAR)                vars = vars.prepend((VarSymbol) i.sym);        }        while (vars.nonEmpty()) {            writeField((VarSymbol) vars.head);            vars = vars.tail;        }    }    void writeMethods(Scope.Entry e) {        List methods = List.make();        for (Scope.Entry i = e; i != null; i = i.sibling) {            if (i.sym.kind == MTH)                methods = methods.prepend((MethodSymbol) i.sym);        }        while (methods.nonEmpty()) {            writeMethod((MethodSymbol) methods.head);            methods = methods.tail;        }    }    /**      * Emit a class file for a given class.      *  @param c      The class from which a class file is generated.      */    public void writeClass(ClassSymbol c) throws IOException, PoolOverflow,    StringOverflow {        File outFile = outputFile(c, ".class");        OutputStream out = new FileOutputStream(outFile);        try {            writeClassFile(out, c);            if (verbose)                log.errWriter.println( log.getLocalizedString("verbose.wrote.file",                        outFile.getPath()));            out.close();            out = null;        }        finally { if (out != null) {                      out.close();                      outFile.delete();                      out = null;                  }                } }    /**      * Write class `c' to outstream `out'.      */    public void writeClassFile(OutputStream out,            ClassSymbol c) throws IOException, PoolOverflow, StringOverflow {        assert (c.flags() & COMPOUND) == 0;        databuf.reset();        poolbuf.reset();        sigbuf.reset();        pool = c.pool;        innerClasses = null;        innerClassesQueue = null;        Type supertype = c.type.supertype();        List interfaces = c.type.interfaces();        long flags = c.flags();        if ((flags & PROTECTED) != 0)            flags |= PUBLIC;        flags = flags & ClassFlags & ~STRICTFP;        if ((flags & INTERFACE) == 0)            flags |= ACC_SUPER;        if (dumpClassModifiers) {            log.errWriter.println();            log.errWriter.println("CLASSFILE  " + c.fullName());            log.errWriter.println("---" + flagNames(flags));        }        databuf.appendChar((int) flags);        databuf.appendChar(pool.put(c));        databuf.appendChar(supertype.tag == CLASS ? pool.put(supertype.tsym) : 0);        databuf.appendChar(interfaces.length());        for (List l = interfaces; l.nonEmpty(); l = l.tail)            databuf.appendChar(pool.put(((Type) l.head).tsym));        int fieldsCount = 0;        int methodsCount = 0;        for (Scope.Entry e = c.members().elems; e != null; e = e.sibling) {            switch (e.sym.kind) {            case VAR:                fieldsCount++;                break;            case MTH:                methodsCount++;                break;            case TYP:                enterInner((ClassSymbol) e.sym);                break;            default:                assert false;            }        }        databuf.appendChar(fieldsCount);        writeFields(c.members().elems);        databuf.appendChar(methodsCount);        writeMethods(c.members().elems);        int acountIdx = beginAttrs();        int acount = 0;        if (c.sourcefile != null && emitSourceFile) {            int alenIdx = writeAttr(names.SourceFile);            String filename = c.sourcefile.toString();            int sepIdx = filename.lastIndexOf(File.separatorChar);            int slashIdx = filename.lastIndexOf('/');            if (slashIdx > sepIdx)                sepIdx = slashIdx;            if (sepIdx >= 0)                filename = filename.substring(sepIdx + 1);            databuf.appendChar(c.pool.put(names.fromString(filename)));            endAttr(alenIdx);            acount++;        }        if (genCrt) {            int alenIdx = writeAttr(names.SourceID);            databuf.appendChar( c.pool.put(                    names.fromString(Long.toString(getLastModified(c.sourcefile)))));            endAttr(alenIdx);            acount++;            alenIdx = writeAttr(names.CompilationID);            databuf.appendChar( c.pool.put(                    names.fromString(Long.toString(System.currentTimeMillis()))));            endAttr(alenIdx);            acount++;        }        acount += writeFlagAttrs(c.flags());        poolbuf.appendInt(JAVA_MAGIC);        poolbuf.appendChar(target.minorVersion);        poolbuf.appendChar(target.majorVersion);        writePool(c.pool);        if (innerClasses != null) {            writeInnerClasses();            acount++;        }        endAttrs(acountIdx, acount);        poolbuf.appendBytes(databuf.elems, 0, databuf.length);        out.write(poolbuf.elems, 0, poolbuf.length);        pool = c.pool = null;    }    /**      * Get modification date of file entry with name filename      */    long getLastModified(Name filename) {        long mod = 0;        File file = new File(filename.toString());        try {            mod = file.lastModified();        } catch (SecurityException e) {            throw new AssertionError(                    "CRT: couldn\'t get source file modification date: " +                    e.getMessage());        }        return mod;    }    /**      * Create output file with given extension for given class.      */    public File outputFile(ClassSymbol c, String extension) throws IOException {        if (outDir == null) {            String filename = Convert.shortName(c.flatname) + extension;            if (c.sourcefile == null)                return new File(filename);            String sourcedir = new File(c.sourcefile.toString()).getParent();            if (sourcedir == null)                return new File(filename);            else                return new File(sourcedir, filename);        } else {            return outputFile(outDir, c.flatname.toString(), extension);        }    }    /**      * open file given by a fully qualified name from root directory `outdir'.      *  create intermediate directories if they don't exist already      */    File outputFile(File outdir, String name, String extension) throws IOException {        int start = 0;        int end = name.indexOf('.');        while (end >= start) {            outdir = new File(outdir, name.substring(start, end));            if (!outdir.exists())                outdir.mkdir();            start = end + 1;            end = name.indexOf('.', start);        }        return new File(outdir, name.substring(start) + extension);    }}

⌨️ 快捷键说明

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