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

📄 classreader.java

📁 java编译器gjc源码 java编译环境
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/**
 * @(#)ClassReader.java	1.55 03/01/23
 *
 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.sun.tools.javac.v8.code;
import com.sun.tools.javac.v8.util.*;

import java.io.*;

import java.util.zip.*;

import java.util.StringTokenizer;

import com.sun.tools.javac.v8.code.Type.*;

import com.sun.tools.javac.v8.code.Symbol.*;

import com.sun.tools.javac.v8.code.Symtab;


/**
 * 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.
 */
public class ClassReader extends ClassFile implements Completer, Flags, Kinds,
TypeTags {

    /**
     * The context key for the class reader.
     */
    private static final Context.Key classReaderKey = new Context.Key();

    /**
     * The string used as separator in class paths.
     */
    public static final String pathSep = System.getProperty("path.separator");

    /**
     * Switch: verbose output.
     */
    public boolean verbose;

    /**
     * Switch: check class file for correct minor version, unrecognized
     *  attributes.
     */
    public 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;

    /**
     * The log to use for verbose output
     */
    private final Log log;

    /**
     * The symbol table.
     */
    private final Symtab syms;

    /**
     * The name table.
     */
    protected final Name.Table names;

    /**
     * Force a completion failure on this name
     */
    final Name completionFailureName;

    /**
     * Can be reassigned from outside:
     *  the class path to be searched for user classes.
     */
    public String classPath;

    /**
     * The class path to be searched for system classes.
     */
    public String bootClassPath;

    /**
     * The path to be searched for sources
     */
    public String sourceClassPath;

    /**
     * Can be reassigned from outside:
     *  the completer to be used for ".java" files. If this remains unassigned
     *  ".java" files will not be loaded.
     */
    public SourceCompleter sourceCompleter = null;

    /**
     * A hashtable containing the encountered top-level and member classes,
     *  indexed by flat names. The table does not contain local classes.
     */
    private Hashtable classes;

    /**
     * A hashtable containing the encountered packages.
     */
    private Hashtable packages;

    /**
     * The current scope where type variables are entered.
     */
    Scope typevars = new Scope(null);

    /**
     * The path name of the class file currently being read.
     */
    String currentClassFileName = null;

    /**
     * The class or method currently being read.
     */
    Symbol currentOwner = null;

    /**
     * The buffer containing the currently read class file.
     */
    byte[] buf = new byte[65520];

    /**
     * The current input pointer.
     */
    int bp;

    /**
     * The objects of the constant pool.
     */
    Object[] poolObj;

    /**
     * For every constant pool entry, an index into buf where the
     *  defining section of the entry is found.
     */
    int[] poolIdx;

    /**
     * Get the ClassReader instance for this invocation.
     */
    public static ClassReader instance(Context context) {
        ClassReader instance = (ClassReader) context.get(classReaderKey);
        if (instance == null)
            instance = new ClassReader(context, true);
        return instance;
    }

    /**
      * Initialize classes and packages, treating this as the definitive classreader.
      */
    public void init(Symtab syms) {
        init(syms, true);
    }

    /**
      * Initialize classes and packages, optionally treating this as
      *  the definitive classreader.
      */
    private void init(Symtab syms, boolean definitive) {
        if (classes != null)
            return;
        if (definitive) {
            assert packages == null || packages == syms.packages;
            packages = syms.packages;
            assert classes == null || classes == syms.classes;
            classes = syms.classes;
        } else {
            packages = new Hashtable();
            classes = new Hashtable();
        }
        packages.put(syms.rootPackage.fullname, syms.rootPackage);
        syms.rootPackage.completer = this;
        packages.put(syms.emptyPackage.fullname, syms.emptyPackage);
        syms.emptyPackage.completer = this;
    }

    /**
      * Construct a new class reader, optionally treated as the
      *  definitive classreader for this invocation.
      */
    protected ClassReader(Context context, boolean definitive) {
        super();
        if (definitive)
            context.put(classReaderKey, this);
        names = Name.Table.instance(context);
        syms = Symtab.instance(context);
        init(syms, definitive);
        log = Log.instance(context);
        Options options = Options.instance(context);
        verbose = options.get("-verbose") != null;
        checkClassFile = options.get("-checkclassfile") != null;
        setClassPaths(options);
        completionFailureName = (options.get("failcomplete") != null) ?
                names.fromString((String) options.get("failcomplete")) : null;
    }

    /**
      * Set classPath, bootClassPath, and sourceClassPath.
      */
    private void setClassPaths(Options options) {
        String cp = (String) options.get("-classpath");
        if (cp == null)
            cp = System.getProperty("env.class.path");
        if (cp == null && System.getProperty("application.home") == null)
            cp = System.getProperty("java.class.path");
        if (cp == null)
            cp = ".";
        classPath = terminate(cp);
        String bp = (String) options.get("-bootclasspath");
        if (bp == null) {
            bp = System.getProperty("sun.boot.class.path");
            if (bp == null)
                bp = System.getProperty("java.class.path");
            if (bp == null)
                bp = ".";
        }
        String bpp = (String) options.get("-Xbootclasspath/p:");
        if (bpp != null)
            bp = bpp + System.getProperty("path.separator") + bp;
        bootClassPath = terminate(bp);
        String ed = (String) options.get("-extdirs");
        if (ed == null)
            ed = System.getProperty("java.ext.dirs");
        if (ed == null)
            ed = "";
        String extdirs = terminate(ed);
        int i = 0;
        int edlen = extdirs.length();
        while (i < edlen) {
            int end = extdirs.indexOf(pathSep, i);
            String extdir = extdirs.substring(i, end);
            addArchives(extdir);
            i = end + 1;
        }
        String sp = (String) options.get("-sourcepath");
        if (sp != null) {
            sourceClassPath = terminate(sp);
        } else {
            sourceClassPath = null;
        }
    }

    /**
      * Add all archives in `extdir' to boot class path
      */
    private void addArchives(String extdir) {
        String[] archives = new File(extdir).list();
        for (int i = 0; archives != null && i < archives.length; i++) {
            if (archives[i].endsWith(".jar")) {
                String prefix = (extdir.endsWith(File.separator)) ? extdir :
                        (extdir + File.separator);
                bootClassPath = bootClassPath + prefix + archives[i] + pathSep;
            }
        }
    }

    /**
      * Add path separator to string if it does not end in one already
      */
    private String terminate(String s) {
        return (s.endsWith(pathSep)) ? s : s + pathSep;
    }

    /**
      * Add member to class unless it is synthetic
      */
    private void enterMember(ClassSymbol c, Symbol sym) {
        if ((sym.flags_field & SYNTHETIC) == 0)
            c.members_field.enter(sym);
    }

    /**
      * Error Diagnoses
      */
    public static class BadClassFile extends CompletionFailure {

        /**
         * @param msg A localized message.
         */
        public BadClassFile(ClassSymbol c, String cname, String msg) {
            super(c, Log.getLocalizedString("bad.class.file.header", cname, msg));
        }
    }

    public BadClassFile badClassFile(String key) {
        return new BadClassFile(currentOwner.enclClass(), currentClassFileName,
                Log.getLocalizedString(key));
    }

    public BadClassFile badClassFile(String key, String arg0) {
        return new BadClassFile(currentOwner.enclClass(), currentClassFileName,
                Log.getLocalizedString(key, arg0));
    }

    public BadClassFile badClassFile(String key, String arg0, String arg1) {
        return new BadClassFile(currentOwner.enclClass(), currentClassFileName,
                Log.getLocalizedString(key, arg0, arg1));
    }

    public BadClassFile badClassFile(String key, String arg0, String arg1,
            String arg2) {
        return new BadClassFile(currentOwner.enclClass(), currentClassFileName,
                Log.getLocalizedString(key, arg0, arg1, arg2));
    }

    public BadClassFile badClassFile(String key, String arg0, String arg1,
            String arg2, String arg3) {
        return new BadClassFile(currentOwner.enclClass(), currentClassFileName,
                Log.getLocalizedString(key, arg0, arg1, arg2, arg3));
    }

    /**
      * Read a character.
      */
    char nextChar() {
        return (char)(((buf[bp++] & 255)<< 8) + (buf[bp++] & 255));
    }

    /**
      * Read an integer.
      */
    int nextInt() {
        return ((buf[bp++] & 255)<< 24) + ((buf[bp++] & 255)<< 16) +
                ((buf[bp++] & 255)<< 8) + (buf[bp++] & 255);
    }

    /**
      * Extract a character at position bp from buf.
      */
    char getChar(int bp) {
        return (char)(((buf[bp] & 255)<< 8) + (buf[bp + 1] & 255));
    }

    /**
      * Extract an integer at position bp from buf.
      */
    int getInt(int bp) {
        return ((buf[bp] & 255)<< 24) + ((buf[bp + 1] & 255)<< 16) +
                ((buf[bp + 2] & 255)<< 8) + (buf[bp + 3] & 255);
    }

    /**
      * Extract a long integer at position bp from buf.
      */
    long getLong(int bp) {
        DataInputStream bufin =
                new DataInputStream(new ByteArrayInputStream(buf, bp, 8));
        try {
            return bufin.readLong();
        } catch (IOException e) {
            throw new AssertionError();
        }
    }

    /**
      * Extract a float at position bp from buf.
      */
    float getFloat(int bp) {
        DataInputStream bufin =
                new DataInputStream(new ByteArrayInputStream(buf, bp, 4));
        try {
            return bufin.readFloat();
        } catch (IOException e) {
            throw new AssertionError();
        }
    }

    /**
      * Extract a double at position bp from buf.
      */
    double getDouble(int bp) {
        DataInputStream bufin =
                new DataInputStream(new ByteArrayInputStream(buf, bp, 8));
        try {
            return bufin.readDouble();
        } catch (IOException e) {
            throw new AssertionError();
        }
    }

    /**
      * Index all constant pool entries, writing their start addresses into
      *  poolIdx.
      */
    void indexPool() {
        poolIdx = new int[nextChar()];
        poolObj = new Object[poolIdx.length];
        int i = 1;
        while (i < poolIdx.length) {
            poolIdx[i++] = bp;
            byte tag = buf[bp++];
            switch (tag) {
            case CONSTANT_Utf8:

            case CONSTANT_Unicode:
                {
                    int len = nextChar();
                    bp = bp + len;
                    break;
                }

            case CONSTANT_Class:

            case CONSTANT_String:
                bp = bp + 2;
                break;

            case CONSTANT_Fieldref:

            case CONSTANT_Methodref:

            case CONSTANT_InterfaceMethodref:

            case CONSTANT_NameandType:

            case CONSTANT_Integer:

            case CONSTANT_Float:
                bp = bp + 4;
                break;

            case CONSTANT_Long:

            case CONSTANT_Double:
                bp = bp + 8;
                i++;
                break;

            default:
                throw badClassFile("bad.const.pool.tag.at", Byte.toString(tag),
                        Integer.toString(bp - 1));

            }
        }
    }

    /**
      * Read constant pool entry at start address i, use pool as a cache.
      */
    Object readPool(int i) {
        Object result = poolObj[i];
        if (result != null)
            return result;
        int index = poolIdx[i];
        if (index == 0)
            return null;
        byte tag = buf[index];
        switch (tag) {
        case CONSTANT_Utf8:
            poolObj[i] = names.fromUtf(buf, index + 3, getChar(index + 1));
            break;

        case CONSTANT_Unicode:

⌨️ 快捷键说明

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