langtools/src/share/classes/com/sun/tools/javac/code/Scope.java
author mcimadamore
Tue, 16 Jun 2009 10:46:37 +0100
changeset 3140 15a274b13051
parent 1264 076a3cde30d5
child 5520 86e4b9a9da40
permissions -rw-r--r--
6638712: Inference with wildcard types causes selection of inapplicable method Summary: Added global sanity check in order to make sure that return type inference does not violate bounds constraints Reviewed-by: jjg
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     1
/*
1264
076a3cde30d5 6754988: Update copyright year
xdono
parents: 1260
diff changeset
     2
 * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
06bc494ca11e Initial load
duke
parents:
diff changeset
     4
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
06bc494ca11e Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
06bc494ca11e Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
06bc494ca11e Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
06bc494ca11e Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
06bc494ca11e Initial load
duke
parents:
diff changeset
    10
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
06bc494ca11e Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
06bc494ca11e Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
06bc494ca11e Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
06bc494ca11e Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
06bc494ca11e Initial load
duke
parents:
diff changeset
    16
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
06bc494ca11e Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
06bc494ca11e Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
06bc494ca11e Initial load
duke
parents:
diff changeset
    20
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
06bc494ca11e Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
06bc494ca11e Initial load
duke
parents:
diff changeset
    23
 * have any questions.
06bc494ca11e Initial load
duke
parents:
diff changeset
    24
 */
06bc494ca11e Initial load
duke
parents:
diff changeset
    25
06bc494ca11e Initial load
duke
parents:
diff changeset
    26
package com.sun.tools.javac.code;
06bc494ca11e Initial load
duke
parents:
diff changeset
    27
06bc494ca11e Initial load
duke
parents:
diff changeset
    28
import com.sun.tools.javac.util.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    29
import java.util.Iterator;
06bc494ca11e Initial load
duke
parents:
diff changeset
    30
06bc494ca11e Initial load
duke
parents:
diff changeset
    31
/** A scope represents an area of visibility in a Java program. The
06bc494ca11e Initial load
duke
parents:
diff changeset
    32
 *  Scope class is a container for symbols which provides
06bc494ca11e Initial load
duke
parents:
diff changeset
    33
 *  efficient access to symbols given their names. Scopes are implemented
06bc494ca11e Initial load
duke
parents:
diff changeset
    34
 *  as hash tables. Scopes can be nested; the next field of a scope points
06bc494ca11e Initial load
duke
parents:
diff changeset
    35
 *  to its next outer scope. Nested scopes can share their hash tables.
06bc494ca11e Initial load
duke
parents:
diff changeset
    36
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    37
 *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
06bc494ca11e Initial load
duke
parents:
diff changeset
    38
 *  you write code that depends on this, you do so at your own risk.
06bc494ca11e Initial load
duke
parents:
diff changeset
    39
 *  This code and its internal interfaces are subject to change or
06bc494ca11e Initial load
duke
parents:
diff changeset
    40
 *  deletion without notice.</b>
06bc494ca11e Initial load
duke
parents:
diff changeset
    41
 */
06bc494ca11e Initial load
duke
parents:
diff changeset
    42
