src/share/classes/sun/rmi/rmic/iiop/ContextStack.java

Fri, 14 Jun 2013 16:31:55 +0100

author
msheppar
date
Fri, 14 Jun 2013 16:31:55 +0100
changeset 512
81d694b1ab2f
parent 158
91006f157c46
child 748
6845b95cba6b
permissions
-rw-r--r--

8011157: Improve CORBA portablility
Summary: fix also reviewed by Alexander Fomin
Reviewed-by: alanb, coffeys, skoivu

duke@1 1 /*
ohair@158 2 * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
ohair@158 7 * published by the Free Software Foundation. Oracle designates this
duke@1 8 * particular file as subject to the "Classpath" exception as provided
ohair@158 9 * by Oracle in the LICENSE file that accompanied this code.
duke@1 10 *
duke@1 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 15 * accompanied this code).
duke@1 16 *
duke@1 17 * You should have received a copy of the GNU General Public License version
duke@1 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 20 *
ohair@158 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@158 22 * or visit www.oracle.com if you need additional information or have any
ohair@158 23 * questions.
duke@1 24 */
duke@1 25
duke@1 26 /*
duke@1 27 * Licensed Materials - Property of IBM
duke@1 28 * RMI-IIOP v1.0
duke@1 29 * Copyright IBM Corp. 1998 1999 All Rights Reserved
duke@1 30 *
duke@1 31 */
duke@1 32
duke@1 33 package sun.rmi.rmic.iiop;
duke@1 34
duke@1 35 import sun.tools.java.CompilerError;
duke@1 36
duke@1 37 /**
duke@1 38 * ContextStack provides a mechanism to record parsing state.
duke@1 39 *
duke@1 40 * @author Bryan Atsatt
duke@1 41 */
duke@1 42 public class ContextStack {
duke@1 43
duke@1 44 // Context codes.
duke@1 45
duke@1 46 public static final int TOP = 1;
duke@1 47
duke@1 48 public static final int METHOD = 2;
duke@1 49 public static final int METHOD_RETURN = 3;
duke@1 50 public static final int METHOD_ARGUMENT = 4;
duke@1 51 public static final int METHOD_EXCEPTION = 5;
duke@1 52
duke@1 53 public static final int MEMBER = 6;
duke@1 54 public static final int MEMBER_CONSTANT = 7;
duke@1 55 public static final int MEMBER_STATIC = 8;
duke@1 56 public static final int MEMBER_TRANSIENT = 9;
duke@1 57
duke@1 58 public static final int IMPLEMENTS = 10;
duke@1 59 public static final int EXTENDS = 11;
duke@1 60
duke@1 61 // String versions of context codes.
duke@1 62
duke@1 63 private static final String[] CODE_NAMES = {
duke@1 64 "UNKNOWN ",
duke@1 65 "Top level type ",
duke@1 66 "Method ",
duke@1 67 "Return parameter ",
duke@1 68 "Parameter ",
duke@1 69 "Exception ",
duke@1 70 "Member ",
duke@1 71 "Constant member ",
duke@1 72 "Static member ",
duke@1 73 "Transient member ",
duke@1 74 "Implements ",
duke@1 75 "Extends ",
duke@1 76 };
duke@1 77 // Member data.
duke@1 78
duke@1 79 private int currentIndex = -1;
duke@1 80 private int maxIndex = 100;
duke@1 81 private TypeContext[] stack = new TypeContext[maxIndex];
duke@1 82 private int newCode = TOP;
duke@1 83 private BatchEnvironment env = null;
duke@1 84 private boolean trace = false;
duke@1 85 private TypeContext tempContext = new TypeContext();
duke@1 86
duke@1 87 private static final String TRACE_INDENT = " ";
duke@1 88
duke@1 89 /**
duke@1 90 * Constructor.
duke@1 91 */
duke@1 92 public ContextStack (BatchEnvironment env) {
duke@1 93 this.env = env;
duke@1 94 env.contextStack = this;
duke@1 95 }
duke@1 96
duke@1 97 /**
duke@1 98 * Return true if env.nerrors > 0.
duke@1 99 */
duke@1 100 public boolean anyErrors () {
duke@1 101 return env.nerrors > 0;
duke@1 102 }
duke@1 103
duke@1 104 /**
duke@1 105 * Enable/disable tracing.
duke@1 106 */
duke@1 107 public void setTrace(boolean trace) {
duke@1 108 this.trace = trace;
duke@1 109 }
duke@1 110
duke@1 111 /**
duke@1 112 * Check trace flag.
duke@1 113 */
duke@1 114 public boolean isTraceOn() {
duke@1 115 return trace;
duke@1 116 }
duke@1 117
duke@1 118 /**
duke@1 119 * Get the environment.
duke@1 120 */
duke@1 121 public BatchEnvironment getEnv() {
duke@1 122 return env;
duke@1 123 }
duke@1 124
duke@1 125 /**
duke@1 126 * Set the new context.
duke@1 127 */
duke@1 128 public void setNewContextCode(int code) {
duke@1 129 newCode = code;
duke@1 130 }
duke@1 131
duke@1 132 /**
duke@1 133 * Get the current context code.
duke@1 134 */
duke@1 135 public int getCurrentContextCode() {
duke@1 136 return newCode;
duke@1 137 }
duke@1 138
duke@1 139
duke@1 140 /**
duke@1 141 * If tracing on, write the current call stack (not the context stack) to
duke@1 142 * System.out.
duke@1 143 */
duke@1 144 final void traceCallStack () {
duke@1 145 if (trace) dumpCallStack();
duke@1 146 }
duke@1 147
duke@1 148 public final static void dumpCallStack() {
duke@1 149 new Error().printStackTrace(System.out);
duke@1 150 }
duke@1 151
duke@1 152 /**
duke@1 153 * Print a line indented by stack depth.
duke@1 154 */
duke@1 155 final private void tracePrint (String text, boolean line) {
duke@1 156 int length = text.length() + (currentIndex * TRACE_INDENT.length());
duke@1 157 StringBuffer buffer = new StringBuffer(length);
duke@1 158 for (int i = 0; i < currentIndex; i++) {
duke@1 159 buffer.append(TRACE_INDENT);
duke@1 160 }
duke@1 161 buffer.append(text);
duke@1 162 if (line) {
duke@1 163 buffer.append("\n");
duke@1 164 }
duke@1 165 System.out.print(buffer.toString());
duke@1 166 }
duke@1 167
duke@1 168 /**
duke@1 169 * If tracing on, print a line.
duke@1 170 */
duke@1 171 final void trace (String text) {
duke@1 172 if (trace) {
duke@1 173 tracePrint(text,false);
duke@1 174 }
duke@1 175 }
duke@1 176
duke@1 177 /**
duke@1 178 * If tracing on, print a line followed by a '\n'.
duke@1 179 */
duke@1 180 final void traceln (String text) {
duke@1 181 if (trace) {
duke@1 182 tracePrint(text,true);
duke@1 183 }
duke@1 184 }
duke@1 185
duke@1 186 /**
duke@1 187 * If tracing on, print a pre-mapped ContextElement.
duke@1 188 */
duke@1 189 final void traceExistingType (Type type) {
duke@1 190 if (trace) {
duke@1 191 tempContext.set(newCode,type);
duke@1 192 traceln(toResultString(tempContext,true,true));
duke@1 193 }
duke@1 194 }
duke@1 195
duke@1 196 /**
duke@1 197 * Push a new element on the stack.
duke@1 198 * @return the new element.
duke@1 199 */
duke@1 200 public TypeContext push (ContextElement element) {
duke@1 201
duke@1 202 currentIndex++;
duke@1 203
duke@1 204 // Grow array if need to...
duke@1 205
duke@1 206 if (currentIndex == maxIndex) {
duke@1 207 int newMax = maxIndex * 2;
duke@1 208 TypeContext[] newStack = new TypeContext[newMax];
duke@1 209 System.arraycopy(stack,0,newStack,0,maxIndex);
duke@1 210 maxIndex = newMax;
duke@1 211 stack = newStack;
duke@1 212 }
duke@1 213
duke@1 214 // Make sure we have a context object to use at this position...
duke@1 215
duke@1 216 TypeContext it = stack[currentIndex];
duke@1 217
duke@1 218 if (it == null) {
duke@1 219 it = new TypeContext();
duke@1 220 stack[currentIndex] = it;
duke@1 221 }
duke@1 222
duke@1 223 // Set the context object...
duke@1 224
duke@1 225 it.set(newCode,element);
duke@1 226
duke@1 227 // Trace...
duke@1 228
duke@1 229 traceln(toTrialString(it));
duke@1 230
duke@1 231 // Return...
duke@1 232
duke@1 233 return it;
duke@1 234 }
duke@1 235
duke@1 236 /**
duke@1 237 * Pop an element from the stack.
duke@1 238 * @return the new current element or null if top.
duke@1 239 */
duke@1 240 public TypeContext pop (boolean wasValid) {
duke@1 241
duke@1 242 if (currentIndex < 0) {
duke@1 243 throw new CompilerError("Nothing on stack!");
duke@1 244 }
duke@1 245
duke@1 246 newCode = stack[currentIndex].getCode();
duke@1 247 traceln(toResultString(stack[currentIndex],wasValid,false));
duke@1 248
duke@1 249 Type last = stack[currentIndex].getCandidateType();
duke@1 250 if (last != null) {
duke@1 251
duke@1 252 // Set status...
duke@1 253
duke@1 254 if (wasValid) {
duke@1 255 last.setStatus(Constants.STATUS_VALID);
duke@1 256 } else {
duke@1 257 last.setStatus(Constants.STATUS_INVALID);
duke@1 258 }
duke@1 259 }
duke@1 260
duke@1 261 currentIndex--;
duke@1 262
duke@1 263 if (currentIndex < 0) {
duke@1 264
duke@1 265 // Done parsing, so update the invalid types
duke@1 266 // if this type was valid...
duke@1 267
duke@1 268 if (wasValid) {
duke@1 269 Type.updateAllInvalidTypes(this);
duke@1 270 }
duke@1 271 return null;
duke@1 272 } else {
duke@1 273 return stack[currentIndex];
duke@1 274 }
duke@1 275 }
duke@1 276
duke@1 277 /**
duke@1 278 * Get the current size.
duke@1 279 */
duke@1 280 public int size () {
duke@1 281 return currentIndex + 1;
duke@1 282 }
duke@1 283
duke@1 284 /**
duke@1 285 * Get a specific context.
duke@1 286 */
duke@1 287 public TypeContext getContext (int index) {
duke@1 288
duke@1 289 if (currentIndex < index) {
duke@1 290 throw new Error("Index out of range");
duke@1 291 }
duke@1 292 return stack[index];
duke@1 293 }
duke@1 294
duke@1 295 /**
duke@1 296 * Get the current top context.
duke@1 297 */
duke@1 298 public TypeContext getContext () {
duke@1 299
duke@1 300 if (currentIndex < 0) {
duke@1 301 throw new Error("Nothing on stack!");
duke@1 302 }
duke@1 303 return stack[currentIndex];
duke@1 304 }
duke@1 305
duke@1 306 /**
duke@1 307 * Is parent context a value type?
duke@1 308 */
duke@1 309 public boolean isParentAValue () {
duke@1 310
duke@1 311 if (currentIndex > 0) {
duke@1 312 return stack[currentIndex - 1].isValue();
duke@1 313 } else {
duke@1 314 return false;
duke@1 315 }
duke@1 316 }
duke@1 317
duke@1 318 /**
duke@1 319 * Get parent context. Null if none.
duke@1 320 */
duke@1 321 public TypeContext getParentContext () {
duke@1 322
duke@1 323 if (currentIndex > 0) {
duke@1 324 return stack[currentIndex - 1];
duke@1 325 } else {
duke@1 326 return null;
duke@1 327 }
duke@1 328 }
duke@1 329
duke@1 330 /**
duke@1 331 * Get a string for the context name...
duke@1 332 */
duke@1 333 public String getContextCodeString () {
duke@1 334
duke@1 335 if (currentIndex >= 0) {
duke@1 336 return CODE_NAMES[newCode];
duke@1 337 } else {
duke@1 338 return CODE_NAMES[0];
duke@1 339 }
duke@1 340 }
duke@1 341
duke@1 342 /**
duke@1 343 * Get a string for the given context code...
duke@1 344 */
duke@1 345 public static String getContextCodeString (int contextCode) {
duke@1 346 return CODE_NAMES[contextCode];
duke@1 347 }
duke@1 348
duke@1 349 private String toTrialString(TypeContext it) {
duke@1 350 int code = it.getCode();
duke@1 351 if (code != METHOD && code != MEMBER) {
duke@1 352 return it.toString() + " (trying " + it.getTypeDescription() + ")";
duke@1 353 } else {
duke@1 354 return it.toString();
duke@1 355 }
duke@1 356 }
duke@1 357
duke@1 358 private String toResultString (TypeContext it, boolean result, boolean preExisting) {
duke@1 359 int code = it.getCode();
duke@1 360 if (code != METHOD && code != MEMBER) {
duke@1 361 if (result) {
duke@1 362 String str = it.toString() + " --> " + it.getTypeDescription();
duke@1 363 if (preExisting) {
duke@1 364 return str + " [Previously mapped]";
duke@1 365 } else {
duke@1 366 return str;
duke@1 367 }
duke@1 368 }
duke@1 369 } else {
duke@1 370 if (result) {
duke@1 371 return it.toString() + " --> [Mapped]";
duke@1 372 }
duke@1 373 }
duke@1 374 return it.toString() + " [Did not map]";
duke@1 375 }
duke@1 376
duke@1 377 public void clear () {
duke@1 378 for (int i = 0; i < stack.length; i++) {
duke@1 379 if (stack[i] != null) stack[i].destroy();
duke@1 380 }
duke@1 381 }
duke@1 382 }
duke@1 383
duke@1 384
duke@1 385 class TypeContext {
duke@1 386
duke@1 387 public void set(int code, ContextElement element) {
duke@1 388 this.code = code;
duke@1 389 this.element = element;
duke@1 390 if (element instanceof ValueType) {
duke@1 391 isValue = true;
duke@1 392 } else {
duke@1 393 isValue = false;
duke@1 394 }
duke@1 395 }
duke@1 396
duke@1 397 public int getCode() {
duke@1 398 return code;
duke@1 399 }
duke@1 400
duke@1 401 public String getName() {
duke@1 402 return element.getElementName();
duke@1 403 }
duke@1 404
duke@1 405 public Type getCandidateType() {
duke@1 406 if (element instanceof Type) {
duke@1 407 return (Type) element;
duke@1 408 } else {
duke@1 409 return null;
duke@1 410 }
duke@1 411 }
duke@1 412
duke@1 413 public String getTypeDescription() {
duke@1 414 if (element instanceof Type) {
duke@1 415 return ((Type) element).getTypeDescription();
duke@1 416 } else {
duke@1 417 return "[unknown type]";
duke@1 418 }
duke@1 419 }
duke@1 420
duke@1 421 public String toString () {
duke@1 422 if (element != null) {
duke@1 423 return ContextStack.getContextCodeString(code) + element.getElementName();
duke@1 424 } else {
duke@1 425 return ContextStack.getContextCodeString(code) + "null";
duke@1 426 }
duke@1 427 }
duke@1 428
duke@1 429 public boolean isValue () {
duke@1 430 return isValue;
duke@1 431 }
duke@1 432
duke@1 433 public boolean isConstant () {
duke@1 434 return code == ContextStack.MEMBER_CONSTANT;
duke@1 435 }
duke@1 436
duke@1 437 public void destroy() {
duke@1 438 if (element instanceof Type) {
duke@1 439 ((Type)element).destroy();
duke@1 440 }
duke@1 441 element = null;
duke@1 442 }
duke@1 443
duke@1 444 private int code = 0;
duke@1 445 private ContextElement element = null;
duke@1 446 private boolean isValue = false;
duke@1 447 }

mercurial