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

📄 scope.java

📁 GJC编译器的源代码。是一个开放源代码的工业级编译器。
💻 JAVA
字号:
/**
 * @(#)Scope.java	1.18 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.*;


/**
 * A scope represents an area of visibility in a Java program. The
 *  Scope class is a container for symbols which provides
 *  efficient access to symbols given their names. Scopes are implemented
 *  as hash tables. Scopes can be nested; the next field of a scope points
 *  to its next outer scope. Nested scopes can share their hash tables.
 */
public class Scope {

    /**
     * Next enclosing scope with whom this scope shares a hashtable
     */
    public Scope next;

    /**
     * The scope's owner.
     */
    public Symbol owner;

    /**
     * A hash table for the scope's entries.
     */
    public Entry[] table;

    /**
     * Mask for hash codes, always equal to (table.length - 1).
     */
    int hashMask;

    /**
     * A linear list that also contains all entries in
     *  reverse order of appearance (i.e later entries are pushed on top).
     */
    public Entry elems;

    /**
     * The number of elements in this scope.
     */
    public int nelems = 0;

    /**
     * Every hash bucket is a list of Entry's which ends in sentinel.
     */
    private static final Entry sentinel = new Entry(null, null, null, null);

    /**
     * The hash table's initial size.
     */
    private static final int INITIAL_SIZE = 128;

    /**
     * A value for the empty scope.
     */
    public static final Scope emptyScope = new Scope(null, null, new Entry[]{});

    /**
     * Construct a new scope, within scope next, with given owner, using
     *  given table. The table's length must be an exponent of 2.
     */
    Scope(Scope next, Symbol owner, Entry[] table) {
        super();
        this.next = next;
        this.owner = owner;
        this.table = table;
        this.hashMask = table.length - 1;
        this.elems = null;
        this.nelems = 0;
    }

    /**
      * Construct a new scope, within scope next, with given owner,
      *  using a fresh table of length INITIAL_SIZE.
      */
    public Scope(Symbol owner) {
        this(null, owner, new Entry[INITIAL_SIZE]);
        for (int i = 0; i < INITIAL_SIZE; i++)
            table[i] = sentinel;
    }

    /**
      * Construct a fresh scope within this scope, with same owner,
      *  which shares its table with the outer scope. Used in connection with
      *  method leave if scope access is stack-like in order to avoid allocation
      *  of fresh tables.
      */
    public Scope dup() {
        return new Scope(this, this.owner, this.table);
    }

    /**
      * Construct a fresh scope within this scope, with same owner,
      *  with a new hash table, whose contents initially are those of
      *  the table of its outer scope.
      */
    public Scope dupUnshared() {
        return new Scope(this, this.owner, (Entry[]) this.table.clone());
    }

    /**
      * Remove all entries of this scope from its table.
      */
    public Scope leave() {
        while (elems != null) {
            int hash = elems.sym.name.index & hashMask;
            Entry e = table[hash];
            assert e == elems :
            elems.sym;
            table[hash] = elems.shadowed;
            elems = elems.sibling;
        }
        return next;
    }

    /**
      * Double size of hash table.
      */
    private void dble() {
        Entry[] oldtable = table;
        Entry[] newtable = new Entry[oldtable.length * 2];
        Scope s = this;
        do {
            s.table = newtable;
            s.hashMask = newtable.length - 1;
            s = s.next;
        } while (s != null)
            ;
        for (int i = 0; i < newtable.length; i++)
            newtable[i] = sentinel;
        for (int i = 0; i < oldtable.length; i++)
            copy(oldtable[i]);
    }

    /**
      * Copy the given entry and all entries shadowed by it to table
      */
    private void copy(Entry e) {
        if (e.sym != null) {
            copy(e.shadowed);
            int hash = e.sym.name.index & hashMask;
            e.shadowed = table[hash];
            table[hash] = e;
        }
    }

    /**
      * Enter symbol sym in this scope.
      */
    public void enter(Symbol sym) {
        enter(sym, this);
    }

    /**
      * Enter symbol sym in this scope, but mark that it comes from
      *  given scope `s'. This is used to enter entries in import scopes.
      */
    public void enter(Symbol sym, Scope s) {
        if (nelems * 3 >= hashMask * 2)
            dble();
        int hash = sym.name.index & hashMask;
        Entry e = new Entry(sym, table[hash], elems, s);
        table[hash] = e;
        elems = e;
        nelems++;
    }

    /**
      * Enter symbol sym in this scope if not already there.
      */
    public void enterIfAbsent(Symbol sym) {
        Entry e = lookup(sym.name);
        while (e.scope == this && e.sym.kind != sym.kind)
            e = e.next();
        if (e.scope != this)
            enter(sym);
    }

    /**
      * Return the entry associated with given name, starting in
      *  this scope and proceeding outwards. If no entry was found,
      *  return the sentinel, which is characterized by having a null in
      *  both its scope and sym fields, whereas both fields are non-null
      *  for regular entries.
      */
    public Entry lookup(Name name) {
        Entry e = table[name.index & hashMask];
        while (e.scope != null && e.sym.name != name)
            e = e.shadowed;
        return e;
    }

    /**
      * A class for scope entries.
      */
    public static class Entry {

        /**
         * The referenced symbol.
         *  sym == null   iff   this == sentinel
         */
        public Symbol sym;

        /**
         * An entry with the same hash code, or sentinel.
         */
        public Entry shadowed;

        /**
         * Next entry in same scope.
         */
        public Entry sibling;

        /**
         * The entry's scope.
         *  scope == null   iff   this == sentinel
         *  for an entry in an import scope, this is the scope
         *  where the entry came from (i.e. was imported from).
         */
        public Scope scope;

        public Entry(Symbol sym, Entry shadowed, Entry sibling, Scope scope) {
            super();
            this.sym = sym;
            this.shadowed = shadowed;
            this.sibling = sibling;
            this.scope = scope;
        }

        /**
          * Return next entry with the same name as this entry, proceeding
          *  outwards if not found in this scope.
          */
        public Entry next() {
            Entry e = shadowed;
            while (e.scope != null && e.sym.name != sym.name)
                e = e.shadowed;
            return e;
        }
    }

    /**
      * An error scope, for which the owner should be an error symbol.
      */
    public static class ErrorScope extends Scope {

        ErrorScope(Scope next, Symbol errSymbol, Entry[] table) {
            super(next, errSymbol, table);
        }

        public ErrorScope(Symbol errSymbol) {
            super(errSymbol);
        }

        public Scope dup() {
            return new ErrorScope(this, owner, table);
        }

        public Scope dupUnshared() {
            return new ErrorScope(this, owner, (Entry[]) table.clone());
        }

        public Entry lookup(Name name) {
            Entry e = super.lookup(name);
            if (e.scope == null)
                return new Entry(owner, null, null, null);
            else
                return e;
        }
    }
}

⌨️ 快捷键说明

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