public class Scope {
06bc494ca11e Initial load
duke
parents:
diff changeset
    43
06bc494ca11e Initial load
duke
parents:
diff changeset
    44
    /** The number of scopes that share this scope's hash table.
06bc494ca11e Initial load
duke
parents:
diff changeset
    45
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    46
    private int shared;
06bc494ca11e Initial load
duke
parents:
diff changeset
    47
06bc494ca11e Initial load
duke
parents:
diff changeset
    48
    /** Next enclosing scope (with whom this scope may share a hashtable)
06bc494ca11e Initial load
duke
parents:
diff changeset
    49
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    50
    public Scope next;
06bc494ca11e Initial load
duke
parents:
diff changeset
    51
06bc494ca11e Initial load
duke
parents:
diff changeset
    52
    /** The scope's owner.
06bc494ca11e Initial load
duke
parents:
diff changeset
    53
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    54
    public Symbol owner;
06bc494ca11e Initial load
duke
parents:
diff changeset
    55
06bc494ca11e Initial load
duke
parents:
diff changeset
    56
    /** A hash table for the scope's entries.
06bc494ca11e Initial load
duke
parents:
diff changeset
    57
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    58
    public Entry[] table;
06bc494ca11e Initial load
duke
parents:
diff changeset
    59
06bc494ca11e Initial load
duke
parents:
diff changeset
    60
    /** Mask for hash codes, always equal to (table.length - 1).
06bc494ca11e Initial load
duke
parents:
diff changeset
    61
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    62
    int hashMask;
06bc494ca11e Initial load
duke
parents:
diff changeset
    63
06bc494ca11e Initial load
duke
parents:
diff changeset
    64
    /** A linear list that also contains all entries in
06bc494ca11e Initial load
duke
parents:
diff changeset
    65
     *  reverse order of appearance (i.e later entries are pushed on top).
06bc494ca11e Initial load
duke
parents:
diff changeset
    66
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    67
    public Entry elems;
06bc494ca11e Initial load
duke
parents:
diff changeset
    68
06bc494ca11e Initial load
duke
parents:
diff changeset
    69
    /** The number of elements in this scope.
06bc494ca11e Initial load
duke
parents:
diff changeset
    70
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    71
    public int nelems = 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
    72
06bc494ca11e Initial load
duke
parents:
diff changeset
    73
    /** Every hash bucket is a list of Entry's which ends in sentinel.
06bc494ca11e Initial load
duke
parents:
diff changeset
    74
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    75
    private static final Entry sentinel = new Entry(null, null, null, null);
06bc494ca11e Initial load
duke
parents:
diff changeset
    76
06bc494ca11e Initial load
duke
parents:
diff changeset
    77
    /** The hash table's initial size.
06bc494ca11e Initial load
duke
parents:
diff changeset
    78
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    79
    private static final int INITIAL_SIZE = 0x10;
06bc494ca11e Initial load
duke
parents:
diff changeset
    80
06bc494ca11e Initial load
duke
parents:
diff changeset
    81
    /** A value for the empty scope.
06bc494ca11e Initial load
duke
parents:
diff changeset
    82
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    83
    public static final Scope emptyScope = new Scope(null, null, new Entry[]{});
06bc494ca11e Initial load
duke
parents:
diff changeset
    84
06bc494ca11e Initial load
duke
parents:
diff changeset
    85
    /** Construct a new scope, within scope next, with given owner, using
06bc494ca11e Initial load
duke
parents:
diff changeset
    86
     *  given table. The table's length must be an exponent of 2.
06bc494ca11e Initial load
duke
parents:
diff changeset
    87
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    88
    Scope(Scope next, Symbol owner, Entry[] table) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    89
        this.next = next;
06bc494ca11e Initial load
duke
parents:
diff changeset
    90
        assert emptyScope == null || owner != null;
06bc494ca11e Initial load
duke
parents:
diff changeset
    91
        this.owner = owner;
06bc494ca11e Initial load
duke
parents:
diff changeset
    92
        this.table = table;
06bc494ca11e Initial load
duke
parents:
diff changeset
    93
        this.hashMask = table.length - 1;
06bc494ca11e Initial load
duke
parents:
diff changeset
    94
        this.elems = null;
06bc494ca11e Initial load
duke
parents:
diff changeset
    95
        this.nelems = 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
    96
        this.shared = 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
    97
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
    98
06bc494ca11e Initial load
duke
parents:
diff changeset
    99
    /** Construct a new scope, within scope next, with given owner,
06bc494ca11e Initial load
duke
parents:
diff changeset
   100
     *  using a fresh table of length INITIAL_SIZE.
06bc494ca11e Initial load
duke
parents:
diff changeset
   101
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   102
    public Scope(Symbol owner) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   103
        this(null, owner, new Entry[INITIAL_SIZE]);
06bc494ca11e Initial load
duke
parents:
diff changeset
   104
        for (int i = 0; i < INITIAL_SIZE; i++) table[i] = sentinel;
06bc494ca11e Initial load
duke
parents:
diff changeset
   105
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   106
06bc494ca11e Initial load
duke
parents:
diff changeset
   107
    /** Construct a fresh scope within this scope, with same owner,
06bc494ca11e Initial load
duke
parents:
diff changeset
   108
     *  which shares its table with the outer scope. Used in connection with
06bc494ca11e Initial load
duke
parents:
diff changeset
   109
     *  method leave if scope access is stack-like in order to avoid allocation
06bc494ca11e Initial load
duke
parents:
diff changeset
   110
     *  of fresh tables.
06bc494ca11e Initial load
duke
parents:
diff changeset
   111
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   112
    public Scope dup() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   113
        Scope result = new Scope(this, this.owner, this.table);
06bc494ca11e Initial load
duke
parents:
diff changeset
   114
        shared++;
06bc494ca11e Initial load
duke
parents:
diff changeset
   115
        // System.out.println("====> duping scope " + this.hashCode() + " owned by " + this.owner + " to " + result.hashCode());
06bc494ca11e Initial load
duke
parents:
diff changeset
   116
        // new Error().printStackTrace(System.out);
06bc494ca11e Initial load
duke
parents:
diff changeset
   117
        return result;
06bc494ca11e Initial load
duke
parents:
diff changeset
   118
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   119
06bc494ca11e Initial load
duke
parents:
diff changeset
   120
    /** Construct a fresh scope within this scope, with new owner,
06bc494ca11e Initial load
duke
parents:
diff changeset
   121
     *  which shares its table with the outer scope. Used in connection with
06bc494ca11e Initial load
duke
parents:
diff changeset
   122
     *  method leave if scope access is stack-like in order to avoid allocation
06bc494ca11e Initial load
duke
parents:
diff changeset
   123
     *  of fresh tables.
06bc494ca11e Initial load
duke
parents:
diff changeset
   124
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   125
    public Scope dup(Symbol newOwner) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   126
        Scope result = new Scope(this, newOwner, this.table);
06bc494ca11e Initial load
duke
parents:
diff changeset
   127
        shared++;
06bc494ca11e Initial load
duke
parents:
diff changeset
   128
        // System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
06bc494ca11e Initial load
duke
parents:
diff changeset
   129
        // new Error().printStackTrace(System.out);
06bc494ca11e Initial load
duke
parents:
diff changeset
   130
        return result;
06bc494ca11e Initial load
duke
parents:
diff changeset
   131
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   132
06bc494ca11e Initial load
duke
parents:
diff changeset
   133
    /** Construct a fresh scope within this scope, with same owner,
06bc494ca11e Initial load
duke
parents:
diff changeset
   134
     *  with a new hash table, whose contents initially are those of
06bc494ca11e Initial load
duke
parents:
diff changeset
   135
     *  the table of its outer scope.
06bc494ca11e Initial load
duke
parents:
diff changeset
   136
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   137
    public Scope dupUnshared() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   138
        return new Scope(this, this.owner, this.table.clone());
06bc494ca11e Initial load
duke
parents:
diff changeset
   139
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   140
06bc494ca11e Initial load
duke
parents:
diff changeset
   141
    /** Remove all entries of this scope from its table, if shared
06bc494ca11e Initial load
duke
parents:
diff changeset
   142
     *  with next.
06bc494ca11e Initial load
duke
parents:
diff changeset
   143
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   144
    public Scope leave() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   145
        assert shared == 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
   146
        if (table != next.table) return next;
06bc494ca11e Initial load
duke
parents:
diff changeset
   147
        while (elems != null) {
1260
a772ba9ba43d 6574134: Allow for alternative implementation of Name Table with garbage collection of name bytes
jjg
parents: 10
diff changeset
   148
            int hash = elems.sym.name.hashCode() & hashMask;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   149
            Entry e = table[hash];
06bc494ca11e Initial load
duke
parents:
diff changeset
   150
            assert e == elems : elems.sym;
06bc494ca11e Initial load
duke
parents:
diff changeset
   151
            table[hash] = elems.shadowed;
06bc494ca11e Initial load
duke
parents:
diff changeset
   152
            elems = elems.sibling;
06bc494ca11e Initial load
duke
parents:
diff changeset
   153
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   154
        assert next.shared > 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
   155
        next.shared--;
06bc494ca11e Initial load
duke
parents:
diff changeset
   156
        // System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode());
06bc494ca11e Initial load
duke
parents:
diff changeset
   157
        // new Error().printStackTrace(System.out);
06bc494ca11e Initial load
duke
parents:
diff changeset
   158
        return next;
06bc494ca11e Initial load
duke
parents:
diff changeset
   159
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   160
06bc494ca11e Initial load
duke
parents:
diff changeset
   161
    /** Double size of hash table.
06bc494ca11e Initial load
duke
parents:
diff changeset
   162
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   163
    private void dble() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   164
        assert shared == 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
   165
        Entry[] oldtable = table;
06bc494ca11e Initial load
duke
parents:
diff changeset
   166
        Entry[] newtable = new Entry[oldtable.length * 2];
06bc494ca11e Initial load
duke
parents:
diff changeset
   167
        for (Scope s = this; s != null; s = s.next) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   168
            if (s.table == oldtable) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   169
                assert s == this || s.shared != 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
   170
                s.table = newtable;
06bc494ca11e Initial load
duke
parents:
diff changeset
   171
                s.hashMask = newtable.length - 1;
06bc494ca11e Initial load
duke
parents:
diff changeset
   172
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   173
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   174
        for (int i = 0; i < newtable.length; i++) newtable[i] = sentinel;
06bc494ca11e Initial load
duke
parents:
diff changeset
   175
        for (int i = 0; i < oldtable.length; i++) copy(oldtable[i]);
06bc494ca11e Initial load
duke
parents:
diff changeset
   176
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   177
06bc494ca11e Initial load
duke
parents:
diff changeset
   178
    /** Copy the given entry and all entries shadowed by it to table
06bc494ca11e Initial load
duke
parents:
diff changeset
   179
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   180
    private void copy(Entry e) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   181
        if (e.sym != null) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   182
            copy(e.shadowed);
1260
a772ba9ba43d 6574134: Allow for alternative implementation of Name Table with garbage collection of name bytes
jjg
parents: 10
diff changeset
   183
            int hash = e.sym.name.hashCode() & hashMask;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   184
            e.shadowed = table[hash];
06bc494ca11e Initial load
duke
parents:
diff changeset
   185
            table[hash] = e;
06bc494ca11e Initial load
duke
parents:
diff changeset
   186
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   187
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   188
06bc494ca11e Initial load
duke
parents:
diff changeset
   189
    /** Enter symbol sym in this scope.
06bc494ca11e Initial load
duke
parents:
diff changeset
   190
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   191
    public void enter(Symbol sym) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   192
        assert shared == 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
   193
        enter(sym, this);
06bc494ca11e Initial load
duke
parents:
diff changeset
   194
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   195
06bc494ca11e Initial load
duke
parents:
diff changeset
   196
    public void enter(Symbol sym, Scope s) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   197
        enter(sym, s, s);
06bc494ca11e Initial load
duke
parents:
diff changeset
   198
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   199
06bc494ca11e Initial load
duke
parents:
diff changeset
   200
    /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   201
     * Enter symbol sym in this scope, but mark that it comes from
06bc494ca11e Initial load
duke
parents:
diff changeset
   202
     * given scope `s' accessed through `origin'.  The last two
06bc494ca11e Initial load
duke
parents:
diff changeset
   203
     * arguments are only used in import scopes.
06bc494ca11e Initial load
duke
parents:
diff changeset
   204
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   205
    public void enter(Symbol sym, Scope s, Scope origin) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   206
        assert shared == 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
   207
        // Temporarily disabled (bug 6460352):
06bc494ca11e Initial load
duke
parents:
diff changeset
   208
        // if (nelems * 3 >= hashMask * 2) dble();
1260
a772ba9ba43d 6574134: Allow for alternative implementation of Name Table with garbage collection of name bytes
jjg
parents: 10
diff changeset
   209
        int hash = sym.name.hashCode() & hashMask;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   210
        Entry e = makeEntry(sym, table[hash], elems, s, origin);
06bc494ca11e Initial load
duke
parents:
diff changeset
   211
        table[hash] = e;
06bc494ca11e Initial load
duke
parents:
diff changeset
   212
        elems = e;
06bc494ca11e Initial load
duke
parents:
diff changeset
   213
        nelems++;
06bc494ca11e Initial load
duke
parents:
diff changeset
   214
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   215
06bc494ca11e Initial load
duke
parents:
diff changeset
   216
    Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   217
        return new Entry(sym, shadowed, sibling, scope);
06bc494ca11e Initial load
duke
parents:
diff changeset
   218
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   219
06bc494ca11e Initial load
duke
parents:
diff changeset
   220
    /** Remove symbol from this scope.  Used when an inner class
06bc494ca11e Initial load
duke
parents:
diff changeset
   221
     *  attribute tells us that the class isn't a package member.
06bc494ca11e Initial load
duke
parents:
diff changeset
   222
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   223
    public void remove(Symbol sym) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   224
        assert shared == 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
   225
        Entry e = lookup(sym.name);
06bc494ca11e Initial load
duke
parents:
diff changeset
   226
        while (e.scope == this && e.sym != sym) e = e.next();
06bc494ca11e Initial load
duke
parents:
diff changeset
   227
        if (e.scope == null) return;
06bc494ca11e Initial load
duke
parents:
diff changeset
   228
06bc494ca11e Initial load
duke
parents:
diff changeset
   229
        // remove e from table and shadowed list;
1260
a772ba9ba43d 6574134: Allow for alternative implementation of Name Table with garbage collection of name bytes
jjg
parents: 10
diff changeset
   230
        Entry te = table[sym.name.hashCode() & hashMask];
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   231
        if (te == e)
1260
a772ba9ba43d 6574134: Allow for alternative implementation of Name Table with garbage collection of name bytes
jjg
parents: 10
diff changeset
   232
            table[sym.name.hashCode() & hashMask] = e.shadowed;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   233
        else while (true) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   234
            if (te.shadowed == e) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   235
                te.shadowed = e.shadowed;
06bc494ca11e Initial load
duke
parents:
diff changeset
   236
                break;
06bc494ca11e Initial load
duke
parents:
diff changeset
   237
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   238
            te = te.shadowed;
06bc494ca11e Initial load
duke
parents:
diff changeset
   239
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   240
06bc494ca11e Initial load
duke
parents:
diff changeset
   241
        // remove e from elems and sibling list
06bc494ca11e Initial load
duke
parents:
diff changeset
   242
        te = elems;
06bc494ca11e Initial load
duke
parents:
diff changeset
   243
        if (te == e)
06bc494ca11e Initial load
duke
parents:
diff changeset
   244
            elems = e.sibling;
06bc494ca11e Initial load
duke
parents:
diff changeset
   245
        else while (true) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   246
            if (te.sibling == e) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   247
                te.sibling = e.sibling;
06bc494ca11e Initial load
duke
parents:
diff changeset
   248
                break;
06bc494ca11e Initial load
duke
parents:
diff changeset
   249
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   250
            te = te.sibling;
06bc494ca11e Initial load
duke
parents:
diff changeset
   251
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   252
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   253
06bc494ca11e Initial load
duke
parents:
diff changeset
   254
    /** Enter symbol sym in this scope if not already there.
06bc494ca11e Initial load
duke
parents:
diff changeset
   255
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   256
    public void enterIfAbsent(Symbol sym) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   257
        assert shared == 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
   258
        Entry e = lookup(sym.name);
06bc494ca11e Initial load
duke
parents:
diff changeset
   259
        while (e.scope == this && e.sym.kind != sym.kind) e = e.next();
06bc494ca11e Initial load
duke
parents:
diff changeset
   260
        if (e.scope != this) enter(sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   261
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   262
06bc494ca11e Initial load
duke
parents:
diff changeset
   263
    /** Given a class, is there already a class with same fully
06bc494ca11e Initial load
duke
parents:
diff changeset
   264
     *  qualified name in this (import) scope?
06bc494ca11e Initial load
duke
parents:
diff changeset
   265
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   266
    public boolean includes(Symbol c) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   267
        for (Scope.Entry e = lookup(c.name);
06bc494ca11e Initial load
duke
parents:
diff changeset
   268
             e.scope == this;
06bc494ca11e Initial load
duke
parents:
diff changeset
   269
             e = e.next()) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   270
            if (e.sym == c) return true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   271
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   272
        return false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   273
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   274
06bc494ca11e Initial load
duke
parents:
diff changeset
   275
    /** Return the entry associated with given name, starting in
06bc494ca11e Initial load
duke
parents:
diff changeset
   276
     *  this scope and proceeding outwards. If no entry was found,
06bc494ca11e Initial load
duke
parents:
diff changeset
   277
     *  return the sentinel, which is characterized by having a null in
06bc494ca11e Initial load
duke
parents:
diff changeset
   278
     *  both its scope and sym fields, whereas both fields are non-null
06bc494ca11e Initial load
duke
parents:
diff changeset
   279
     *  for regular entries.
06bc494ca11e Initial load
duke
parents:
diff changeset
   280
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   281
    public Entry lookup(Name name) {
1260
a772ba9ba43d 6574134: Allow for alternative implementation of Name Table with garbage collection of name bytes
jjg
parents: 10
diff changeset
   282
        Entry e = table[name.hashCode() & hashMask];
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   283
        while (e.scope != null && e.sym.name != name)
06bc494ca11e Initial load
duke
parents:
diff changeset
   284
            e = e.shadowed;
06bc494ca11e Initial load
duke
parents:
diff changeset
   285
        return e;
06bc494ca11e Initial load
duke
parents:
diff changeset
   286
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   287
06bc494ca11e Initial load
duke
parents:
diff changeset
   288
    public Iterable<Symbol> getElements() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   289
        return new Iterable<Symbol>() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   290
            public Iterator<Symbol> iterator() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   291
                return new Iterator<Symbol>() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   292
                    private Scope currScope = Scope.this;
06bc494ca11e Initial load
duke
parents:
diff changeset
   293
                    private Scope.Entry currEntry = elems;
06bc494ca11e Initial load
duke
parents:
diff changeset
   294
                    {
06bc494ca11e Initial load
duke
parents:
diff changeset
   295
                        update();
06bc494ca11e Initial load
duke
parents:
diff changeset
   296
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   297
06bc494ca11e Initial load
duke
parents:
diff changeset
   298
                    public boolean hasNext() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   299
                        return currEntry != null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   300
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   301
06bc494ca11e Initial load
duke
parents:
diff changeset
   302
                    public Symbol next() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   303
                        Symbol sym = (currEntry == null ? null : currEntry.sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   304
                        currEntry = currEntry.sibling;
06bc494ca11e Initial load
duke
parents:
diff changeset
   305
                        update();
06bc494ca11e Initial load
duke
parents:
diff changeset
   306
                        return sym;
06bc494ca11e Initial load
duke
parents:
diff changeset
   307
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   308
06bc494ca11e Initial load
duke
parents:
diff changeset
   309
                    public void remove() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   310
                        throw new UnsupportedOperationException();
06bc494ca11e Initial load
duke
parents:
diff changeset
   311
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   312
06bc494ca11e Initial load
duke
parents:
diff changeset
   313
                    private void update() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   314
                        while (currEntry == null && currScope.next != null) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   315
                            currScope = currScope.next;
06bc494ca11e Initial load
duke
parents:
diff changeset
   316
                            currEntry = currScope.elems;
06bc494ca11e Initial load
duke
parents:
diff changeset
   317
                        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   318
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   319
                };
06bc494ca11e Initial load
duke
parents:
diff changeset
   320
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   321
        };
06bc494ca11e Initial load
duke
parents:
diff changeset
   322
06bc494ca11e Initial load
duke
parents:
diff changeset
   323
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   324
06bc494ca11e Initial load
duke
parents:
diff changeset
   325
    public String toString() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   326
        StringBuilder result = new StringBuilder();
06bc494ca11e Initial load
duke
parents:
diff changeset
   327
        result.append("Scope[");
06bc494ca11e Initial load
duke
parents:
diff changeset
   328
        for (Scope s = this; s != null ; s = s.next) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   329
            if (s != this) result.append(" | ");
06bc494ca11e Initial load
duke
parents:
diff changeset
   330
            for (Entry e = s.elems; e != null; e = e.sibling) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   331
                if (e != s.elems) result.append(", ");
06bc494ca11e Initial load
duke
parents:
diff changeset
   332
                result.append(e.sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   333
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   334
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   335
        result.append("]");
06bc494ca11e Initial load
duke
parents:
diff changeset
   336
        return result.toString();
06bc494ca11e Initial load
duke
parents:
diff changeset
   337
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   338
06bc494ca11e Initial load
duke
parents:
diff changeset
   339
    /** A class for scope entries.
06bc494ca11e Initial load
duke
parents:
diff changeset
   340
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   341
    public static class Entry {
06bc494ca11e Initial load
duke
parents:
diff changeset
   342
06bc494ca11e Initial load
duke
parents:
diff changeset
   343
        /** The referenced symbol.
06bc494ca11e Initial load
duke
parents:
diff changeset
   344
         *  sym == null   iff   this == sentinel
06bc494ca11e Initial load
duke
parents:
diff changeset
   345
         */
06bc494ca11e Initial load
duke
parents:
diff changeset
   346
        public Symbol sym;
06bc494ca11e Initial load
duke
parents:
diff changeset
   347
06bc494ca11e Initial load
duke
parents:
diff changeset
   348
        /** An entry with the same hash code, or sentinel.
06bc494ca11e Initial load
duke
parents:
diff changeset
   349
         */
06bc494ca11e Initial load
duke
parents:
diff changeset
   350
        private Entry shadowed;
06bc494ca11e Initial load
duke
parents:
diff changeset
   351
06bc494ca11e Initial load
duke
parents:
diff changeset
   352
        /** Next entry in same scope.
06bc494ca11e Initial load
duke
parents:
diff changeset
   353
         */
06bc494ca11e Initial load
duke
parents:
diff changeset
   354
        public Entry sibling;
06bc494ca11e Initial load
duke
parents:
diff changeset
   355
06bc494ca11e Initial load
duke
parents:
diff changeset
   356
        /** The entry's scope.
06bc494ca11e Initial load
duke
parents:
diff changeset
   357
         *  scope == null   iff   this == sentinel
06bc494ca11e Initial load
duke
parents:
diff changeset
   358
         *  for an entry in an import scope, this is the scope
06bc494ca11e Initial load
duke
parents:
diff changeset
   359
         *  where the entry came from (i.e. was imported from).
06bc494ca11e Initial load
duke
parents:
diff changeset
   360
         */
06bc494ca11e Initial load
duke
parents:
diff changeset
   361
        public Scope scope;
06bc494ca11e Initial load
duke
parents:
diff changeset
   362
06bc494ca11e Initial load
duke
parents:
diff changeset
   363
        public Entry(Symbol sym, Entry shadowed, Entry sibling, Scope scope) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   364
            this.sym = sym;
06bc494ca11e Initial load
duke
parents:
diff changeset
   365
            this.shadowed = shadowed;
06bc494ca11e Initial load
duke
parents:
diff changeset
   366
            this.sibling = sibling;
06bc494ca11e Initial load
duke
parents:
diff changeset
   367
            this.scope = scope;
06bc494ca11e Initial load
duke
parents:
diff changeset
   368
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   369
06bc494ca11e Initial load
duke
parents:
diff changeset
   370
        /** Return next entry with the same name as this entry, proceeding
06bc494ca11e Initial load
duke
parents:
diff changeset
   371
         *  outwards if not found in this scope.
06bc494ca11e Initial load
duke
parents:
diff changeset
   372
         */
06bc494ca11e Initial load
duke
parents:
diff changeset
   373
        public Entry next() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   374
            Entry e = shadowed;
06bc494ca11e Initial load
duke
parents:
diff changeset
   375
            while (e.scope != null && e.sym.name != sym.name)
06bc494ca11e Initial load
duke
parents:
diff changeset
   376
                e = e.shadowed;
06bc494ca11e Initial load
duke
parents:
diff changeset
   377
            return e;
06bc494ca11e Initial load
duke
parents:
diff changeset
   378
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   379
06bc494ca11e Initial load
duke
parents:
diff changeset
   380
        public Scope getOrigin() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   381
            // The origin is only recorded for import scopes.  For all
06bc494ca11e Initial load
duke
parents:
diff changeset
   382
            // other scope entries, the "enclosing" type is available
06bc494ca11e Initial load
duke
parents:
diff changeset
   383
            // from other sources.  See Attr.visitSelect and
06bc494ca11e Initial load
duke
parents:
diff changeset
   384
            // Attr.visitIdent.  Rather than throwing an assertion
06bc494ca11e Initial load
duke
parents:
diff changeset
   385
            // error, we return scope which will be the same as origin
06bc494ca11e Initial load
duke
parents:
diff changeset
   386
            // in many cases.
06bc494ca11e Initial load
duke
parents:
diff changeset
   387
            return scope;
06bc494ca11e Initial load
duke
parents:
diff changeset
   388
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   389
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   390
06bc494ca11e Initial load
duke
parents:
diff changeset
   391
    public static class ImportScope extends Scope {
06bc494ca11e Initial load
duke
parents:
diff changeset
   392
06bc494ca11e Initial load
duke
parents:
diff changeset
   393
        public ImportScope(Symbol owner) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   394
            super(owner);
06bc494ca11e Initial load
duke
parents:
diff changeset
   395
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   396
06bc494ca11e Initial load
duke
parents:
diff changeset
   397
        @Override
06bc494ca11e Initial load
duke
parents:
diff changeset
   398
        Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   399
            return new ImportEntry(sym, shadowed, sibling, scope, origin);
06bc494ca11e Initial load
duke
parents:
diff changeset
   400
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   401
06bc494ca11e Initial load
duke
parents:
diff changeset
   402
        public Entry lookup(Name name) {
1260
a772ba9ba43d 6574134: Allow for alternative implementation of Name Table with garbage collection of name bytes
jjg
parents: 10
diff changeset
   403
            Entry e = table[name.hashCode() & hashMask];
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   404
            while (e.scope != null &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   405
                   (e.sym.name != name ||
06bc494ca11e Initial load
duke
parents:
diff changeset
   406
                    /* Since an inner class will show up in package and
06bc494ca11e Initial load
duke
parents:
diff changeset
   407
                     * import scopes until its inner class attribute has
06bc494ca11e Initial load
duke
parents:
diff changeset
   408
                     * been processed, we have to weed it out here.  This
06bc494ca11e Initial load
duke
parents:
diff changeset
   409
                     * is done by comparing the owners of the entry's
06bc494ca11e Initial load
duke
parents:
diff changeset
   410
                     * scope and symbol fields.  The scope field's owner
06bc494ca11e Initial load
duke
parents:
diff changeset
   411
                     * points to where the class originally was imported
06bc494ca11e Initial load
duke
parents:
diff changeset
   412
                     * from.  The symbol field's owner points to where the
06bc494ca11e Initial load
duke
parents:
diff changeset
   413
                     * class is situated now.  This can change when an
06bc494ca11e Initial load
duke
parents:
diff changeset
   414
                     * inner class is read (see ClassReader.enterClass).
06bc494ca11e Initial load
duke
parents:
diff changeset
   415
                     * By comparing the two fields we make sure that we do
06bc494ca11e Initial load
duke
parents:
diff changeset
   416
                     * not accidentally import an inner class that started
06bc494ca11e Initial load
duke
parents:
diff changeset
   417
                     * life as a flat class in a package. */
06bc494ca11e Initial load
duke
parents:
diff changeset
   418
                    e.sym.owner != e.scope.owner))
06bc494ca11e Initial load
duke
parents:
diff changeset
   419
                e = e.shadowed;
06bc494ca11e Initial load
duke
parents:
diff changeset
   420
            return e;
06bc494ca11e Initial load
duke
parents:
diff changeset
   421
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   422
06bc494ca11e Initial load
duke
parents:
diff changeset
   423
        static class ImportEntry extends Entry {
06bc494ca11e Initial load
duke
parents:
diff changeset
   424
            private Scope origin;
06bc494ca11e Initial load
duke
parents:
diff changeset
   425
06bc494ca11e Initial load
duke
parents:
diff changeset
   426
            ImportEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   427
                super(sym, shadowed, sibling, scope);
06bc494ca11e Initial load
duke
parents:
diff changeset
   428
                this.origin = origin;
06bc494ca11e Initial load
duke
parents:
diff changeset
   429
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   430
            public Entry next() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   431
                Entry e = super.shadowed;
06bc494ca11e Initial load
duke
parents:
diff changeset
   432
                while (e.scope != null &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   433
                       (e.sym.name != sym.name ||
06bc494ca11e Initial load
duke
parents:
diff changeset
   434
                        e.sym.owner != e.scope.owner)) // see lookup()
06bc494ca11e Initial load
duke
parents:
diff changeset
   435
                    e = e.shadowed;
06bc494ca11e Initial load
duke
parents:
diff changeset
   436
                return e;
06bc494ca11e Initial load
duke
parents:
diff changeset
   437
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   438
06bc494ca11e Initial load
duke
parents:
diff changeset
   439
            @Override
06bc494ca11e Initial load
duke
parents:
diff changeset
   440
            public Scope getOrigin() { return origin; }
06bc494ca11e Initial load
duke
parents:
diff changeset
   441
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   442
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   443
06bc494ca11e Initial load
duke
parents:
diff changeset
   444
    /** An empty scope, into which you can't place anything.  Used for
06bc494ca11e Initial load
duke
parents:
diff changeset
   445
     *  the scope for a variable initializer.
06bc494ca11e Initial load
duke
parents:
diff changeset
   446
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   447
    public static class DelegatedScope extends Scope {
06bc494ca11e Initial load
duke
parents:
diff changeset
   448
        Scope delegatee;
06bc494ca11e Initial load
duke
parents:
diff changeset
   449
        public static final Entry[] emptyTable = new Entry[0];
06bc494ca11e Initial load
duke
parents:
diff changeset
   450
06bc494ca11e Initial load
duke
parents:
diff changeset
   451
        public DelegatedScope(Scope outer) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   452
            super(outer, outer.owner, emptyTable);
06bc494ca11e Initial load
duke
parents:
diff changeset
   453
            delegatee = outer;
06bc494ca11e Initial load
duke
parents:
diff changeset
   454
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   455
        public Scope dup() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   456
            return new DelegatedScope(next);
06bc494ca11e Initial load
duke
parents:
diff changeset
   457
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   458
        public Scope dupUnshared() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   459
            return new DelegatedScope(next);
06bc494ca11e Initial load
duke
parents:
diff changeset
   460
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   461
        public Scope leave() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   462
            return next;
06bc494ca11e Initial load
duke
parents:
diff changeset
   463
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   464
        public void enter(Symbol sym) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   465
            // only anonymous classes could be put here
06bc494ca11e Initial load
duke
parents:
diff changeset
   466
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   467
        public void enter(Symbol sym, Scope s) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   468
            // only anonymous classes could be put here
06bc494ca11e Initial load
duke
parents:
diff changeset
   469
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   470
        public void remove(Symbol sym) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   471
            throw new AssertionError(sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   472
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   473
        public Entry lookup(Name name) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   474
            return delegatee.lookup(name);
06bc494ca11e Initial load
duke
parents:
diff changeset
   475
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   476
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   477
06bc494ca11e Initial load
duke
parents:
diff changeset
   478
    /** An error scope, for which the owner should be an error symbol. */
06bc494ca11e Initial load
duke
parents:
diff changeset
   479
    public static class ErrorScope extends Scope {
06bc494ca11e Initial load
duke
parents:
diff changeset
   480
        ErrorScope(Scope next, Symbol errSymbol, Entry[] table) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   481
            super(next, /*owner=*/errSymbol, table);
06bc494ca11e Initial load
duke
parents:
diff changeset
   482
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   483
        public ErrorScope(Symbol errSymbol) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   484
            super(errSymbol);
06bc494ca11e Initial load
duke
parents:
diff changeset
   485
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   486
        public Scope dup() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   487
            return new ErrorScope(this, owner, table);
06bc494ca11e Initial load
duke
parents:
diff changeset
   488
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   489
        public Scope dupUnshared() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   490
            return new ErrorScope(this, owner, table.clone());
06bc494ca11e Initial load
duke
parents:
diff changeset
   491
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   492
        public Entry lookup(Name name) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   493
            Entry e = super.lookup(name);
06bc494ca11e Initial load
duke
parents:
diff changeset
   494
            if (e.scope == null)
06bc494ca11e Initial load
duke
parents:
diff changeset
   495
                return new Entry(owner, null, null, null);
06bc494ca11e Initial load
duke
parents:
diff changeset
   496
            else
06bc494ca11e Initial load
duke
parents:
diff changeset
   497
                return e;
06bc494ca11e Initial load
duke
parents:
diff changeset
   498
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   499
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   500
}