Env.java revision 2571:10fc81ac75b4
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 com.sun.tools.javac.tree.JCTree.JCLambda; 30import java.util.Iterator; 31import java.util.NoSuchElementException; 32 33/** A class for environments, instances of which are passed as 34 * arguments to tree visitors. Environments refer to important ancestors 35 * of the subtree that's currently visited, such as the enclosing method, 36 * the enclosing class, or the enclosing toplevel node. They also contain 37 * a generic component, represented as a type parameter, to carry further 38 * information specific to individual passes. 39 * 40 * <p><b>This is NOT part of any supported API. 41 * If you write code that depends on this, you do so at your own risk. 42 * This code and its internal interfaces are subject to change or 43 * deletion without notice.</b> 44 */ 45public class Env<A> implements Iterable<Env<A>> { 46 47 /** The next enclosing environment. 48 */ 49 public Env<A> next; 50 51 /** The environment enclosing the current class. 52 */ 53 public Env<A> outer; 54 55 /** The tree with which this environment is associated. 56 */ 57 public JCTree tree; 58 59 /** The enclosing toplevel tree. 60 */ 61 public JCTree.JCCompilationUnit toplevel; 62 63 /** The next enclosing class definition. 64 */ 65 public JCTree.JCClassDecl enclClass; 66 67 /** The next enclosing method definition. 68 */ 69 public JCTree.JCMethodDecl enclMethod; 70 71 /** A generic field for further information. 72 */ 73 public A info; 74 75 /** Is this an environment for evaluating a base clause? 76 */ 77 public boolean baseClause = false; 78 79 /** Create an outermost environment for a given (toplevel)tree, 80 * with a given info field. 81 */ 82 public Env(JCTree tree, A info) { 83 this.next = null; 84 this.outer = null; 85 this.tree = tree; 86 this.toplevel = null; 87 this.enclClass = null; 88 this.enclMethod = null; 89 this.info = info; 90 } 91 92 /** Duplicate this environment, updating with given tree and info, 93 * and copying all other fields. 94 */ 95 public Env<A> dup(JCTree tree, A info) { 96 return dupto(new Env<>(tree, info)); 97 } 98 99 /** Duplicate this environment into a given Environment, 100 * using its tree and info, and copying all other fields. 101 */ 102 public Env<A> dupto(Env<A> that) { 103 that.next = this; 104 that.outer = this.outer; 105 that.toplevel = this.toplevel; 106 that.enclClass = this.enclClass; 107 that.enclMethod = this.enclMethod; 108 return that; 109 } 110 111 /** Duplicate this environment, updating with given tree, 112 * and copying all other fields. 113 */ 114 public Env<A> dup(JCTree tree) { 115 return dup(tree, this.info); 116 } 117 118 /** Return closest enclosing environment which points to a tree with given tag. 119 */ 120 public Env<A> enclosing(JCTree.Tag tag) { 121 Env<A> env1 = this; 122 while (env1 != null && !env1.tree.hasTag(tag)) env1 = env1.next; 123 return env1; 124 } 125 126 @Override 127 public String toString() { 128 StringBuilder sb = new StringBuilder(); 129 sb.append("Env[").append(info); 130// if (enclMethod != null) 131// sb.append(",enclMethod=").append(Pretty.toSimpleString(enclMethod)); 132// if (enclClass != null) 133// sb.append(",enclClass=").append(Pretty.toSimpleString(enclClass)); 134 if (outer != null) 135 sb.append(",outer=").append(outer); 136 sb.append("]"); 137 return sb.toString(); 138 } 139 140 public Iterator<Env<A>> iterator() { 141 return new Iterator<Env<A>>() { 142 Env<A> next = Env.this; 143 public boolean hasNext() { 144 return next.outer != null; 145 } 146 public Env<A> next() { 147 if (hasNext()) { 148 Env<A> current = next; 149 next = current.outer; 150 return current; 151 } 152 throw new NoSuchElementException(); 153 154 } 155 public void remove() { 156 throw new UnsupportedOperationException(); 157 } 158 }; 159 } 160 161 public JCLambda getLambda() { 162 Env<A> out = enclosing(JCTree.Tag.LAMBDA); 163 164 return out != null ? (JCLambda) out.tree : null; 165 } 166} 167