1/* 2 * Copyright (c) 1994, 2003, 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 sun.tools.tree; 27 28import sun.tools.java.*; 29import sun.tools.asm.Assembler; 30import java.io.PrintStream; 31import java.util.Hashtable; 32 33/** 34 * WARNING: The contents of this source file are not part of any 35 * supported API. Code that depends on them does so at its own risk: 36 * they are subject to change or removal without notice. 37 */ 38public 39class ThisExpression extends Expression { 40 LocalMember field; 41 Expression implementation; 42 Expression outerArg; 43 44 /** 45 * Constructor 46 */ 47 public ThisExpression(long where) { 48 super(THIS, where, Type.tObject); 49 } 50 protected ThisExpression(int op, long where) { 51 super(op, where, Type.tObject); 52 } 53 public ThisExpression(long where, LocalMember field) { 54 super(THIS, where, Type.tObject); 55 this.field = field; 56 field.readcount++; 57 } 58 public ThisExpression(long where, Context ctx) { 59 super(THIS, where, Type.tObject); 60 field = ctx.getLocalField(idThis); 61 field.readcount++; 62 } 63 64 /** 65 * Constructor for "x.this()" 66 */ 67 public ThisExpression(long where, Expression outerArg) { 68 this(where); 69 this.outerArg = outerArg; 70 } 71 72 public Expression getImplementation() { 73 if (implementation != null) 74 return implementation; 75 return this; 76 } 77 78 /** 79 * From the 'this' in an expression of the form outer.this(...), 80 * or the 'super' in an expression of the form outer.super(...), 81 * return the "outer" expression, or null if there is none. 82 */ 83 public Expression getOuterArg() { 84 return outerArg; 85 } 86 87 /** 88 * Check expression 89 */ 90 public Vset checkValue(Environment env, Context ctx, Vset vset, Hashtable<Object, Object> exp) { 91 if (ctx.field.isStatic()) { 92 env.error(where, "undef.var", opNames[op]); 93 type = Type.tError; 94 return vset; 95 } 96 if (field == null) { 97 field = ctx.getLocalField(idThis); 98 field.readcount++; 99 } 100 if (field.scopeNumber < ctx.frameNumber) { 101 // get a "this$C" copy via the current object 102 implementation = ctx.makeReference(env, field); 103 } 104 if (!vset.testVar(field.number)) { 105 env.error(where, "access.inst.before.super", opNames[op]); 106 } 107 if (field == null) { 108 type = ctx.field.getClassDeclaration().getType(); 109 } else { 110 type = field.getType(); 111 } 112 return vset; 113 } 114 115 public boolean isNonNull() { 116 return true; 117 } 118 119 // A 'ThisExpression' node can never appear on the LHS of an assignment in a correct 120 // program, but handle this case anyhow to provide a safe error recovery. 121 122 public FieldUpdater getAssigner(Environment env, Context ctx) { 123 return null; 124 } 125 126 public FieldUpdater getUpdater(Environment env, Context ctx) { 127 return null; 128 } 129 130 /** 131 * Inline 132 */ 133 public Expression inlineValue(Environment env, Context ctx) { 134 if (implementation != null) 135 return implementation.inlineValue(env, ctx); 136 if (field != null && field.isInlineable(env, false)) { 137 Expression e = (Expression)field.getValue(env); 138 //System.out.println("INLINE = "+ e + ", THIS"); 139 if (e != null) { 140 e = e.copyInline(ctx); 141 e.type = type; // in case op==SUPER 142 return e; 143 } 144 } 145 return this; 146 } 147 148 /** 149 * Create a copy of the expression for method inlining 150 */ 151 public Expression copyInline(Context ctx) { 152 if (implementation != null) 153 return implementation.copyInline(ctx); 154 ThisExpression e = (ThisExpression)clone(); 155 if (field == null) { 156 // The expression is copied into the context of a method 157 e.field = ctx.getLocalField(idThis); 158 e.field.readcount++; 159 } else { 160 e.field = field.getCurrentInlineCopy(ctx); 161 } 162 if (outerArg != null) { 163 e.outerArg = outerArg.copyInline(ctx); 164 } 165 return e; 166 } 167 168 /** 169 * Code 170 */ 171 public void codeValue(Environment env, Context ctx, Assembler asm) { 172 asm.add(where, opc_aload, field.number); 173 } 174 175 /** 176 * Print 177 */ 178 public void print(PrintStream out) { 179 if (outerArg != null) { 180 out.print("(outer="); 181 outerArg.print(out); 182 out.print(" "); 183 } 184 String pfx = (field == null) ? "" 185 : field.getClassDefinition().getName().getFlatName().getName()+"."; 186 pfx += opNames[op]; 187 out.print(pfx + "#" + ((field != null) ? field.hashCode() : 0)); 188 if (outerArg != null) 189 out.print(")"); 190 } 191} 192