📄 scope.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 + -