Env.java revision 2628:8df25ec8c930
1/* 2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.javac.comp; 27 28import com.sun.tools.javac.tree.*; 29import java.util.Iterator; 30import java.util.NoSuchElementException; 31 32/** A class for environments, instances of which are passed as 33 * arguments to tree visitors. Environments refer to important ancestors 34 * of the subtree that's currently visited, such as the enclosing method, 35 * the enclosing class, or the enclosing toplevel node. They also contain 36 * a generic component, represented as a type parameter, to carry further 37 * information specific to individual passes. 38 * 39 * <p><b>This is NOT part of any supported API. 40 * If you write code that depends on this, you do so at your own risk. 41 * This code and its internal interfaces are subject to change or 42 * deletion without notice.</b> 43 */ 44public class Env<A> implements Iterable<Env<A>> { 45 46 /** The next enclosing environment. 47 */ 48 public Env<A> next; 49 50 /** The environment enclosing the current class. 51 */ 52 public Env<A> outer; 53 54 /** The tree with which this environment is associated. 55 */ 56 public JCTree tree; 57 58 /** The enclosing toplevel tree. 59 */ 60 public JCTree.JCCompilationUnit toplevel; 61 62 /** The next enclosing class definition. 63 */ 64 public JCTree.JCClassDecl enclClass; 65 66 /** The next enclosing method definition. 67 */ 68 public JCTree.JCMethodDecl enclMethod; 69 70 /** A generic field for further information. 71 */ 72 public A info; 73 74 /** Is this an environment for evaluating a base clause? 75 */ 76 public boolean baseClause = false; 77 78 /** Create an outermost environment for a given (toplevel)tree, 79 * with a given info field. 80 */ 81 public Env(JCTree tree, A info) { 82 this.next = null; 83 this.outer = null; 84 this.tree = tree; 85 this.toplevel = null; 86 this.enclClass = null; 87 this.enclMethod = null; 88 this.info = info; 89 } 90 91 /** Duplicate this environment, updating with given tree and info, 92 * and copying all other fields. 93 */ 94 public Env<A> dup(JCTree tree, A info) { 95 return dupto(new Env<>(tree, info)); 96 } 97 98 /** Duplicate this environment into a given Environment, 99 * using its tree and info, and copying all other fields. 100 */ 101 public Env<A> dupto(Env<A> that) { 102 that.next = this; 103 that.outer = this.outer; 104 that.toplevel = this.toplevel; 105 that.enclClass = this.enclClass; 106 that.enclMethod = this.enclMethod; 107 return that; 108 } 109 110 /** Duplicate this environment, updating with given tree, 111 * and copying all other fields. 112 */ 113 public Env<A> dup(JCTree tree) { 114 return dup(tree, this.info); 115 } 116 117 /** Return closest enclosing environment which points to a tree with given tag. 118 */ 119 public Env<A> enclosing(JCTree.Tag tag) { 120 Env<A> env1 = this; 121 while (env1 != null && !env1.tree.hasTag(tag)) env1 = env1.next; 122 return env1; 123 } 124 125 @Override 126 public String toString() { 127 StringBuilder sb = new StringBuilder(); 128 sb.append("Env[").append(info); 129// if (enclMethod != null) 130// sb.append(",enclMethod=").append(Pretty.toSimpleString(enclMethod)); 131// if (enclClass != null) 132// sb.append(",enclClass=").append(Pretty.toSimpleString(enclClass)); 133 if (outer != null) 134 sb.append(",outer=").append(outer); 135 sb.append("]"); 136 return sb.toString(); 137 } 138 139 public Iterator<Env<A>> iterator() { 140 return new Iterator<Env<A>>() { 141 Env<A> next = Env.this; 142 public boolean hasNext() { 143 return next.outer != null; 144 } 145 public Env<A> next() { 146 if (hasNext()) { 147 Env<A> current = next; 148 next = current.outer; 149 return current; 150 } 151 throw new NoSuchElementException(); 152 153 } 154 public void remove() { 155 throw new UnsupportedOperationException(); 156 } 157 }; 158 } 159} 160