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

📄 classreader.java

📁 这是实现Javac功能的GJC的最新源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        } else if (checkClassFile && majorVersion == Target.MAX().majorVersion &&                minorVersion > Target.MAX().minorVersion) {            printCCF("found.later.version", Integer.toString(minorVersion));        }        indexPool();        readClass(c);    }    /**      * Is this the name of a zip file?      */    boolean isZip(String name) {        return new File(name).isFile();    }    /**      * An archive consists of a zipfile and a list of zip entries in      *  that file.      */    static class Archive {        ZipFile zdir;        List entries;        Archive(ZipFile zdir, List entries) {            super();            this.zdir = zdir;            this.entries = entries;        }    }    /**      * A directory of zip files already opened.      */    Hashtable archives = Hashtable.make();    /**     * Open a new zip file directory.     */    Archive openArchive(String dirname) throws IOException {        Archive archive = (ClassReader.Archive) archives.get(dirname);        if (archive == null) {            ZipFile zdir = new ZipFile(dirname);            ListBuffer entries = new ListBuffer();            for (java.util.Enumeration e = zdir.entries(); e.hasMoreElements();) {                entries.append((ZipEntry) e.nextElement());            }            archive = new Archive(zdir, entries.toList());            archives.put(dirname, archive);        }        return archive;    }    /**      * Close the ClassReader, releasing resources.      */    public void close() {        for (List dirnames = archives.keys(); dirnames.nonEmpty();                dirnames = dirnames.tail) {            Archive a = (ClassReader.Archive) archives.remove(dirnames.head);            try {                a.zdir.close();            } catch (IOException e) {            }        }    }    /**      * Define a new class given its name and owner.      */    public ClassSymbol defineClass(Name name, Symbol owner) {        ClassSymbol c = new ClassSymbol(0, name, owner);        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 = (ClassSymbol) 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.name = name;            c.owner = owner;            c.fullname = ClassSymbol.formFullName(name, owner);        }        return c;    }    /**      * 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 = (ClassSymbol) classes.get(flatname);        if (c == null) {            Name packageName = Convert.packagePart(flatname);            if (packageName == names.empty)                packageName = names.emptyPackage;            c = defineClass(Convert.shortName(flatname), enterPackage(packageName));            classes.put(flatname, c);        }        return c;    }    /**      * 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);            c.owner.complete();            fillIn(c);        } else if (sym.kind == PCK) {            PackageSymbol p = (PackageSymbol) sym;            fillIn(p);        }    }    /**      * We can only read a single class file at a time; this      * flag keeps track of when we are currently reading a class      * file.      */    private boolean filling = false;    /**     * Fill in definition of class `c' from corresponding class or     *  source file.     */    private void fillIn(ClassSymbol c) {        if (completionFailureName == c.fullname) {            throw new CompletionFailure(c, "user-selected completion failure by class name");        }        currentOwner = c;        FileEntry classfile = c.classfile;        if (classfile != null) {            try {                assert ! filling;                InputStream s = classfile.open();                currentClassFileName = classfile.getPath();                if (verbose) {                    printVerbose("loading", currentClassFileName);                }                if (classfile.getName().endsWith(".class")) {                    filling = true;                    int size = (int) classfile.length();                    if (buf.length < size)                        buf = new byte[size];                    int n = 0;                    while (n < size)                        n = n + s.read(buf, n, size - n);                    s.close();                    bp = 0;                    readClassFile(c);                } else {                    sourceCompleter.complete(c, currentClassFileName, s);                }                return;            } catch (IOException ex) {                throw badClassFile("unable.to.access.file", ex.getMessage());            }            finally { filling = false;                } } else {            String fn = externalizeFileName(c.flatname);            throw newCompletionFailure(c,                    Log.getLocalizedString("dot.class.not.found", fn));        }    }    /**      * Static factory for CompletionFailure objects.      *  In practice, only one can be used at a time, so we share one      *  to reduce the expense of allocating new exception objects.      */    private CompletionFailure newCompletionFailure(ClassSymbol c, String localized) {        CompletionFailure result = cachedCompletionFailure;        result.sym = c;        result.errmsg = localized;        return result;    }    private CompletionFailure cachedCompletionFailure =            new CompletionFailure(null, null);    /**     * Load a toplevel class with given fully qualified name     *  The class is entered into `classes' only if load was successful.     */    public ClassSymbol loadClass(Name flatname) throws CompletionFailure {        boolean absent = classes.get(flatname) == null;        ClassSymbol c = enterClass(flatname);        if (c.members_field == null && c.completer != null) {            try {                c.complete();            } catch (CompletionFailure ex) {                if (absent)                    classes.remove(flatname);                throw ex;            }        }        return c;    }    /**      * Check to see if a package exists, given its fully qualified name.      */    public boolean packageExists(Name fullname) {        return enterPackage(fullname).exists();    }    /**      * Make a package, given its fully qualified name.      */    public PackageSymbol enterPackage(Name fullname) {        PackageSymbol p = (PackageSymbol) packages.get(fullname);        if (p == null) {            assert fullname.length() != 0 :            "rootPackage missing!";            p = new PackageSymbol(Convert.shortName(fullname),                    enterPackage(Convert.packagePart(fullname)));            p.completer = this;            packages.put(fullname, p);        }        return p;    }    /**      * Make a package, given its unqualified name and enclosing package.      */    public PackageSymbol enterPackage(Name name, PackageSymbol owner) {        return enterPackage(TypeSymbol.formFullName(name, owner));    }    /**      * Include class corresponding to given class file in package,      *  unless (1) we already have one the same kind (.class or .java), or      *         (2) we have one of the other kind, and the given class file      *             is older.      */    private void includeClassFile(PackageSymbol p, FileEntry file) {        if ((p.flags_field & EXISTS) == 0)            for (Symbol q = p; q != null && q.kind == PCK; q = q.owner)                q.flags_field |= EXISTS;        String filename = file.getName();        int seen;        int extlen;        if (filename.endsWith(".class")) {            seen = CLASS_SEEN;            extlen = 6;        } else {            seen = SOURCE_SEEN;            extlen = 5;        }        Name classname =                names.fromString(filename.substring(0, filename.length() - extlen));        ClassSymbol c = (ClassSymbol) p.members_field.lookup(classname).sym;        if (c == null) {            c = enterClass(classname, p);            c.classfile = file;            if (c.owner == p)                p.members_field.enter(c);        } else if (c.classfile != null && (c.flags_field & seen) == 0) {            if ((c.flags_field & (CLASS_SEEN | SOURCE_SEEN)) != 0) {                long fdate = file.lastModified();                long cdate = c.classfile.lastModified();                if (fdate >= 0 && cdate >= 0 && fdate > cdate) {                    c.classfile = file;                }            }        }        c.flags_field |= seen;    }    /**      * Insert all files in subdirectory `name' of `pathname'      *  which end in one of the extensions in `extensions' into package.      */    private void list(String pathname, String name, String[] extensions,            PackageSymbol p) {        try {            if (isZip(pathname)) {                Archive archive = openArchive(pathname);                if (name.length() != 0) {                    name = name.replace('\\', '/');                    if (!name.endsWith("/"))                        name = name + "/";                }                int namelen = name.length();                for (List l = archive.entries; l.nonEmpty(); l = l.tail) {                    ZipEntry entry = (ZipEntry) l.head;                    String ename = entry.getName();                    if (ename.startsWith(name)) {                        if (endsWith(ename, extensions)) {                            String suffix = ename.substring(namelen);                            if (suffix.length() > 0 && suffix.indexOf('/') < 0) {                                includeClassFile(p,                                        new FileEntry.Zipped(suffix,                                        archive.zdir, entry));                            }                        } else                            extraZipFileActions(p, ename, name, pathname);                    }                }            } else {                File f = name.length() != 0 ? new File(pathname, name) :                        new File(pathname);                String[] names = f.list();                if (names != null && caseMapCheck(f, name)) {                    for (int i = 0; i < names.length; i++) {                        String fname = names[i];                        if (isValidFile(fname, extensions)) {                            includeClassFile(p,                                    new FileEntry.Regular(fname, new File(f, fname)));                        } else                            extraFileActions(p, fname, f);                    }                }            }        } catch (IOException ex) {        }    }    private boolean endsWith(String s, String[] extensions) {        for (int i = 0; i < extensions.length; i++)            if (s.endsWith(extensions[i]))                return true;        return false;    }    private boolean isValidFile(String s, String[] extensions) {        for (int i = 0; i < extensions.length; i++) {            String extension = extensions[i];            if (s.endsWith(extension) && isJavaIdentifier(                    s.substring(0, s.length() - extension.length())))                return true;        }        return false;    }    private boolean isJavaIdentifier(String s) {        if (s.length() < 1)            return false;        if (!Character.isJavaIdentifierStart(s.charAt(0)))            return false;        for (int j = 1; j < s.length(); j++)            if (!Character.isJavaIdentifierPart(s.charAt(j)))                return false;        return true;    }    static final boolean fileSystemIsCaseSensitive = File.separatorChar == '/';    /**     * Hack to make Windows case sensitive. Test whether given path     *  ends in a string of characters with the same case as given name.     *  Ignore file separators in both path and name.     */    private boolean caseMapCheck(File f, String name) throws IOException {        if (fileSystemIsCaseSensitive)            return true;        String path = f.getCanonicalPath();        char[] pcs = path.toCharArray();        char[] ncs = name.toCharArray();        int i = pcs.length - 1;        int j = ncs.length - 1;        while (i >= 0 && j >= 0) {            while (i >= 0 && pcs[i] == File.separatorChar)                i--;            while (j >= 0 && ncs[j] == File.separatorChar)                j--;            if (i >= 0 && j >= 0) {                if (pcs[i] != ncs[j])                    return false;                i--;                j--;            }        }        return j < 0;    }    /**      * These are used to support javadoc      */    protected void extraZipFileActions(PackageSymbol pack, String zipEntryName,            String classPathName, String zipName) {    }    protected void extraFileActions(PackageSymbol pack, String fileName,            File fileDir) {    }    /**      * Insert all files in subdirectory `name' somewhere on      *  class path `path' which end in one of the extensions in `extensions'      *  into package.      */    private void listAll(String path, String name, String[] extensions,            PackageSymbol p) {        int i = 0;        int plen = path.length();        while (i < plen) {            int end = path.indexOf(pathSep, i);            String pathname = path.substring(i, end);            list(pathname, name, extensions, p);            i = end + 1;        }    }    static final String[] classOnly = {".class"};    static final String[] javaOnly = {".java"};    static final String[] classOrJava = {".class", ".java"};    /**     * Load directory of package into members scope.     */    private void fillIn(PackageSymbol p) {        if (p.members_field == null)            p.members_field = new Scope(p);        Name packageName = p.fullname;        if (packageName == names.emptyPackage)            packageName = names.empty;        String dirname = externalizeFileName(packageName);        listAll(bootClassPath, dirname, classOnly, p);        if (sourceCompleter != null && sourceClassPath == null) {            listAll(classPath, dirname, classOrJava, p);        } else {            listAll(classPath, dirname, classOnly, p);            if (sourceCompleter != null) {                listAll(sourceClassPath, dirname, javaOnly, p);            }        }    }    /**      * Output for "-verbose" option.      *  @param key The key to look up the correct internationalized string.      *  @param arg An argument for substitution into the output string.      */    private void printVerbose(String key, String arg) {        Log.printLines(log.noticeWriter,                Log.getLocalizedString("verbose." + key, arg));    }    /**      * Output for "-checkclassfile" option.      *  @param key The key to look up the correct internationalized string.      *  @param arg An argument for substitution into the output string.      */    private void printCCF(String key, String arg) {        Log.printLines(log.noticeWriter,                Log.getLocalizedString("verbose." + key, arg));    }    public interface SourceCompleter {        void complete(ClassSymbol sym, String filename,                InputStream f) throws CompletionFailure;            }        }

⌨️ 快捷键说明

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