src/jdk/nashorn/internal/ir/Block.java

changeset 1536
bb0fac71c1da
parent 1226
8b3f832bea55
child 1959
61ffdd1b89f2
equal deleted inserted replaced
1535:8f28ca037c57 1536:bb0fac71c1da
128 public boolean isGlobalScope() { 128 public boolean isGlobalScope() {
129 return getFlag(IS_GLOBAL_SCOPE); 129 return getFlag(IS_GLOBAL_SCOPE);
130 } 130 }
131 131
132 /** 132 /**
133 * Clear the symbols in the block. 133 * Returns true if this block defines any symbols.
134 * TODO: make this immutable. 134 * @return true if this block defines any symbols.
135 */ 135 */
136 public void clearSymbols() { 136 public boolean hasSymbols() {
137 symbols.clear(); 137 return !symbols.isEmpty();
138 }
139
140 /**
141 * Replaces symbols defined in this block with different symbols. Used to ensure symbol tables are
142 * immutable upon construction and have copy-on-write semantics. Note that this method only replaces the
143 * symbols in the symbol table, it does not act on any contained AST nodes that might reference the symbols.
144 * Those should be updated separately as this method is meant to be used as part of such an update pass.
145 * @param lc the current lexical context
146 * @param replacements the map of symbol replacements
147 * @return a new block with replaced symbols, or this block if none of the replacements modified the symbol
148 * table.
149 */
150 public Block replaceSymbols(final LexicalContext lc, final Map<Symbol, Symbol> replacements) {
151 if (symbols.isEmpty()) {
152 return this;
153 }
154 final LinkedHashMap<String, Symbol> newSymbols = new LinkedHashMap<>(symbols);
155 for (final Map.Entry<String, Symbol> entry: newSymbols.entrySet()) {
156 final Symbol newSymbol = replacements.get(entry.getValue());
157 assert newSymbol != null : "Missing replacement for " + entry.getKey();
158 entry.setValue(newSymbol);
159 }
160 return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, newSymbols, conversion));
161 }
162
163 /**
164 * Returns a copy of this block with a shallow copy of the symbol table.
165 * @return a copy of this block with a shallow copy of the symbol table.
166 */
167 public Block copyWithNewSymbols() {
168 return new Block(this, finish, statements, flags, new LinkedHashMap<>(symbols), conversion);
138 } 169 }
139 170
140 @Override 171 @Override
141 public Node ensureUniqueLabels(final LexicalContext lc) { 172 public Node ensureUniqueLabels(final LexicalContext lc) {
142 return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols, conversion)); 173 return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols, conversion));
160 /** 191 /**
161 * Get a copy of the list for all the symbols defined in this block 192 * Get a copy of the list for all the symbols defined in this block
162 * @return symbol iterator 193 * @return symbol iterator
163 */ 194 */
164 public List<Symbol> getSymbols() { 195 public List<Symbol> getSymbols() {
165 return Collections.unmodifiableList(new ArrayList<>(symbols.values())); 196 return symbols.isEmpty() ? Collections.<Symbol>emptyList() : Collections.unmodifiableList(new ArrayList<>(symbols.values()));
166 } 197 }
167 198
168 /** 199 /**
169 * Retrieves an existing symbol defined in the current block. 200 * Retrieves an existing symbol defined in the current block.
170 * @param name the name of the symbol 201 * @param name the name of the symbol
324 } 355 }
325 356
326 /** 357 /**
327 * Add or overwrite an existing symbol in the block 358 * Add or overwrite an existing symbol in the block
328 * 359 *
329 * @param lc get lexical context
330 * @param symbol symbol 360 * @param symbol symbol
331 */ 361 */
332 public void putSymbol(final LexicalContext lc, final Symbol symbol) { 362 public void putSymbol(final Symbol symbol) {
333 symbols.put(symbol.getName(), symbol); 363 symbols.put(symbol.getName(), symbol);
334 } 364 }
335 365
336 /** 366 /**
337 * Check whether scope is necessary for this Block 367 * Check whether scope is necessary for this Block

mercurial