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

Thu, 24 May 2018 16:41:12 +0800

author
aoqi
date
Thu, 24 May 2018 16:41:12 +0800
changeset 1410
9c913ea7e4a1
parent 748
6845b95cba6b
permissions
-rw-r--r--

Merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 /*
aoqi@0 27 * Licensed Materials - Property of IBM
aoqi@0 28 * RMI-IIOP v1.0
aoqi@0 29 * Copyright IBM Corp. 1998 1999 All Rights Reserved
aoqi@0 30 *
aoqi@0 31 */
aoqi@0 32
aoqi@0 33 package sun.rmi.rmic.iiop;
aoqi@0 34
aoqi@0 35 import java.util.Arrays;
aoqi@0 36 import java.util.Vector;
aoqi@0 37 import sun.tools.java.Identifier;
aoqi@0 38 import sun.tools.java.ClassNotFound;
aoqi@0 39 import sun.tools.java.ClassDefinition;
aoqi@0 40 import sun.tools.java.ClassDeclaration;
aoqi@0 41 import sun.tools.java.MemberDefinition;
aoqi@0 42 import sun.tools.java.CompilerError;
aoqi@0 43 import sun.tools.tree.Node;
aoqi@0 44 import sun.tools.tree.LocalMember;
aoqi@0 45 import sun.tools.tree.CharExpression;
aoqi@0 46 import sun.tools.tree.IntegerExpression;
aoqi@0 47 import sun.rmi.rmic.IndentingWriter;
aoqi@0 48 import java.io.IOException;
aoqi@0 49 import java.util.HashSet;
aoqi@0 50 import java.util.Enumeration;
aoqi@0 51 import java.io.File;
aoqi@0 52
aoqi@0 53 /**
aoqi@0 54 * A CompoundType is an abstract base class for all IIOP class and
aoqi@0 55 * interface types.
aoqi@0 56 *
aoqi@0 57 * @author Bryan Atsatt
aoqi@0 58 */
aoqi@0 59 public abstract class CompoundType extends Type {
aoqi@0 60
aoqi@0 61 protected Method[] methods;
aoqi@0 62 protected InterfaceType[] interfaces;
aoqi@0 63 protected Member[] members;
aoqi@0 64 protected ClassDefinition classDef;
aoqi@0 65 protected ClassDeclaration classDecl;
aoqi@0 66
aoqi@0 67 protected boolean isCORBAObject = false;
aoqi@0 68 protected boolean isIDLEntity = false;
aoqi@0 69 protected boolean isAbstractBase = false;
aoqi@0 70 protected boolean isValueBase = false;
aoqi@0 71 protected boolean isCORBAUserException = false;
aoqi@0 72 protected boolean isException = false;
aoqi@0 73 protected boolean isCheckedException = false;
aoqi@0 74 protected boolean isRemoteExceptionOrSubclass = false;
aoqi@0 75 protected String idlExceptionName;
aoqi@0 76 protected String qualifiedIDLExceptionName;
aoqi@0 77
aoqi@0 78 //_____________________________________________________________________
aoqi@0 79 // Public Interfaces
aoqi@0 80 //_____________________________________________________________________
aoqi@0 81
aoqi@0 82 /**
aoqi@0 83 * Return true if this type implements
aoqi@0 84 * org.omg.CORBA.Object.
aoqi@0 85 */
aoqi@0 86 public boolean isCORBAObject () {
aoqi@0 87 return isCORBAObject;
aoqi@0 88 }
aoqi@0 89
aoqi@0 90 /**
aoqi@0 91 * Return true if this type implements
aoqi@0 92 * org.omg.CORBA.portable.IDLEntity.
aoqi@0 93 */
aoqi@0 94 public boolean isIDLEntity () {
aoqi@0 95 return isIDLEntity;
aoqi@0 96 }
aoqi@0 97
aoqi@0 98 /**
aoqi@0 99 * Return true if this type implements
aoqi@0 100 * org.omg.CORBA.portable.ValueBase.
aoqi@0 101 */
aoqi@0 102 public boolean isValueBase () {
aoqi@0 103 return isValueBase;
aoqi@0 104 }
aoqi@0 105
aoqi@0 106 /**
aoqi@0 107 * Return true if this type is a CORBA
aoqi@0 108 * abstract interface.
aoqi@0 109 */
aoqi@0 110 public boolean isAbstractBase () {
aoqi@0 111 return isAbstractBase;
aoqi@0 112 }
aoqi@0 113
aoqi@0 114 /**
aoqi@0 115 * Return true if this type is an exception.
aoqi@0 116 */
aoqi@0 117 public boolean isException () {
aoqi@0 118 return isException;
aoqi@0 119 }
aoqi@0 120
aoqi@0 121 /**
aoqi@0 122 * Return true if this type is a "checked" exception.
aoqi@0 123 * Result if valid iff isException() returns true.
aoqi@0 124 */
aoqi@0 125 public boolean isCheckedException () {
aoqi@0 126 return isCheckedException;
aoqi@0 127 }
aoqi@0 128
aoqi@0 129 /**
aoqi@0 130 * Return true if this type is a java.rmi.RemoteException
aoqi@0 131 * or one of its subclasses. Result if valid iff isException()
aoqi@0 132 * returns true.
aoqi@0 133 */
aoqi@0 134 public boolean isRemoteExceptionOrSubclass () {
aoqi@0 135 return isRemoteExceptionOrSubclass;
aoqi@0 136 }
aoqi@0 137
aoqi@0 138 /**
aoqi@0 139 * Return true if this type is exactly
aoqi@0 140 * org.omg.CORBA.UserException.
aoqi@0 141 */
aoqi@0 142 public boolean isCORBAUserException () {
aoqi@0 143 return isCORBAUserException;
aoqi@0 144 }
aoqi@0 145
aoqi@0 146 /**
aoqi@0 147 * Return true if this type implements
aoqi@0 148 * isIDLEntity() && isException().
aoqi@0 149 */
aoqi@0 150 public boolean isIDLEntityException () {
aoqi@0 151 return isIDLEntity() && isException();
aoqi@0 152 }
aoqi@0 153 /**
aoqi@0 154 * Return true if isIDLEntity() && !isValueBase()
aoqi@0 155 * && !isAbstractBase() && !isCORBAObject()
aoqi@0 156 * && !isIDLEntityException().
aoqi@0 157 */
aoqi@0 158 public boolean isBoxed () {
aoqi@0 159 return (isIDLEntity() && !isValueBase() &&
aoqi@0 160 !isAbstractBase() && !isCORBAObject() &&
aoqi@0 161 !isIDLEntityException());
aoqi@0 162 }
aoqi@0 163
aoqi@0 164 /**
aoqi@0 165 * If this type represents an exception, return the
aoqi@0 166 * IDL name including the "Ex" mangling, otherwise
aoqi@0 167 * return null.
aoqi@0 168 */
aoqi@0 169 public String getIDLExceptionName () {
aoqi@0 170 return idlExceptionName;
aoqi@0 171 }
aoqi@0 172
aoqi@0 173 /**
aoqi@0 174 * If this type represents an exception, return the
aoqi@0 175 * qualified IDL name including the "Ex" mangling,
aoqi@0 176 * otherwise return null.
aoqi@0 177 * @param global If true, prepends "::".
aoqi@0 178 */
aoqi@0 179 public String getQualifiedIDLExceptionName (boolean global) {
aoqi@0 180 if (qualifiedIDLExceptionName != null &&
aoqi@0 181 global &&
aoqi@0 182 getIDLModuleNames().length > 0) {
aoqi@0 183 return IDL_NAME_SEPARATOR + qualifiedIDLExceptionName;
aoqi@0 184 } else {
aoqi@0 185 return qualifiedIDLExceptionName;
aoqi@0 186 }
aoqi@0 187 }
aoqi@0 188
aoqi@0 189 /**
aoqi@0 190 * Return signature for this type (e.g. com.acme.Dynamite
aoqi@0 191 * would return "com.acme.Dynamite", byte = "B")
aoqi@0 192 */
aoqi@0 193 public String getSignature() {
aoqi@0 194 String sig = classDecl.getType().getTypeSignature();
aoqi@0 195 if (sig.endsWith(";")) {
aoqi@0 196 sig = sig.substring(0,sig.length()-1);
aoqi@0 197 }
aoqi@0 198 return sig;
aoqi@0 199 }
aoqi@0 200
aoqi@0 201 /**
aoqi@0 202 * Return the ClassDeclaration for this type.
aoqi@0 203 */
aoqi@0 204 public ClassDeclaration getClassDeclaration() {
aoqi@0 205 return classDecl;
aoqi@0 206 }
aoqi@0 207
aoqi@0 208 /**
aoqi@0 209 * Return the ClassDefinition for this type.
aoqi@0 210 */
aoqi@0 211 public ClassDefinition getClassDefinition() {
aoqi@0 212 return classDef;
aoqi@0 213 }
aoqi@0 214
aoqi@0 215 /**
aoqi@0 216 * Return the parent class of this type. Returns null if this
aoqi@0 217 * type is an interface or if there is no parent.
aoqi@0 218 */
aoqi@0 219 public ClassType getSuperclass() {
aoqi@0 220 return null;
aoqi@0 221 }
aoqi@0 222
aoqi@0 223 /**
aoqi@0 224 * Return an array of interfaces directly implemented by this type.
aoqi@0 225 * <p>
aoqi@0 226 * The order of the array returned is arbitrary.
aoqi@0 227 */
aoqi@0 228 public InterfaceType[] getInterfaces() {
aoqi@0 229 if( interfaces != null ) {
aoqi@0 230 return (InterfaceType[]) interfaces.clone();
aoqi@0 231 }
aoqi@0 232 return null;
aoqi@0 233 }
aoqi@0 234
aoqi@0 235 /**
aoqi@0 236 * Return an array of Type.Method objects representing all
aoqi@0 237 * of the methods implemented directly by this type.
aoqi@0 238 */
aoqi@0 239 public Method[] getMethods() {
aoqi@0 240 if( methods != null ) {
aoqi@0 241 return (Method[]) methods.clone();
aoqi@0 242 }
aoqi@0 243 return null;
aoqi@0 244 }
aoqi@0 245
aoqi@0 246 /**
aoqi@0 247 * Return an array of Type.Member objects representing all of
aoqi@0 248 * the data members directly implemented by this interface.
aoqi@0 249 */
aoqi@0 250 public Member[] getMembers() {
aoqi@0 251 if( members != null ) {
aoqi@0 252 return (Member[]) members.clone();
aoqi@0 253 }
aoqi@0 254 return null;
aoqi@0 255 }
aoqi@0 256
aoqi@0 257 /**
aoqi@0 258 * Create a CompoundType object for the given class.
aoqi@0 259 *
aoqi@0 260 * If the class is not a properly formed or if some other error occurs, the
aoqi@0 261 * return value will be null, and errors will have been reported to the
aoqi@0 262 * supplied BatchEnvironment.
aoqi@0 263 */
aoqi@0 264 public static CompoundType forCompound (ClassDefinition classDef,
aoqi@0 265 ContextStack stack) {
aoqi@0 266 CompoundType result = null;
aoqi@0 267
aoqi@0 268 try {
aoqi@0 269 result = (CompoundType) makeType(classDef.getType(),classDef,stack);
aoqi@0 270 } catch (ClassCastException e) {}
aoqi@0 271
aoqi@0 272 return result;
aoqi@0 273 }
aoqi@0 274
aoqi@0 275
aoqi@0 276 //_____________________________________________________________________
aoqi@0 277 // Subclass/Internal Interfaces
aoqi@0 278 //_____________________________________________________________________
aoqi@0 279
aoqi@0 280 /**
aoqi@0 281 * Release all resources.
aoqi@0 282 */
aoqi@0 283 protected void destroy () {
aoqi@0 284 if (!destroyed) {
aoqi@0 285 super.destroy();
aoqi@0 286
aoqi@0 287 if (methods != null) {
aoqi@0 288 for (int i = 0; i < methods.length; i++) {
aoqi@0 289 if (methods[i] != null) methods[i].destroy();
aoqi@0 290 }
aoqi@0 291 methods = null;
aoqi@0 292 }
aoqi@0 293
aoqi@0 294 if (interfaces != null) {
aoqi@0 295 for (int i = 0; i < interfaces.length; i++) {
aoqi@0 296 if (interfaces[i] != null) interfaces[i].destroy();
aoqi@0 297 }
aoqi@0 298 interfaces = null;
aoqi@0 299 }
aoqi@0 300
aoqi@0 301 if (members != null) {
aoqi@0 302 for (int i = 0; i < members.length; i++) {
aoqi@0 303 if (members[i] != null) members[i].destroy();
aoqi@0 304 }
aoqi@0 305 members = null;
aoqi@0 306 }
aoqi@0 307
aoqi@0 308 classDef = null;
aoqi@0 309 classDecl = null;
aoqi@0 310 }
aoqi@0 311 }
aoqi@0 312
aoqi@0 313 /*
aoqi@0 314 * Load a Class instance. Return null if fail.
aoqi@0 315 */
aoqi@0 316 protected Class loadClass() {
aoqi@0 317
aoqi@0 318 Class ourClass = null;
aoqi@0 319
aoqi@0 320 // To avoid getting out-of-date Class instances, and
aoqi@0 321 // to ensure that there is an instance, we must compile
aoqi@0 322 // any classes that we've seen and which are not yet
aoqi@0 323 // compiled. We can't just compile this class, 'cuz it
aoqi@0 324 // may have dependencies on classes which have not been
aoqi@0 325 // compiled...
aoqi@0 326
aoqi@0 327 try {
aoqi@0 328 env.getMain().compileAllClasses(env);
aoqi@0 329 } catch (Exception e1) {
aoqi@0 330 for (Enumeration e = env.getClasses() ; e.hasMoreElements() ; ) {
aoqi@0 331 ClassDeclaration c = (ClassDeclaration)e.nextElement();
aoqi@0 332 }
aoqi@0 333 failedConstraint(26,false,stack,"required classes");
aoqi@0 334 env.flushErrors();
aoqi@0 335 }
aoqi@0 336
aoqi@0 337 // Now try to get the Class...
aoqi@0 338 // The outer try block is there for people who might want to use
aoqi@0 339 // the compiler at run-time of their AS.
aoqi@0 340 // They could set and use their own context class loader for loading
aoqi@0 341 // classes directly.
aoqi@0 342 try {
aoqi@0 343 ClassLoader cl = Thread.currentThread().getContextClassLoader();
aoqi@0 344 ourClass = cl.loadClass(getQualifiedName());
aoqi@0 345 } catch(ClassNotFoundException cfe) {
aoqi@0 346
aoqi@0 347 try {
aoqi@0 348 ourClass = env.classPathLoader.loadClass(getQualifiedName());
aoqi@0 349 } catch (NullPointerException e) {
aoqi@0 350 // This should never happen
aoqi@0 351 } catch (ClassNotFoundException e) {
aoqi@0 352 // Fall through to the next case (which is to look in the
aoqi@0 353 // output directory for generated files)
aoqi@0 354 }
aoqi@0 355 }
aoqi@0 356
aoqi@0 357 /* This piece of code used to cause the compiler to ignore jar files
aoqi@0 358 on its classpath
aoqi@0 359 try {
aoqi@0 360 ourClass = Util.loadClass(getQualifiedName(),null,null);
aoqi@0 361 } catch (ClassNotFoundException e) {
aoqi@0 362 } catch (LinkageError e) {
aoqi@0 363 }
aoqi@0 364 */
aoqi@0 365
aoqi@0 366 if (ourClass == null) {
aoqi@0 367
aoqi@0 368 // Try one last thing. If the class was compiled into
aoqi@0 369 // a directory that's not in the classpath, the load
aoqi@0 370 // will fail. Let's get the bits off the disk and load
aoqi@0 371 // it directly...
aoqi@0 372
aoqi@0 373 if (env.loader == null) {
aoqi@0 374 File destDir = env.getMain().getDestinationDir();
aoqi@0 375 if (destDir == null) {
aoqi@0 376 destDir = new File(".");
aoqi@0 377 }
aoqi@0 378 env.loader = new DirectoryLoader(destDir);
aoqi@0 379 }
aoqi@0 380
aoqi@0 381 try {
aoqi@0 382 ourClass = env.loader.loadClass(getQualifiedName());
aoqi@0 383 } catch (Exception e) {}
aoqi@0 384 }
aoqi@0 385
aoqi@0 386 return ourClass;
aoqi@0 387 }
aoqi@0 388
aoqi@0 389 // Print "extends XX"
aoqi@0 390
aoqi@0 391 protected boolean printExtends (IndentingWriter writer,
aoqi@0 392 boolean useQualifiedNames,
aoqi@0 393 boolean useIDLNames,
aoqi@0 394 boolean globalIDLNames) throws IOException {
aoqi@0 395
aoqi@0 396 ClassType parent = getSuperclass();
aoqi@0 397
aoqi@0 398 if (parent != null && (!useIDLNames ||
aoqi@0 399 (!parent.isType(TYPE_ANY) && !parent.isType(TYPE_CORBA_OBJECT)))) {
aoqi@0 400 writer.p(" extends ");
aoqi@0 401 parent.printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
aoqi@0 402 return true;
aoqi@0 403 }
aoqi@0 404 return false;
aoqi@0 405 }
aoqi@0 406
aoqi@0 407 // Print "implements XX, YY"
aoqi@0 408
aoqi@0 409 protected void printImplements (IndentingWriter writer,
aoqi@0 410 String prefix,
aoqi@0 411 boolean useQualifiedNames,
aoqi@0 412 boolean useIDLNames,
aoqi@0 413 boolean globalIDLNames) throws IOException {
aoqi@0 414
aoqi@0 415 InterfaceType[] interfaces = getInterfaces();
aoqi@0 416
aoqi@0 417 String adjective = " implements";
aoqi@0 418
aoqi@0 419 if (isInterface()) {
aoqi@0 420 adjective = " extends";
aoqi@0 421 }
aoqi@0 422
aoqi@0 423 if (useIDLNames) {
aoqi@0 424 adjective = ":";
aoqi@0 425 }
aoqi@0 426
aoqi@0 427 for (int i = 0; i < interfaces.length; i++) {
aoqi@0 428 if (!useIDLNames || (!interfaces[i].isType(TYPE_ANY) && !interfaces[i].isType(TYPE_CORBA_OBJECT))) {
aoqi@0 429 if (i == 0) {
aoqi@0 430 writer.p(prefix + adjective + " ");
aoqi@0 431 } else {
aoqi@0 432 writer.p(", ");
aoqi@0 433 }
aoqi@0 434 interfaces[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
aoqi@0 435 }
aoqi@0 436 }
aoqi@0 437 }
aoqi@0 438
aoqi@0 439 // Print members
aoqi@0 440
aoqi@0 441 protected void printMembers ( IndentingWriter writer,
aoqi@0 442 boolean useQualifiedNames,
aoqi@0 443 boolean useIDLNames,
aoqi@0 444 boolean globalIDLNames) throws IOException {
aoqi@0 445
aoqi@0 446 CompoundType.Member[] members = getMembers();
aoqi@0 447
aoqi@0 448 for (int i = 0; i < members.length; i++) {
aoqi@0 449 if (!members[i].isInnerClassDeclaration()) {
aoqi@0 450 Type it = members[i].getType();
aoqi@0 451 String visibility = members[i].getVisibility();
aoqi@0 452 String name;
aoqi@0 453
aoqi@0 454 if (useIDLNames) {
aoqi@0 455 name = members[i].getIDLName();
aoqi@0 456 } else {
aoqi@0 457 name = members[i].getName();
aoqi@0 458 }
aoqi@0 459
aoqi@0 460 String value = members[i].getValue();
aoqi@0 461
aoqi@0 462 writer.p(visibility);
aoqi@0 463 if (visibility.length() > 0) {
aoqi@0 464 writer.p(" ");
aoqi@0 465 }
aoqi@0 466 it.printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
aoqi@0 467 writer.p(" " + name);
aoqi@0 468
aoqi@0 469 if (value != null) {
aoqi@0 470 writer.pln(" = " + value + ";");
aoqi@0 471 } else {
aoqi@0 472 writer.pln(";");
aoqi@0 473 }
aoqi@0 474 }
aoqi@0 475 }
aoqi@0 476 }
aoqi@0 477
aoqi@0 478 // Print methods
aoqi@0 479
aoqi@0 480 protected void printMethods ( IndentingWriter writer,
aoqi@0 481 boolean useQualifiedNames,
aoqi@0 482 boolean useIDLNames,
aoqi@0 483 boolean globalIDLNames) throws IOException {
aoqi@0 484
aoqi@0 485 CompoundType.Method[] methods = getMethods();
aoqi@0 486
aoqi@0 487 for (int m = 0; m < methods.length; m++) {
aoqi@0 488 CompoundType.Method theMethod = methods[m];
aoqi@0 489 printMethod(theMethod,writer,useQualifiedNames,useIDLNames,globalIDLNames);
aoqi@0 490 }
aoqi@0 491 }
aoqi@0 492
aoqi@0 493 // Print a method...
aoqi@0 494
aoqi@0 495 protected void printMethod (CompoundType.Method it,
aoqi@0 496 IndentingWriter writer,
aoqi@0 497 boolean useQualifiedNames,
aoqi@0 498 boolean useIDLNames,
aoqi@0 499 boolean globalIDLNames) throws IOException {
aoqi@0 500
aoqi@0 501
aoqi@0 502 // Write visibility...
aoqi@0 503
aoqi@0 504 String visibility = it.getVisibility();
aoqi@0 505
aoqi@0 506 writer.p(visibility);
aoqi@0 507 if (visibility.length() > 0) {
aoqi@0 508 writer.p(" ");
aoqi@0 509 }
aoqi@0 510
aoqi@0 511 // Write return type...
aoqi@0 512
aoqi@0 513 it.getReturnType().printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
aoqi@0 514
aoqi@0 515 // Write method name...
aoqi@0 516
aoqi@0 517 if (useIDLNames) {
aoqi@0 518 writer.p(" " + it.getIDLName());
aoqi@0 519 } else {
aoqi@0 520 writer.p(" " + it.getName());
aoqi@0 521 }
aoqi@0 522
aoqi@0 523 // Write arguments...
aoqi@0 524
aoqi@0 525 writer.p(" (");
aoqi@0 526 Type[] args = it.getArguments();
aoqi@0 527 String[] argNames = it.getArgumentNames();
aoqi@0 528
aoqi@0 529 for (int i = 0; i < args.length; i++) {
aoqi@0 530 if (i > 0) {
aoqi@0 531 writer.p(", ");
aoqi@0 532 }
aoqi@0 533
aoqi@0 534 if (useIDLNames) {
aoqi@0 535 writer.p("in ");
aoqi@0 536 }
aoqi@0 537
aoqi@0 538 args[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
aoqi@0 539 writer.p(" " + argNames[i]);
aoqi@0 540 }
aoqi@0 541 writer.p(")");
aoqi@0 542
aoqi@0 543 // Write exceptions...
aoqi@0 544
aoqi@0 545 ClassType[] exceptions;
aoqi@0 546
aoqi@0 547 if (isType(TYPE_IMPLEMENTATION)) {
aoqi@0 548 exceptions = it.getImplExceptions();
aoqi@0 549 } else {
aoqi@0 550 exceptions = it.getExceptions();
aoqi@0 551 }
aoqi@0 552
aoqi@0 553 for (int i = 0; i < exceptions.length; i++) {
aoqi@0 554 if (i == 0) {
aoqi@0 555 if (useIDLNames) {
aoqi@0 556 writer.p(" raises (");
aoqi@0 557 } else {
aoqi@0 558 writer.p(" throws ");
aoqi@0 559 }
aoqi@0 560 } else {
aoqi@0 561 writer.p(", ");
aoqi@0 562 }
aoqi@0 563
aoqi@0 564 if (useIDLNames) {
aoqi@0 565 if (useQualifiedNames) {
aoqi@0 566 writer.p(exceptions[i].getQualifiedIDLExceptionName(globalIDLNames));
aoqi@0 567 } else {
aoqi@0 568 writer.p(exceptions[i].getIDLExceptionName());
aoqi@0 569 }
aoqi@0 570 writer.p(" [a.k.a. ");
aoqi@0 571 exceptions[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
aoqi@0 572 writer.p("]");
aoqi@0 573 } else {
aoqi@0 574 exceptions[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
aoqi@0 575 }
aoqi@0 576 }
aoqi@0 577
aoqi@0 578 if (useIDLNames && exceptions.length > 0) {
aoqi@0 579 writer.p(")");
aoqi@0 580 }
aoqi@0 581
aoqi@0 582 if (it.isInherited()) {
aoqi@0 583 writer.p(" // Inherited from ");
aoqi@0 584 writer.p(it.getDeclaredBy());
aoqi@0 585 }
aoqi@0 586
aoqi@0 587 writer.pln(";");
aoqi@0 588 }
aoqi@0 589
aoqi@0 590 /**
aoqi@0 591 * Create a CompoundType instance for the given class. NOTE: This constructor
aoqi@0 592 * is ONLY for SpecialClassType and SpecialInterfaceType.
aoqi@0 593 */
aoqi@0 594 protected CompoundType(ContextStack stack, int typeCode, ClassDefinition classDef) {
aoqi@0 595 super(stack,typeCode);
aoqi@0 596 this.classDef = classDef;
aoqi@0 597 classDecl = classDef.getClassDeclaration();
aoqi@0 598 interfaces = new InterfaceType[0];
aoqi@0 599 methods = new Method[0];
aoqi@0 600 members = new Member[0];
aoqi@0 601
aoqi@0 602 // If we are an inner class/interface, reset the type codes...
aoqi@0 603
aoqi@0 604 if (classDef.isInnerClass()) {
aoqi@0 605 setTypeCode(typeCode | TM_INNER);
aoqi@0 606 }
aoqi@0 607
aoqi@0 608 // Set special flags...
aoqi@0 609
aoqi@0 610 setFlags();
aoqi@0 611 }
aoqi@0 612
aoqi@0 613 private void setFlags() {
aoqi@0 614
aoqi@0 615 try {
aoqi@0 616
aoqi@0 617 // Set our special interface flags...
aoqi@0 618
aoqi@0 619 isCORBAObject = env.defCorbaObject.implementedBy(env,classDecl);
aoqi@0 620 isIDLEntity = env.defIDLEntity.implementedBy(env,classDecl);
aoqi@0 621 isValueBase = env.defValueBase.implementedBy(env,classDecl);
aoqi@0 622 isAbstractBase = isInterface() && // Interface, not a class.
aoqi@0 623 isIDLEntity && // Implements IDLEntity.
aoqi@0 624 !isValueBase && // Does not implement ValueBase.
aoqi@0 625 !isCORBAObject; // Does not implement org.omg.CORBA.Object;
aoqi@0 626 isCORBAUserException = (classDecl.getName() == idCorbaUserException);
aoqi@0 627
aoqi@0 628 // Is this an exception?
aoqi@0 629
aoqi@0 630 if (env.defThrowable.implementedBy(env, classDecl)) {
aoqi@0 631
aoqi@0 632 // Yes...
aoqi@0 633
aoqi@0 634 isException = true;
aoqi@0 635
aoqi@0 636 // Is it a checked exception?
aoqi@0 637
aoqi@0 638 if (env.defRuntimeException.implementedBy(env,classDecl) ||
aoqi@0 639 env.defError.implementedBy(env,classDecl)) {
aoqi@0 640 isCheckedException = false;
aoqi@0 641 } else {
aoqi@0 642 isCheckedException = true;
aoqi@0 643 }
aoqi@0 644
aoqi@0 645 // Is it java.rmi.RemoteException or a subclass?
aoqi@0 646
aoqi@0 647 if (env.defRemoteException.implementedBy(env,classDecl)) {
aoqi@0 648 isRemoteExceptionOrSubclass = true;
aoqi@0 649 } else {
aoqi@0 650 isRemoteExceptionOrSubclass = false;
aoqi@0 651 }
aoqi@0 652 } else {
aoqi@0 653 isException = false;
aoqi@0 654 }
aoqi@0 655 } catch (ClassNotFound e) {
aoqi@0 656 classNotFound(stack,e);
aoqi@0 657 }
aoqi@0 658 }
aoqi@0 659
aoqi@0 660 /**
aoqi@0 661 * Create a CompoundType instance for the given class. The resulting
aoqi@0 662 * object is not yet completely initialized.
aoqi@0 663 */
aoqi@0 664 protected CompoundType(ContextStack stack, ClassDefinition classDef,
aoqi@0 665 int typeCode) {
aoqi@0 666 super(stack,typeCode);
aoqi@0 667 this.classDef = classDef;
aoqi@0 668 classDecl = classDef.getClassDeclaration();
aoqi@0 669
aoqi@0 670 // If we are an inner class/interface, reset the type codes...
aoqi@0 671
aoqi@0 672 if (classDef.isInnerClass()) {
aoqi@0 673 setTypeCode(typeCode | TM_INNER);
aoqi@0 674 }
aoqi@0 675
aoqi@0 676 // Set special flags...
aoqi@0 677
aoqi@0 678 setFlags();
aoqi@0 679
aoqi@0 680 // Set names...
aoqi@0 681
aoqi@0 682 Identifier id = classDef.getName();
aoqi@0 683 String idlName;
aoqi@0 684 String[] idlModuleNames;
aoqi@0 685
aoqi@0 686 try {
aoqi@0 687
aoqi@0 688 // These can fail if we get case-sensitive name matches...
aoqi@0 689
aoqi@0 690 idlName = IDLNames.getClassOrInterfaceName(id,env);
aoqi@0 691 idlModuleNames = IDLNames.getModuleNames(id,isBoxed(),env);
aoqi@0 692
aoqi@0 693 setNames(id,idlModuleNames,idlName);
aoqi@0 694
aoqi@0 695 // Is this an exception?
aoqi@0 696
aoqi@0 697 if (isException()) {
aoqi@0 698
aoqi@0 699 // Yes, so set our mangled exception names...
aoqi@0 700
aoqi@0 701 isException = true;
aoqi@0 702 idlExceptionName = IDLNames.getExceptionName(getIDLName());
aoqi@0 703 qualifiedIDLExceptionName =
aoqi@0 704 IDLNames.getQualifiedName(getIDLModuleNames(),idlExceptionName);
aoqi@0 705 }
aoqi@0 706
aoqi@0 707 // Set interfaces, methods and members...
aoqi@0 708
aoqi@0 709 interfaces = null; // set in initialize()
aoqi@0 710 methods = null; // set in initialize()
aoqi@0 711 members = null; // set in initialize()
aoqi@0 712
aoqi@0 713 } catch (Exception e) {
aoqi@0 714 failedConstraint(7,false,stack,id.toString(),e.getMessage());
aoqi@0 715 throw new CompilerError("");
aoqi@0 716 }
aoqi@0 717 }
aoqi@0 718
aoqi@0 719 /**
aoqi@0 720 * Initialize this instance.
aoqi@0 721 */
aoqi@0 722 protected boolean initialize ( Vector directInterfaces,
aoqi@0 723 Vector directMethods,
aoqi@0 724 Vector directMembers,
aoqi@0 725 ContextStack stack,
aoqi@0 726 boolean quiet) {
aoqi@0 727
aoqi@0 728 boolean result = true;
aoqi@0 729
aoqi@0 730 // Initialize our arrays...
aoqi@0 731
aoqi@0 732 if (directInterfaces != null && directInterfaces.size() > 0) {
aoqi@0 733 interfaces = new InterfaceType[directInterfaces.size()];
aoqi@0 734 directInterfaces.copyInto(interfaces);
aoqi@0 735 } else {
aoqi@0 736 interfaces = new InterfaceType[0];
aoqi@0 737 }
aoqi@0 738
aoqi@0 739 if (directMethods != null && directMethods.size() > 0) {
aoqi@0 740 methods = new Method[directMethods.size()];
aoqi@0 741 directMethods.copyInto(methods);
aoqi@0 742
aoqi@0 743 // Now set the idl names for each...
aoqi@0 744
aoqi@0 745 try {
aoqi@0 746 IDLNames.setMethodNames(this, methods,env);
aoqi@0 747 } catch (Exception e) {
aoqi@0 748 failedConstraint(13,quiet,stack,getQualifiedName(),e.getMessage());
aoqi@0 749 result = false;
aoqi@0 750 }
aoqi@0 751
aoqi@0 752 } else {
aoqi@0 753 methods = new Method[0];
aoqi@0 754 }
aoqi@0 755
aoqi@0 756 if (directMembers != null && directMembers.size() > 0) {
aoqi@0 757 members = new Member[directMembers.size()];
aoqi@0 758 directMembers.copyInto(members);
aoqi@0 759
aoqi@0 760 // If we have any un-initialized inner classes, now is the time
aoqi@0 761 // to init them...
aoqi@0 762
aoqi@0 763 for (int i = 0; i < members.length; i++) {
aoqi@0 764 if (members[i].isInnerClassDeclaration()) {
aoqi@0 765 try {
aoqi@0 766 members[i].init(stack,this);
aoqi@0 767 } catch (CompilerError e) {
aoqi@0 768 return false;
aoqi@0 769 }
aoqi@0 770 }
aoqi@0 771 }
aoqi@0 772
aoqi@0 773 // Now set the idl names for each...
aoqi@0 774
aoqi@0 775 try {
aoqi@0 776 IDLNames.setMemberNames(this, members,methods,env);
aoqi@0 777 } catch (Exception e) {
aoqi@0 778 int constraint = classDef.isInterface() ? 19 : 20;
aoqi@0 779 failedConstraint(constraint,quiet,stack,getQualifiedName(),e.getMessage());
aoqi@0 780 result = false;
aoqi@0 781 }
aoqi@0 782
aoqi@0 783 } else {
aoqi@0 784 members = new Member[0];
aoqi@0 785 }
aoqi@0 786
aoqi@0 787 // Set our repositoryID...
aoqi@0 788
aoqi@0 789 if (result) {
aoqi@0 790 result = setRepositoryID();
aoqi@0 791 }
aoqi@0 792
aoqi@0 793 return result;
aoqi@0 794 }
aoqi@0 795
aoqi@0 796 /*
aoqi@0 797 * Return Type or null if error. classDef may be null.
aoqi@0 798 */
aoqi@0 799 protected static Type makeType (sun.tools.java.Type theType,
aoqi@0 800 ClassDefinition classDef,
aoqi@0 801 ContextStack stack) {
aoqi@0 802
aoqi@0 803 if (stack.anyErrors()) return null;
aoqi@0 804
aoqi@0 805 // See if we can find this type in the cache. If so, return it...
aoqi@0 806
aoqi@0 807 String key = theType.toString();
aoqi@0 808
aoqi@0 809 Type result = getType(key,stack);
aoqi@0 810
aoqi@0 811 if (result != null) {
aoqi@0 812 return result;
aoqi@0 813 }
aoqi@0 814
aoqi@0 815 // Gotta try with context...
aoqi@0 816
aoqi@0 817 result = getType(key + stack.getContextCodeString(),stack);
aoqi@0 818
aoqi@0 819 if (result != null) {
aoqi@0 820 return result;
aoqi@0 821 }
aoqi@0 822
aoqi@0 823 // Gotta map it...
aoqi@0 824
aoqi@0 825 BatchEnvironment env = stack.getEnv();
aoqi@0 826 int typeCode = theType.getTypeCode();
aoqi@0 827 switch (typeCode) {
aoqi@0 828 case TC_BOOLEAN:
aoqi@0 829 case TC_BYTE:
aoqi@0 830 case TC_CHAR:
aoqi@0 831 case TC_SHORT:
aoqi@0 832 case TC_INT:
aoqi@0 833 case TC_LONG:
aoqi@0 834 case TC_FLOAT:
aoqi@0 835 case TC_DOUBLE:
aoqi@0 836 {
aoqi@0 837 // Primitive...
aoqi@0 838
aoqi@0 839 result = PrimitiveType.forPrimitive(theType,stack);
aoqi@0 840 break;
aoqi@0 841 }
aoqi@0 842
aoqi@0 843 case TC_ARRAY:
aoqi@0 844 {
aoqi@0 845 // Array.
aoqi@0 846
aoqi@0 847 result = ArrayType.forArray(theType,stack);
aoqi@0 848 break;
aoqi@0 849 }
aoqi@0 850
aoqi@0 851 case TC_CLASS:
aoqi@0 852 {
aoqi@0 853 try {
aoqi@0 854 // First, make sure we have the class definition...
aoqi@0 855
aoqi@0 856 ClassDefinition theClass = classDef;
aoqi@0 857
aoqi@0 858 if (theClass == null) {
aoqi@0 859 theClass = env.getClassDeclaration(theType).getClassDefinition(env);
aoqi@0 860 }
aoqi@0 861
aoqi@0 862 // Is it an interface or a class?
aoqi@0 863
aoqi@0 864 if (theClass.isInterface()) {
aoqi@0 865
aoqi@0 866 // An interface. Is it a special case?
aoqi@0 867
aoqi@0 868 result = SpecialInterfaceType.forSpecial(theClass,stack);
aoqi@0 869
aoqi@0 870 if (result == null) {
aoqi@0 871
aoqi@0 872 // No, does it implement java.rmi.Remote?
aoqi@0 873
aoqi@0 874 if (env.defRemote.implementedBy(env,theClass.getClassDeclaration())) {
aoqi@0 875
aoqi@0 876 // Yep, so just see if we can create an instance of RemoteType
aoqi@0 877 // from it...
aoqi@0 878
aoqi@0 879 boolean parentIsValue = stack.isParentAValue();
aoqi@0 880 result = RemoteType.forRemote(theClass,stack,parentIsValue);
aoqi@0 881
aoqi@0 882 // If we did not succeed AND we are in a value context, then
aoqi@0 883 // go ahead and make an NC type out of it...
aoqi@0 884
aoqi@0 885 if (result == null && parentIsValue) {
aoqi@0 886 result = NCInterfaceType.forNCInterface(theClass,stack);
aoqi@0 887 }
aoqi@0 888 } else {
aoqi@0 889
aoqi@0 890 // Nope, is it an AbstractType?
aoqi@0 891
aoqi@0 892 result = AbstractType.forAbstract(theClass,stack,true);
aoqi@0 893
aoqi@0 894 if (result == null) {
aoqi@0 895
aoqi@0 896 // No, so treat it as a non-conforming interface type...
aoqi@0 897
aoqi@0 898 result = NCInterfaceType.forNCInterface(theClass,stack);
aoqi@0 899 }
aoqi@0 900 }
aoqi@0 901 }
aoqi@0 902 } else {
aoqi@0 903
aoqi@0 904 // A class. Is it a special case?
aoqi@0 905
aoqi@0 906 result = SpecialClassType.forSpecial(theClass,stack);
aoqi@0 907
aoqi@0 908 if (result == null) {
aoqi@0 909
aoqi@0 910 ClassDeclaration classDecl = theClass.getClassDeclaration();
aoqi@0 911
aoqi@0 912 // Nope, does it implement java.rmi.Remote?
aoqi@0 913
aoqi@0 914 if (env.defRemote.implementedBy(env,classDecl)) {
aoqi@0 915
aoqi@0 916 // Yep, so just see if we can create an instance of
aoqi@0 917 // ImplementationType from it...
aoqi@0 918
aoqi@0 919 boolean parentIsValue = stack.isParentAValue();
aoqi@0 920 result = ImplementationType.forImplementation(theClass,stack,parentIsValue);
aoqi@0 921
aoqi@0 922 // If we did not succeed AND inValue is true, then
aoqi@0 923 // go ahead and make an NC type out of it...
aoqi@0 924
aoqi@0 925 if (result == null && parentIsValue) {
aoqi@0 926 result = NCClassType.forNCClass(theClass,stack);
aoqi@0 927 }
aoqi@0 928 } else {
aoqi@0 929
aoqi@0 930 // No, does it implement Serializable?
aoqi@0 931
aoqi@0 932 if (env.defSerializable.implementedBy(env,classDecl)) {
aoqi@0 933
aoqi@0 934 // Yep, so just see if we can create an instance of ValueType
aoqi@0 935 // from it...
aoqi@0 936
aoqi@0 937 result = ValueType.forValue(theClass,stack,true);
aoqi@0 938 }
aoqi@0 939
aoqi@0 940 if (result == null) {
aoqi@0 941
aoqi@0 942 // Treat it as a non-conforming class type...
aoqi@0 943
aoqi@0 944 result = NCClassType.forNCClass(theClass,stack);
aoqi@0 945 }
aoqi@0 946 }
aoqi@0 947 }
aoqi@0 948 }
aoqi@0 949 } catch (ClassNotFound e) {
aoqi@0 950 classNotFound(stack,e);
aoqi@0 951 }
aoqi@0 952 break;
aoqi@0 953 }
aoqi@0 954
aoqi@0 955 default: throw new CompilerError("Unknown typecode (" + typeCode + ") for " + theType.getTypeSignature());
aoqi@0 956 }
aoqi@0 957
aoqi@0 958 return result;
aoqi@0 959 }
aoqi@0 960
aoqi@0 961 /*
aoqi@0 962 * Check if exception is RemoteException or one of its parents.
aoqi@0 963 */
aoqi@0 964 public static boolean isRemoteException (ClassType ex,
aoqi@0 965 BatchEnvironment env) {
aoqi@0 966 sun.tools.java.Type exceptionType = ex.getClassDeclaration().getType();
aoqi@0 967
aoqi@0 968 if (exceptionType.equals(env.typeRemoteException) ||
aoqi@0 969 exceptionType.equals(env.typeIOException) ||
aoqi@0 970 exceptionType.equals(env.typeException) ||
aoqi@0 971 exceptionType.equals(env.typeThrowable)) {
aoqi@0 972
aoqi@0 973 return true;
aoqi@0 974 }
aoqi@0 975 return false;
aoqi@0 976 }
aoqi@0 977
aoqi@0 978 /*
aoqi@0 979 * Check if method is conforming.
aoqi@0 980 */
aoqi@0 981 protected boolean isConformingRemoteMethod (Method method, boolean quiet)
aoqi@0 982 throws ClassNotFound {
aoqi@0 983
aoqi@0 984 // Do we have one exception that is RemoteException or
aoqi@0 985 // a superclass of RemoteException?
aoqi@0 986
aoqi@0 987 boolean haveRemote = false;
aoqi@0 988 ClassType[] exceptions = method.getExceptions();
aoqi@0 989
aoqi@0 990 for (int i = 0; i < exceptions.length; i++) {
aoqi@0 991
aoqi@0 992 // Is it a conforming exception?
aoqi@0 993
aoqi@0 994 if (isRemoteException(exceptions[i],env)) {
aoqi@0 995
aoqi@0 996 // Got it.
aoqi@0 997
aoqi@0 998 haveRemote = true;
aoqi@0 999 break;
aoqi@0 1000 }
aoqi@0 1001 }
aoqi@0 1002
aoqi@0 1003 // Do we have our exception?
aoqi@0 1004
aoqi@0 1005 if (!haveRemote) {
aoqi@0 1006
aoqi@0 1007 // No, so report failure...
aoqi@0 1008
aoqi@0 1009 failedConstraint(5,quiet,stack,method.getEnclosing(), method.toString());
aoqi@0 1010 }
aoqi@0 1011
aoqi@0 1012 // Are any of the arguments exceptions which implement IDLEntity?
aoqi@0 1013 // If so, report failure...
aoqi@0 1014
aoqi@0 1015 boolean noIDLEntity = !isIDLEntityException(method.getReturnType(),method,quiet);
aoqi@0 1016 if (noIDLEntity) {
aoqi@0 1017 Type[] args = method.getArguments();
aoqi@0 1018 for (int i = 0; i < args.length; i++) {
aoqi@0 1019 if (isIDLEntityException(args[i],method,quiet)) {
aoqi@0 1020 noIDLEntity = false;
aoqi@0 1021 break;
aoqi@0 1022 }
aoqi@0 1023 }
aoqi@0 1024 }
aoqi@0 1025
aoqi@0 1026 return (haveRemote && noIDLEntity);
aoqi@0 1027 }
aoqi@0 1028
aoqi@0 1029 protected boolean isIDLEntityException(Type type, CompoundType.Method method,boolean quiet)
aoqi@0 1030 throws ClassNotFound {
aoqi@0 1031 if (type.isArray()) {
aoqi@0 1032 type = type.getElementType();
aoqi@0 1033 }
aoqi@0 1034 if (type.isCompound()){
aoqi@0 1035 if (((CompoundType)type).isIDLEntityException()) {
aoqi@0 1036 failedConstraint(18,quiet,stack,method.getEnclosing(), method.toString());
aoqi@0 1037 return true;
aoqi@0 1038 }
aoqi@0 1039 }
aoqi@0 1040 return false;
aoqi@0 1041 }
aoqi@0 1042
aoqi@0 1043 /**
aoqi@0 1044 * Convert all invalid types to valid ones.
aoqi@0 1045 */
aoqi@0 1046 protected void swapInvalidTypes () {
aoqi@0 1047
aoqi@0 1048 // Walk all interfaces and check them...
aoqi@0 1049
aoqi@0 1050 for (int i = 0; i < interfaces.length; i++) {
aoqi@0 1051 if (interfaces[i].getStatus() != STATUS_VALID) {
aoqi@0 1052 interfaces[i] = (InterfaceType)getValidType(interfaces[i]);
aoqi@0 1053 }
aoqi@0 1054 }
aoqi@0 1055
aoqi@0 1056 // Update methods...
aoqi@0 1057
aoqi@0 1058 for (int i = 0; i < methods.length; i++) {
aoqi@0 1059 methods[i].swapInvalidTypes();
aoqi@0 1060 }
aoqi@0 1061
aoqi@0 1062 // Update members...
aoqi@0 1063
aoqi@0 1064 for (int i = 0; i < members.length; i++) {
aoqi@0 1065 members[i].swapInvalidTypes();
aoqi@0 1066 }
aoqi@0 1067 }
aoqi@0 1068
aoqi@0 1069 /*
aoqi@0 1070 * Add matching types to list. Return true if this type has not
aoqi@0 1071 * been previously checked, false otherwise.
aoqi@0 1072 */
aoqi@0 1073 protected boolean addTypes (int typeCodeFilter,
aoqi@0 1074 HashSet checked,
aoqi@0 1075 Vector matching) {
aoqi@0 1076
aoqi@0 1077 // Check self.
aoqi@0 1078
aoqi@0 1079 boolean result = super.addTypes(typeCodeFilter,checked,matching);
aoqi@0 1080
aoqi@0 1081 // Have we been checked before?
aoqi@0 1082
aoqi@0 1083 if (result) {
aoqi@0 1084
aoqi@0 1085 // Nope, so walk parent(s) and check them...
aoqi@0 1086
aoqi@0 1087 ClassType parent = getSuperclass();
aoqi@0 1088
aoqi@0 1089 if (parent != null) {
aoqi@0 1090 parent.addTypes(typeCodeFilter,checked,matching);
aoqi@0 1091 }
aoqi@0 1092
aoqi@0 1093 // Walk all interfaces and check them...
aoqi@0 1094
aoqi@0 1095 //if (interfaces == null) System.out.println("NULL for " +getQualifiedName() + " interfaces");
aoqi@0 1096 for (int i = 0; i < interfaces.length; i++) {
aoqi@0 1097
aoqi@0 1098 // Now recurse and add it and any referenced types...
aoqi@0 1099
aoqi@0 1100 //if (interfaces[i] == null) System.out.println("NULL for " +getQualifiedName() + " interfaces[" + i + "]");
aoqi@0 1101 interfaces[i].addTypes(typeCodeFilter,checked,matching);
aoqi@0 1102 }
aoqi@0 1103
aoqi@0 1104 // Walk all methods and check arguments...
aoqi@0 1105
aoqi@0 1106 //if (methods == null) System.out.println("NULL for " +getQualifiedName() + " methods");
aoqi@0 1107 for (int i = 0; i < methods.length; i++) {
aoqi@0 1108
aoqi@0 1109 // Add return type...
aoqi@0 1110 //if (methods[i] == null) System.out.println("NULL for " +getQualifiedName() + " methods[" + i + "]");
aoqi@0 1111 //if (methods[i].getReturnType() == null) System.out.println("NULL for " +getQualifiedName() + methods[i]);
aoqi@0 1112 methods[i].getReturnType().addTypes(typeCodeFilter,checked,matching);
aoqi@0 1113
aoqi@0 1114 // Add args...
aoqi@0 1115
aoqi@0 1116 Type[] args = methods[i].getArguments();
aoqi@0 1117 //if (args == null) System.out.println("NULL for " + getQualifiedName() + " args");
aoqi@0 1118
aoqi@0 1119 for (int j = 0; j < args.length; j++) {
aoqi@0 1120
aoqi@0 1121 Type arg = args[j];
aoqi@0 1122 //if (arg == null) System.out.println("NULL for " + getQualifiedName() + " arg[" +j+"]");
aoqi@0 1123
aoqi@0 1124 // Add argument...
aoqi@0 1125
aoqi@0 1126 arg.addTypes(typeCodeFilter,checked,matching);
aoqi@0 1127 }
aoqi@0 1128
aoqi@0 1129 // Add exceptions...
aoqi@0 1130
aoqi@0 1131 ClassType[] exceptions = methods[i].getExceptions();
aoqi@0 1132 //if (exceptions == null) System.out.println("NULL for " + getQualifiedName() + " exceptions");
aoqi@0 1133
aoqi@0 1134 for (int j = 0; j < exceptions.length; j++) {
aoqi@0 1135
aoqi@0 1136 ClassType ex = exceptions[j];
aoqi@0 1137
aoqi@0 1138 // Add argument...
aoqi@0 1139
aoqi@0 1140 ex.addTypes(typeCodeFilter,checked,matching);
aoqi@0 1141 }
aoqi@0 1142 }
aoqi@0 1143
aoqi@0 1144 // Walk all members and add em...
aoqi@0 1145
aoqi@0 1146 //if (members == null) System.out.println("NULL for " +getQualifiedName() + " members");
aoqi@0 1147 for (int i = 0; i < members.length; i++) {
aoqi@0 1148 //if (members[i] == null) System.out.println("NULL for " +getQualifiedName() + " members[" + i + "]");
aoqi@0 1149 Type cType = members[i].getType();
aoqi@0 1150 //if (cType == null) System.out.println("NULL for " + getQualifiedName() + " cType");
aoqi@0 1151
aoqi@0 1152 // Add it...
aoqi@0 1153
aoqi@0 1154 cType.addTypes(typeCodeFilter,checked,matching);
aoqi@0 1155 }
aoqi@0 1156 }
aoqi@0 1157
aoqi@0 1158 return result;
aoqi@0 1159 }
aoqi@0 1160
aoqi@0 1161 /*
aoqi@0 1162 * Return true if theType is a conforming constant type.
aoqi@0 1163 */
aoqi@0 1164 private boolean isConformingConstantType (MemberDefinition member) {
aoqi@0 1165 return isConformingConstantType(member.getType(),member);
aoqi@0 1166 }
aoqi@0 1167
aoqi@0 1168 /*
aoqi@0 1169 * Return true if theType is a conforming constant type.
aoqi@0 1170 */
aoqi@0 1171 private boolean isConformingConstantType (sun.tools.java.Type theType,MemberDefinition member) {
aoqi@0 1172
aoqi@0 1173 // Constraint 3: Constants must be either primitives or String.
aoqi@0 1174
aoqi@0 1175 boolean result = true;
aoqi@0 1176 int typeCode = theType.getTypeCode();
aoqi@0 1177 switch (typeCode) {
aoqi@0 1178 case TC_BOOLEAN:
aoqi@0 1179 case TC_BYTE:
aoqi@0 1180 case TC_CHAR:
aoqi@0 1181 case TC_SHORT:
aoqi@0 1182 case TC_INT:
aoqi@0 1183 case TC_LONG:
aoqi@0 1184 case TC_FLOAT:
aoqi@0 1185 case TC_DOUBLE: // Primitive, so OK...
aoqi@0 1186 {
aoqi@0 1187 break;
aoqi@0 1188 }
aoqi@0 1189
aoqi@0 1190 case TC_CLASS: // Must be java.lang.String
aoqi@0 1191 {
aoqi@0 1192 if (theType.getClassName() != idJavaLangString) {
aoqi@0 1193 failedConstraint(3,false,stack,member.getClassDefinition(),member.getName());
aoqi@0 1194 result = false;
aoqi@0 1195 }
aoqi@0 1196 break;
aoqi@0 1197 }
aoqi@0 1198
aoqi@0 1199 case TC_ARRAY: // Array constants are not allowed.
aoqi@0 1200 {
aoqi@0 1201 failedConstraint(3,false,stack,member.getClassDefinition(),member.getName());
aoqi@0 1202 result = false;
aoqi@0 1203 break;
aoqi@0 1204 }
aoqi@0 1205
aoqi@0 1206 default:
aoqi@0 1207 throw new Error("unexpected type code: " + typeCode);
aoqi@0 1208 }
aoqi@0 1209
aoqi@0 1210 return result;
aoqi@0 1211 }
aoqi@0 1212
aoqi@0 1213
aoqi@0 1214 /*
aoqi@0 1215 * Update any method from 'currentMethods' which is defined in a
aoqi@0 1216 * parent class so that it's 'declaredBy' field specifies the
aoqi@0 1217 * parent.
aoqi@0 1218 * @param current The class or interface to gather methods from.
aoqi@0 1219 * @param currentMethods The list into which to put the methods.
aoqi@0 1220 * for contraint 6.
aoqi@0 1221 * @param quiet true if silent errors.
aoqi@0 1222 * @param stack the context stack.
aoqi@0 1223 * @return currentMethods or null if failed a constraint check.
aoqi@0 1224 */
aoqi@0 1225 protected Vector updateParentClassMethods(ClassDefinition current,
aoqi@0 1226 Vector currentMethods,
aoqi@0 1227 boolean quiet,
aoqi@0 1228 ContextStack stack)
aoqi@0 1229 throws ClassNotFound {
aoqi@0 1230
aoqi@0 1231 ClassDeclaration parentDecl = current.getSuperClass(env);
aoqi@0 1232
aoqi@0 1233 while (parentDecl != null) {
aoqi@0 1234
aoqi@0 1235 ClassDefinition parentDef = parentDecl.getClassDefinition(env);
aoqi@0 1236 Identifier currentID = parentDecl.getName();
aoqi@0 1237
aoqi@0 1238 if ( currentID == idJavaLangObject ) break;
aoqi@0 1239
aoqi@0 1240 // Walk all members of this class and update any that
aoqi@0 1241 // already exist in currentMethods...
aoqi@0 1242
aoqi@0 1243 for (MemberDefinition member = parentDef.getFirstMember();
aoqi@0 1244 member != null;
aoqi@0 1245 member = member.getNextMember()) {
aoqi@0 1246
aoqi@0 1247 if (member.isMethod() &&
aoqi@0 1248 !member.isInitializer() &&
aoqi@0 1249 !member.isConstructor() &&
aoqi@0 1250 !member.isPrivate()) {
aoqi@0 1251
aoqi@0 1252 // It's a method. Is it valid?
aoqi@0 1253
aoqi@0 1254 Method method;
aoqi@0 1255 try {
aoqi@0 1256 method = new Method((CompoundType)this,member,quiet,stack);
aoqi@0 1257 } catch (Exception e) {
aoqi@0 1258 // Don't report anything here, it's already been reported...
aoqi@0 1259 return null;
aoqi@0 1260 }
aoqi@0 1261
aoqi@0 1262 // Have we already seen it?
aoqi@0 1263
aoqi@0 1264 int index = currentMethods.indexOf(method);
aoqi@0 1265 if (index >= 0) {
aoqi@0 1266
aoqi@0 1267 // Yes, so update it...
aoqi@0 1268
aoqi@0 1269 Method currentMethod = (Method)currentMethods.elementAt(index);
aoqi@0 1270 currentMethod.setDeclaredBy(currentID);
aoqi@0 1271 }
aoqi@0 1272 else currentMethods.addElement(method);
aoqi@0 1273 }
aoqi@0 1274 }
aoqi@0 1275
aoqi@0 1276 // Update parent and keep walking up the chain...
aoqi@0 1277
aoqi@0 1278 parentDecl = parentDef.getSuperClass(env);
aoqi@0 1279 }
aoqi@0 1280
aoqi@0 1281 return currentMethods;
aoqi@0 1282 }
aoqi@0 1283
aoqi@0 1284 /*
aoqi@0 1285 * Add all of the public and protected methods defined in
aoqi@0 1286 * current (other than initializers) to allMethods. If a sub-interface
aoqi@0 1287 * re-declares an inherited method, it will not be added.
aoqi@0 1288 * @param current The class or interface to gather methods from.
aoqi@0 1289 * @param directMethods The list into which to put the methods.
aoqi@0 1290 * @param noMultiInheritedMethods A flag to enable/disable checking
aoqi@0 1291 * for contraint 6.
aoqi@0 1292 * @param quiet true if silent errors.
aoqi@0 1293 * @param stack the context stack.
aoqi@0 1294 * @return directMethods or null if failed a constraint check.
aoqi@0 1295 */
aoqi@0 1296 protected Vector addAllMethods (ClassDefinition current, Vector directMethods,
aoqi@0 1297 boolean noMultiInheritedMethods,
aoqi@0 1298 boolean quiet,
aoqi@0 1299 ContextStack stack)
aoqi@0 1300 throws ClassNotFound {
aoqi@0 1301
aoqi@0 1302 // Constraint 6: Multiple inherited interfaces may not
aoqi@0 1303 // declare the same method.
aoqi@0 1304
aoqi@0 1305 ClassDeclaration[] interfaces = current.getInterfaces();
aoqi@0 1306
aoqi@0 1307 // We want to add members starting at the _least_ derived
aoqi@0 1308 // interfaces. To do so, recurse until we have no more
aoqi@0 1309 // interfaces...
aoqi@0 1310
aoqi@0 1311 for (int i = 0; i < interfaces.length; i++) {
aoqi@0 1312
aoqi@0 1313 Vector result = addAllMethods(interfaces[i].getClassDefinition(env),
aoqi@0 1314 directMethods,
aoqi@0 1315 noMultiInheritedMethods,quiet,stack);
aoqi@0 1316 if (result == null) {
aoqi@0 1317 return null;
aoqi@0 1318 }
aoqi@0 1319 }
aoqi@0 1320
aoqi@0 1321 // Walk all members of this interface, adding any unique methods
aoqi@0 1322 // other than initializers and private methods...
aoqi@0 1323
aoqi@0 1324 for (MemberDefinition member = current.getFirstMember();
aoqi@0 1325 member != null;
aoqi@0 1326 member = member.getNextMember())
aoqi@0 1327 {
aoqi@0 1328 if (member.isMethod() &&
aoqi@0 1329 !member.isInitializer() &&
aoqi@0 1330 !member.isPrivate()) {
aoqi@0 1331
aoqi@0 1332 // It's a method. Is it valid?
aoqi@0 1333
aoqi@0 1334 Method method;
aoqi@0 1335 try {
aoqi@0 1336 method = new Method((CompoundType)this,member,quiet,stack);
aoqi@0 1337 } catch (Exception e) {
aoqi@0 1338 // Don't report anything here, it's already been reported...
aoqi@0 1339 return null;
aoqi@0 1340 }
aoqi@0 1341
aoqi@0 1342 // Have we already seen it?
aoqi@0 1343
aoqi@0 1344 if (!directMethods.contains(method)) {
aoqi@0 1345
aoqi@0 1346 // Nope, so add it...
aoqi@0 1347
aoqi@0 1348 directMethods.addElement(method);
aoqi@0 1349
aoqi@0 1350 } else {
aoqi@0 1351
aoqi@0 1352 // Yes. This is an error unless we are looking at the
aoqi@0 1353 // target interface (or this is a ValueType). Are we?
aoqi@0 1354
aoqi@0 1355 if (noMultiInheritedMethods && current != classDef &&
aoqi@0 1356 !stack.isParentAValue() && !stack.getContext().isValue()) {
aoqi@0 1357
aoqi@0 1358 // Nope. Say so and signal error by returning null..
aoqi@0 1359
aoqi@0 1360 Method existingMethod = (Method) directMethods.elementAt(directMethods.indexOf(method));
aoqi@0 1361 ClassDefinition existingMemberClassDef = existingMethod.getMemberDefinition().getClassDefinition();
aoqi@0 1362
aoqi@0 1363 // There are more legal cases to consider here.
aoqi@0 1364 // If the two methods belong to interfaces that inherit from each other
aoqi@0 1365 // then it is just a redefinition which is legal.
aoqi@0 1366 if ( current != existingMemberClassDef &&
aoqi@0 1367 ! inheritsFrom(current, existingMemberClassDef) &&
aoqi@0 1368 ! inheritsFrom(existingMemberClassDef, current))
aoqi@0 1369 {
aoqi@0 1370 //Identifier int1 = existingMethod.getEnclosing().getIdentifier();
aoqi@0 1371 //Identifier int2 = current.getName();
aoqi@0 1372 //String message = int1.toString() + " and " + int2.toString();
aoqi@0 1373 String message = existingMemberClassDef.getName() + " and " + current.getName();
aoqi@0 1374 failedConstraint(6,quiet,stack,classDef,message,method);
aoqi@0 1375 return null;
aoqi@0 1376 }
aoqi@0 1377 }
aoqi@0 1378
aoqi@0 1379 // Bug fix 5014329
aoqi@0 1380
aoqi@0 1381 // find a matching method.
aoqi@0 1382 int index = directMethods.indexOf(method);
aoqi@0 1383 Method other = (Method) directMethods.get(index);
aoqi@0 1384
aoqi@0 1385 // merge the two methods, such that the new method
aoqi@0 1386 // will contain only those exception that can be thrown
aoqi@0 1387 // by both these methods, not just one of them.
aoqi@0 1388 Method newMethod = method.mergeWith(other);
aoqi@0 1389
aoqi@0 1390 // replace the old method with the new.
aoqi@0 1391 directMethods.set(index, newMethod);
aoqi@0 1392 }
aoqi@0 1393 }
aoqi@0 1394 }
aoqi@0 1395
aoqi@0 1396 return directMethods;
aoqi@0 1397 }
aoqi@0 1398
aoqi@0 1399 // This should really be a method on ClassDefinition, but it takes too long to change the shared source.
aoqi@0 1400 // Works for both, classes and interfaces.
aoqi@0 1401 protected boolean inheritsFrom(ClassDefinition def, ClassDefinition otherDef) {
aoqi@0 1402 if (def == otherDef)
aoqi@0 1403 return true;
aoqi@0 1404
aoqi@0 1405 ClassDefinition superDef;
aoqi@0 1406 if (def.getSuperClass() != null) {
aoqi@0 1407 superDef = def.getSuperClass().getClassDefinition();
aoqi@0 1408 if (inheritsFrom(superDef, otherDef))
aoqi@0 1409 return true;
aoqi@0 1410 }
aoqi@0 1411
aoqi@0 1412 ClassDeclaration[] interfaces = def.getInterfaces();
aoqi@0 1413 for (int i=0; i<interfaces.length; i++) {
aoqi@0 1414 superDef = interfaces[i].getClassDefinition();
aoqi@0 1415 if (inheritsFrom(superDef, otherDef))
aoqi@0 1416 return true;
aoqi@0 1417 }
aoqi@0 1418 return false;
aoqi@0 1419 }
aoqi@0 1420
aoqi@0 1421 /*
aoqi@0 1422 * Add all of the interfaces implemented directly by current
aoqi@0 1423 * to the list. Returns null if any are non-conforming.
aoqi@0 1424 */
aoqi@0 1425 protected Vector addRemoteInterfaces (Vector list,
aoqi@0 1426 boolean allowNonConforming,
aoqi@0 1427 ContextStack stack) throws ClassNotFound {
aoqi@0 1428
aoqi@0 1429 // Add all the interfaces of current...
aoqi@0 1430
aoqi@0 1431 ClassDefinition theInterface = getClassDefinition();
aoqi@0 1432 ClassDeclaration[] interfaces = theInterface.getInterfaces();
aoqi@0 1433
aoqi@0 1434 stack.setNewContextCode(ContextStack.IMPLEMENTS);
aoqi@0 1435
aoqi@0 1436 for (int i = 0; i < interfaces.length; i++) {
aoqi@0 1437
aoqi@0 1438 ClassDefinition def = interfaces[i].getClassDefinition(env);
aoqi@0 1439
aoqi@0 1440 // Is it a SpecialInterfaceType...
aoqi@0 1441
aoqi@0 1442 InterfaceType it = SpecialInterfaceType.forSpecial(def,stack);;
aoqi@0 1443
aoqi@0 1444 if (it == null) {
aoqi@0 1445
aoqi@0 1446 // No, is it Remote?
aoqi@0 1447
aoqi@0 1448 if (env.defRemote.implementedBy(env, interfaces[i])) {
aoqi@0 1449
aoqi@0 1450 // Yes, so it must be a RemoteType.
aoqi@0 1451
aoqi@0 1452 it = RemoteType.forRemote(def,stack,false);
aoqi@0 1453
aoqi@0 1454 } else {
aoqi@0 1455
aoqi@0 1456 // Then try Abstract...
aoqi@0 1457
aoqi@0 1458 it = AbstractType.forAbstract(def,stack,true);
aoqi@0 1459
aoqi@0 1460 if (it == null && allowNonConforming) {
aoqi@0 1461
aoqi@0 1462 // Must be non-conforming...
aoqi@0 1463
aoqi@0 1464 it = NCInterfaceType.forNCInterface(def,stack);
aoqi@0 1465 }
aoqi@0 1466 }
aoqi@0 1467 }
aoqi@0 1468
aoqi@0 1469 if (it != null) {
aoqi@0 1470 list.addElement(it);
aoqi@0 1471 } else {
aoqi@0 1472 return null;
aoqi@0 1473 }
aoqi@0 1474 }
aoqi@0 1475
aoqi@0 1476 return list;
aoqi@0 1477 }
aoqi@0 1478
aoqi@0 1479 /*
aoqi@0 1480 * Add all of the interfaces implemented directly by current
aoqi@0 1481 * to the list.
aoqi@0 1482 */
aoqi@0 1483 protected Vector addNonRemoteInterfaces (Vector list,
aoqi@0 1484 ContextStack stack) throws ClassNotFound {
aoqi@0 1485
aoqi@0 1486 // Add all the interfaces of current...
aoqi@0 1487
aoqi@0 1488 ClassDefinition theInterface = getClassDefinition();
aoqi@0 1489 ClassDeclaration[] interfaces = theInterface.getInterfaces();
aoqi@0 1490
aoqi@0 1491 stack.setNewContextCode(ContextStack.IMPLEMENTS);
aoqi@0 1492
aoqi@0 1493 for (int i = 0; i < interfaces.length; i++) {
aoqi@0 1494
aoqi@0 1495 ClassDefinition def = interfaces[i].getClassDefinition(env);
aoqi@0 1496
aoqi@0 1497 // First try SpecialInterfaceType...
aoqi@0 1498
aoqi@0 1499 InterfaceType it = SpecialInterfaceType.forSpecial(def,stack);
aoqi@0 1500
aoqi@0 1501 if (it == null) {
aoqi@0 1502
aoqi@0 1503 // Then try AbstractType...
aoqi@0 1504
aoqi@0 1505 it = AbstractType.forAbstract(def,stack,true);
aoqi@0 1506
aoqi@0 1507 if (it == null) {
aoqi@0 1508
aoqi@0 1509 // Then try NCInterfaceType...
aoqi@0 1510
aoqi@0 1511 it = NCInterfaceType.forNCInterface(def,stack);
aoqi@0 1512 }
aoqi@0 1513 }
aoqi@0 1514
aoqi@0 1515 if (it != null) {
aoqi@0 1516 list.addElement(it);
aoqi@0 1517 } else {
aoqi@0 1518 return null;
aoqi@0 1519 }
aoqi@0 1520 }
aoqi@0 1521
aoqi@0 1522 return list;
aoqi@0 1523 }
aoqi@0 1524
aoqi@0 1525
aoqi@0 1526 /*
aoqi@0 1527 * Walk self, adding constants and data members.
aoqi@0 1528 * @return true if all conform, false otherwise.
aoqi@0 1529 */
aoqi@0 1530 protected boolean addAllMembers (Vector allMembers,
aoqi@0 1531 boolean onlyConformingConstants, // AND inner classes.
aoqi@0 1532 boolean quiet,
aoqi@0 1533 ContextStack stack) {
aoqi@0 1534
aoqi@0 1535 boolean result = true;
aoqi@0 1536
aoqi@0 1537 // Walk all members of this interface...
aoqi@0 1538
aoqi@0 1539 for (MemberDefinition member = getClassDefinition().getFirstMember();
aoqi@0 1540 member != null && result;
aoqi@0 1541 member = member.getNextMember())
aoqi@0 1542 {
aoqi@0 1543 if (!member.isMethod()) {
aoqi@0 1544
aoqi@0 1545 try {
aoqi@0 1546 String value = null;
aoqi@0 1547
aoqi@0 1548 // Prod it to setValue if it is a constant...
aoqi@0 1549
aoqi@0 1550 member.getValue(env);
aoqi@0 1551
aoqi@0 1552 // Get the value, if any...
aoqi@0 1553
aoqi@0 1554 Node node = member.getValue();
aoqi@0 1555
aoqi@0 1556 if (node != null) {
aoqi@0 1557 // We don't want to change the code in CharExpression,
aoqi@0 1558 // which is shared among tools, to return the right string
aoqi@0 1559 // in case the type is char, so we treat it special here.
aoqi@0 1560 if (member.getType().getTypeCode() == TC_CHAR) {
aoqi@0 1561 Integer intValue = (Integer)((IntegerExpression)node).getValue();
aoqi@0 1562 value = "L'" + String.valueOf((char)intValue.intValue()) + "'";
aoqi@0 1563 } else {
aoqi@0 1564 value = node.toString();
aoqi@0 1565 }
aoqi@0 1566 }
aoqi@0 1567
aoqi@0 1568 // Are we supposed to allow only conforming constants?
aoqi@0 1569
aoqi@0 1570 if (onlyConformingConstants && member.getInnerClass() == null) {
aoqi@0 1571
aoqi@0 1572 // Yep, so check it...
aoqi@0 1573
aoqi@0 1574 if (value == null || !isConformingConstantType(member)) {
aoqi@0 1575 failedConstraint(3,quiet,stack,member.getClassDefinition(),member.getName());
aoqi@0 1576 result = false;
aoqi@0 1577 break;
aoqi@0 1578 }
aoqi@0 1579 }
aoqi@0 1580
aoqi@0 1581 // Make member and add to list...
aoqi@0 1582
aoqi@0 1583 try {
aoqi@0 1584 Member newMember = new Member(member,value,stack,this);
aoqi@0 1585 allMembers.addElement(newMember);
aoqi@0 1586 } catch (CompilerError e) {
aoqi@0 1587 result = false;
aoqi@0 1588 }
aoqi@0 1589
aoqi@0 1590 } catch (ClassNotFound e) {
aoqi@0 1591 classNotFound(stack,e);
aoqi@0 1592 result = false;
aoqi@0 1593 }
aoqi@0 1594 }
aoqi@0 1595 }
aoqi@0 1596
aoqi@0 1597 return result;
aoqi@0 1598 }
aoqi@0 1599 /*
aoqi@0 1600 * Walk self, adding constants.
aoqi@0 1601 * @return true if all conform, false otherwise.
aoqi@0 1602 */
aoqi@0 1603 protected boolean addConformingConstants (Vector allMembers,
aoqi@0 1604 boolean quiet,
aoqi@0 1605 ContextStack stack) {
aoqi@0 1606
aoqi@0 1607 boolean result = true;
aoqi@0 1608
aoqi@0 1609 // Walk all members of this interface...
aoqi@0 1610
aoqi@0 1611 for (MemberDefinition member = getClassDefinition().getFirstMember();
aoqi@0 1612 member != null && result;
aoqi@0 1613 member = member.getNextMember())
aoqi@0 1614 {
aoqi@0 1615 if (!member.isMethod()) {
aoqi@0 1616
aoqi@0 1617 try {
aoqi@0 1618 String value = null;
aoqi@0 1619
aoqi@0 1620 // Prod it to setValue if it is a constant...
aoqi@0 1621
aoqi@0 1622 member.getValue(env);
aoqi@0 1623
aoqi@0 1624 // Get the value, if any...
aoqi@0 1625
aoqi@0 1626 Node node = member.getValue();
aoqi@0 1627
aoqi@0 1628 if (node != null) {
aoqi@0 1629 value = node.toString();
aoqi@0 1630 }
aoqi@0 1631
aoqi@0 1632
aoqi@0 1633 // Is it a constant?
aoqi@0 1634
aoqi@0 1635 if (value != null) {
aoqi@0 1636
aoqi@0 1637 // Yes, is it conforming?
aoqi@0 1638
aoqi@0 1639 if (!isConformingConstantType(member)) {
aoqi@0 1640 failedConstraint(3,quiet,stack,member.getClassDefinition(),member.getName());
aoqi@0 1641 result = false;
aoqi@0 1642 break;
aoqi@0 1643 }
aoqi@0 1644
aoqi@0 1645 // Yes, so make a member and add to list...
aoqi@0 1646
aoqi@0 1647 try {
aoqi@0 1648 Member newMember = new Member(member,value,stack,this);
aoqi@0 1649 allMembers.addElement(newMember);
aoqi@0 1650 } catch (CompilerError e) {
aoqi@0 1651 result = false;
aoqi@0 1652 }
aoqi@0 1653 }
aoqi@0 1654 } catch (ClassNotFound e) {
aoqi@0 1655 classNotFound(stack,e);
aoqi@0 1656 result = false;
aoqi@0 1657 }
aoqi@0 1658 }
aoqi@0 1659 }
aoqi@0 1660
aoqi@0 1661 return result;
aoqi@0 1662 }
aoqi@0 1663
aoqi@0 1664 protected ValueType[] getMethodExceptions (MemberDefinition member,
aoqi@0 1665 boolean quiet,
aoqi@0 1666 ContextStack stack) throws Exception {
aoqi@0 1667
aoqi@0 1668 boolean result = true;
aoqi@0 1669 stack.setNewContextCode(ContextStack.METHOD_EXCEPTION);
aoqi@0 1670 ClassDeclaration[] except = member.getExceptions(env);
aoqi@0 1671 ValueType[] exceptions = new ValueType[except.length];
aoqi@0 1672
aoqi@0 1673 try {
aoqi@0 1674 for (int i = 0; i < except.length; i++) {
aoqi@0 1675 ClassDefinition theClass = except[i].getClassDefinition(env);
aoqi@0 1676 try {
aoqi@0 1677 ValueType type = ValueType.forValue(theClass,stack,false);
aoqi@0 1678 if (type != null) {
aoqi@0 1679 exceptions[i] = type;
aoqi@0 1680 } else {
aoqi@0 1681 result = false;
aoqi@0 1682 }
aoqi@0 1683 } catch (ClassCastException e1) {
aoqi@0 1684 failedConstraint(22,quiet,stack,getQualifiedName());
aoqi@0 1685 throw new CompilerError("Method: exception " + theClass.getName() + " not a class type!");
aoqi@0 1686 } catch (NullPointerException e2) {
aoqi@0 1687 failedConstraint(23,quiet,stack,getQualifiedName());
aoqi@0 1688 throw new CompilerError("Method: caught null pointer exception");
aoqi@0 1689 }
aoqi@0 1690 }
aoqi@0 1691 } catch (ClassNotFound e) {
aoqi@0 1692 classNotFound(quiet,stack,e);
aoqi@0 1693 result = false;
aoqi@0 1694 }
aoqi@0 1695
aoqi@0 1696 if (!result) {
aoqi@0 1697 throw new Exception();
aoqi@0 1698 }
aoqi@0 1699
aoqi@0 1700 // Remove any duplicates (javac seems to allow them, but rmic will
aoqi@0 1701 // generate bad ties)...
aoqi@0 1702
aoqi@0 1703 int dupCount = 0;
aoqi@0 1704 for (int i = 0; i < exceptions.length; i++) {
aoqi@0 1705 for (int j = 0; j < exceptions.length; j++) {
aoqi@0 1706 if (i != j && exceptions[i] != null && exceptions[i] == exceptions[j]) {
aoqi@0 1707 exceptions[j] = null;
aoqi@0 1708 dupCount++;
aoqi@0 1709 }
aoqi@0 1710 }
aoqi@0 1711 }
aoqi@0 1712 if (dupCount > 0) {
aoqi@0 1713 int offset = 0;
aoqi@0 1714 ValueType[] temp = new ValueType[exceptions.length - dupCount];
aoqi@0 1715 for (int i = 0; i < exceptions.length; i++) {
aoqi@0 1716 if (exceptions[i] != null) {
aoqi@0 1717 temp[offset++] = exceptions[i];
aoqi@0 1718 }
aoqi@0 1719 }
aoqi@0 1720 exceptions = temp;
aoqi@0 1721 }
aoqi@0 1722
aoqi@0 1723 return exceptions;
aoqi@0 1724 }
aoqi@0 1725
aoqi@0 1726
aoqi@0 1727 protected static String getVisibilityString (MemberDefinition member) {
aoqi@0 1728 String vis = "";
aoqi@0 1729 String prefix = "";
aoqi@0 1730
aoqi@0 1731 if (member.isPublic()) {
aoqi@0 1732 vis += "public";
aoqi@0 1733 prefix = " ";
aoqi@0 1734 } else if (member.isProtected()) {
aoqi@0 1735 vis += "protected";
aoqi@0 1736 prefix = " ";
aoqi@0 1737 } else if (member.isPrivate()) {
aoqi@0 1738 vis += "private";
aoqi@0 1739 prefix = " ";
aoqi@0 1740 }
aoqi@0 1741
aoqi@0 1742 if (member.isStatic()) {
aoqi@0 1743 vis += prefix;
aoqi@0 1744 vis += "static";
aoqi@0 1745 prefix = " ";
aoqi@0 1746 }
aoqi@0 1747
aoqi@0 1748 if (member.isFinal()) {
aoqi@0 1749 vis += prefix;
aoqi@0 1750 vis += "final";
aoqi@0 1751 prefix = " ";
aoqi@0 1752 }
aoqi@0 1753
aoqi@0 1754 return vis;
aoqi@0 1755 }
aoqi@0 1756
aoqi@0 1757 protected boolean assertNotImpl(Type type,
aoqi@0 1758 boolean quiet,
aoqi@0 1759 ContextStack stack,
aoqi@0 1760 CompoundType enclosing,
aoqi@0 1761 boolean dataMember) {
aoqi@0 1762
aoqi@0 1763 if (type.isType(TYPE_IMPLEMENTATION)) {
aoqi@0 1764 int constraint = dataMember ? 28 : 21;
aoqi@0 1765 failedConstraint(constraint,quiet,stack,type,enclosing.getName());
aoqi@0 1766 return false;
aoqi@0 1767 }
aoqi@0 1768 return true;
aoqi@0 1769 }
aoqi@0 1770
aoqi@0 1771 //_____________________________________________________________________
aoqi@0 1772 // Inner Class "Method"
aoqi@0 1773 //_____________________________________________________________________
aoqi@0 1774
aoqi@0 1775 /**
aoqi@0 1776 * A CompoundType.Method object encapsulates IIOP-specific information
aoqi@0 1777 * about a particular method in the interface represented by the outer
aoqi@0 1778 * instance.
aoqi@0 1779 */
aoqi@0 1780 public class Method implements ContextElement, Cloneable {
aoqi@0 1781
aoqi@0 1782 /**
aoqi@0 1783 * Is this method inherited?
aoqi@0 1784 */
aoqi@0 1785 public boolean isInherited () {
aoqi@0 1786 return declaredBy != enclosing.getIdentifier();
aoqi@0 1787 }
aoqi@0 1788
aoqi@0 1789 /**
aoqi@0 1790 * Is this method an attribute?
aoqi@0 1791 * Return true if getAttributeKind != ATTRIBUTE_NONE.
aoqi@0 1792 */
aoqi@0 1793 public boolean isAttribute () {
aoqi@0 1794 return attributeKind != ATTRIBUTE_NONE;
aoqi@0 1795 }
aoqi@0 1796
aoqi@0 1797 /**
aoqi@0 1798 * Is this method a read-write attribute?
aoqi@0 1799 */
aoqi@0 1800 public boolean isReadWriteAttribute () {
aoqi@0 1801 return attributeKind == ATTRIBUTE_IS_RW ||
aoqi@0 1802 attributeKind == ATTRIBUTE_GET_RW;
aoqi@0 1803 }
aoqi@0 1804
aoqi@0 1805 /**
aoqi@0 1806 * Return the attribute kind.
aoqi@0 1807 */
aoqi@0 1808 public int getAttributeKind() {
aoqi@0 1809 return attributeKind;
aoqi@0 1810 }
aoqi@0 1811
aoqi@0 1812 /**
aoqi@0 1813 * Return the attribute name. Will be null if
aoqi@0 1814 * attribute kind == ATTRIBUTE_NONE.
aoqi@0 1815 */
aoqi@0 1816 public String getAttributeName() {
aoqi@0 1817 return attributeName;
aoqi@0 1818 }
aoqi@0 1819
aoqi@0 1820 /**
aoqi@0 1821 * For kinds ATTRIBUTE_GET_RW or ATTRIBUTE_IS_RW, return
aoqi@0 1822 * the index of the matching ATTRIBUTE_SET method, and
aoqi@0 1823 * vice-versa. For all other cases, return -1.
aoqi@0 1824 */
aoqi@0 1825 public int getAttributePairIndex() {
aoqi@0 1826 return attributePairIndex;
aoqi@0 1827 }
aoqi@0 1828
aoqi@0 1829 /**
aoqi@0 1830 * Return context element name.
aoqi@0 1831 */
aoqi@0 1832 public String getElementName() {
aoqi@0 1833 return memberDef.toString();
aoqi@0 1834 }
aoqi@0 1835
aoqi@0 1836 /**
aoqi@0 1837 * Equality check based on method signature.
aoqi@0 1838 */
aoqi@0 1839 public boolean equals(Object obj) {
aoqi@0 1840 Method other = (Method) obj;
aoqi@0 1841
aoqi@0 1842 if (getName().equals(other.getName()) &&
aoqi@0 1843 arguments.length == other.arguments.length) {
aoqi@0 1844
aoqi@0 1845 for (int i = 0; i < arguments.length; i++) {
aoqi@0 1846 if (! arguments[i].equals(other.arguments[i])) {
aoqi@0 1847 return false;
aoqi@0 1848 }
aoqi@0 1849 }
aoqi@0 1850 return true;
aoqi@0 1851 }
aoqi@0 1852 return false;
aoqi@0 1853 }
aoqi@0 1854
aoqi@0 1855 public int hashCode() {
aoqi@0 1856 return getName().hashCode() ^ Arrays.hashCode(arguments);
aoqi@0 1857 }
aoqi@0 1858
aoqi@0 1859 /**
aoqi@0 1860 * Return a new Method object that is a legal combination of
aoqi@0 1861 * this method object and another one.
aoqi@0 1862 *
aoqi@0 1863 * This requires determining the exceptions declared by the
aoqi@0 1864 * combined method, which must be only those exceptions
aoqi@0 1865 * that may thrown by both of the old methods.
aoqi@0 1866 */
aoqi@0 1867 public Method mergeWith(Method other) {
aoqi@0 1868 if (!equals(other)) {
aoqi@0 1869 env.error(0, "attempt to merge method failed:", getName(),
aoqi@0 1870 enclosing.getClassDefinition().getName());
aoqi@0 1871 }
aoqi@0 1872
aoqi@0 1873 Vector legalExceptions = new Vector();
aoqi@0 1874 try {
aoqi@0 1875 collectCompatibleExceptions(
aoqi@0 1876 other.exceptions, exceptions, legalExceptions);
aoqi@0 1877 collectCompatibleExceptions(
aoqi@0 1878 exceptions, other.exceptions, legalExceptions);
aoqi@0 1879 } catch (ClassNotFound e) {
aoqi@0 1880 env.error(0, "class.not.found", e.name,
aoqi@0 1881 enclosing.getClassDefinition().getName());
aoqi@0 1882 return null;
aoqi@0 1883 }
aoqi@0 1884
aoqi@0 1885 Method merged = (Method) clone();
aoqi@0 1886 merged.exceptions = new ValueType[legalExceptions.size()];
aoqi@0 1887 legalExceptions.copyInto(merged.exceptions);
aoqi@0 1888 merged.implExceptions = merged.exceptions;
aoqi@0 1889
aoqi@0 1890 return merged;
aoqi@0 1891 }
aoqi@0 1892
aoqi@0 1893 /**
aoqi@0 1894 * Add to the supplied list all exceptions in the "from" array
aoqi@0 1895 * that are subclasses of an exception in the "with" array.
aoqi@0 1896 */
aoqi@0 1897 private void collectCompatibleExceptions(
aoqi@0 1898 ValueType[] from, ValueType[] with, Vector list)
aoqi@0 1899 throws ClassNotFound {
aoqi@0 1900
aoqi@0 1901 for (int i = 0; i < from.length; i++) {
aoqi@0 1902 ClassDefinition exceptionDef = from[i].getClassDefinition();
aoqi@0 1903 if (!list.contains(from[i])) {
aoqi@0 1904 for (int j = 0; j < with.length; j++) {
aoqi@0 1905 if (exceptionDef.subClassOf(
aoqi@0 1906 enclosing.getEnv(),
aoqi@0 1907 with[j].getClassDeclaration())) {
aoqi@0 1908 list.addElement(from[i]);
aoqi@0 1909 break;
aoqi@0 1910 }
aoqi@0 1911 }
aoqi@0 1912 }
aoqi@0 1913 }
aoqi@0 1914 }
aoqi@0 1915
aoqi@0 1916 /**
aoqi@0 1917 * Return the compound type which contains this method.
aoqi@0 1918 */
aoqi@0 1919 public CompoundType getEnclosing() {
aoqi@0 1920 return enclosing;
aoqi@0 1921 }
aoqi@0 1922
aoqi@0 1923 /**
aoqi@0 1924 * Return the identifier for the class or interface which
aoqi@0 1925 * declares this method.
aoqi@0 1926 */
aoqi@0 1927 public Identifier getDeclaredBy() {
aoqi@0 1928 return declaredBy;
aoqi@0 1929 }
aoqi@0 1930
aoqi@0 1931 /**
aoqi@0 1932 * Return the visibility (e.g. "public final") of this member.
aoqi@0 1933 */
aoqi@0 1934 public String getVisibility() {
aoqi@0 1935 return vis;
aoqi@0 1936 }
aoqi@0 1937
aoqi@0 1938 /**
aoqi@0 1939 * Methods to check various attributes.
aoqi@0 1940 */
aoqi@0 1941 public boolean isPublic() {
aoqi@0 1942 return memberDef.isPublic();
aoqi@0 1943 }
aoqi@0 1944
aoqi@0 1945 public boolean isProtected() {
aoqi@0 1946 return memberDef.isPrivate();
aoqi@0 1947 }
aoqi@0 1948
aoqi@0 1949 public boolean isPrivate() {
aoqi@0 1950 return memberDef.isPrivate();
aoqi@0 1951 }
aoqi@0 1952
aoqi@0 1953 public boolean isStatic() {
aoqi@0 1954 return memberDef.isStatic();
aoqi@0 1955 }
aoqi@0 1956
aoqi@0 1957 /**
aoqi@0 1958 * Return the name of this method.
aoqi@0 1959 */
aoqi@0 1960 public String getName() {
aoqi@0 1961 return name;
aoqi@0 1962 }
aoqi@0 1963
aoqi@0 1964 /**
aoqi@0 1965 * IDL_Naming
aoqi@0 1966 * Return the IDL name of this method.
aoqi@0 1967 */
aoqi@0 1968 public String getIDLName() {
aoqi@0 1969 return idlName;
aoqi@0 1970 }
aoqi@0 1971
aoqi@0 1972 /**
aoqi@0 1973 * Return the type of this method.
aoqi@0 1974 */
aoqi@0 1975 public sun.tools.java.Type getType() {
aoqi@0 1976 return memberDef.getType();
aoqi@0 1977 }
aoqi@0 1978
aoqi@0 1979 /**
aoqi@0 1980 * Return true if this is a constructor.
aoqi@0 1981 */
aoqi@0 1982 public boolean isConstructor () {
aoqi@0 1983 return memberDef.isConstructor();
aoqi@0 1984 }
aoqi@0 1985
aoqi@0 1986 /**
aoqi@0 1987 * Return true if this is NOT a constructor && is not
aoqi@0 1988 * an attribute.
aoqi@0 1989 */
aoqi@0 1990 public boolean isNormalMethod () {
aoqi@0 1991 return (!memberDef.isConstructor()) && attributeKind == ATTRIBUTE_NONE;
aoqi@0 1992 }
aoqi@0 1993
aoqi@0 1994 /**
aoqi@0 1995 * Get the return type of this method. May be null.
aoqi@0 1996 */
aoqi@0 1997 public Type getReturnType() {
aoqi@0 1998 return returnType;
aoqi@0 1999 }
aoqi@0 2000
aoqi@0 2001 /**
aoqi@0 2002 * Return the argument types of this method.
aoqi@0 2003 */
aoqi@0 2004 public Type[] getArguments() {
aoqi@0 2005 return (Type[]) arguments.clone();
aoqi@0 2006 }
aoqi@0 2007
aoqi@0 2008 /**
aoqi@0 2009 * Return the names of the argument types of this method.
aoqi@0 2010 */
aoqi@0 2011 public String[] getArgumentNames() {
aoqi@0 2012 return argumentNames;
aoqi@0 2013 }
aoqi@0 2014
aoqi@0 2015 /**
aoqi@0 2016 * Return the MemberDefinition from which this method was created.
aoqi@0 2017 */
aoqi@0 2018 public MemberDefinition getMemberDefinition() {
aoqi@0 2019 return memberDef;
aoqi@0 2020 }
aoqi@0 2021
aoqi@0 2022 /**
aoqi@0 2023 * Return an array of the exception classes declared to be
aoqi@0 2024 * thrown by this remote method.
aoqi@0 2025 *
aoqi@0 2026 * For methods with the same name and type signature inherited
aoqi@0 2027 * from multiple remote interfaces, the array will contain
aoqi@0 2028 * the set of exceptions declared in all of the interfaces'
aoqi@0 2029 * methods that can be legally thrown in each of them.
aoqi@0 2030 */
aoqi@0 2031 public ValueType[] getExceptions() {
aoqi@0 2032 return (ValueType[]) exceptions.clone();
aoqi@0 2033 }
aoqi@0 2034
aoqi@0 2035 /**
aoqi@0 2036 * Same as getExceptions(), except when method is in an
aoqi@0 2037 * ImplementationType and the exceptions list is narrower.
aoqi@0 2038 */
aoqi@0 2039 public ValueType[] getImplExceptions() {
aoqi@0 2040 return (ValueType[]) implExceptions.clone();
aoqi@0 2041 }
aoqi@0 2042
aoqi@0 2043 /**
aoqi@0 2044 * Return an array containing only those exceptions which
aoqi@0 2045 * need to be caught. Removes java.rmi.RemoteException,
aoqi@0 2046 * java.lang.RuntimeException, java.lang.Error, and their
aoqi@0 2047 * subclasses, then removes any exceptions which are more
aoqi@0 2048 * derived than another in the list. Returns null if no
aoqi@0 2049 * exceptions need to be caught.
aoqi@0 2050 */
aoqi@0 2051 public ValueType[] getUniqueCatchList(ValueType[] list) {
aoqi@0 2052 ValueType[] result = list;
aoqi@0 2053 int newSize = list.length;
aoqi@0 2054
aoqi@0 2055 try {
aoqi@0 2056
aoqi@0 2057 // First, remove RemoteException, RuntimeException, Error, and their subclasses...
aoqi@0 2058 for (int i = 0; i < list.length; i++) {
aoqi@0 2059 ClassDeclaration decl = list[i].getClassDeclaration();
aoqi@0 2060 if (env.defRemoteException.superClassOf(env, decl) ||
aoqi@0 2061 env.defRuntimeException.superClassOf(env, decl) ||
aoqi@0 2062 env.defError.superClassOf(env, decl)) {
aoqi@0 2063 list[i] = null;
aoqi@0 2064 newSize--;
aoqi@0 2065 }
aoqi@0 2066 }
aoqi@0 2067
aoqi@0 2068 // Now remove derived types...
aoqi@0 2069 for (int i = 0; i < list.length; i++) {
aoqi@0 2070 if (list[i] != null) {
aoqi@0 2071 ClassDefinition current = list[i].getClassDefinition();
aoqi@0 2072 for (int j = 0; j < list.length; j++) {
aoqi@0 2073 if (j != i && list[i] != null && list[j] != null &&
aoqi@0 2074 current.superClassOf(env, list[j].getClassDeclaration())) {
aoqi@0 2075 list[j] = null;
aoqi@0 2076 newSize--;
aoqi@0 2077 }
aoqi@0 2078 }
aoqi@0 2079 }
aoqi@0 2080 }
aoqi@0 2081
aoqi@0 2082 } catch (ClassNotFound e) {
aoqi@0 2083 classNotFound(stack,e); // Report error but do not stop.
aoqi@0 2084 }
aoqi@0 2085
aoqi@0 2086 // Create new list if we removed anything...
aoqi@0 2087
aoqi@0 2088 if (newSize < list.length) {
aoqi@0 2089 ValueType[] temp = new ValueType[newSize];
aoqi@0 2090 int offset = 0;
aoqi@0 2091 for (int i = 0; i < list.length; i++) {
aoqi@0 2092 if (list[i] != null) {
aoqi@0 2093 temp[offset++] = list[i];
aoqi@0 2094 }
aoqi@0 2095 }
aoqi@0 2096 list = temp;
aoqi@0 2097 }
aoqi@0 2098
aoqi@0 2099 if (list.length == 0) {
aoqi@0 2100 return null;
aoqi@0 2101 } else {
aoqi@0 2102 return list;
aoqi@0 2103 }
aoqi@0 2104 }
aoqi@0 2105
aoqi@0 2106 /**
aoqi@0 2107 * Return an array containing only those exceptions which need to be
aoqi@0 2108 * handled explicitly by the stub. Removes java.lang.RuntimeException,
aoqi@0 2109 * java.lang.Error, and their subclasses, since these are all passed
aoqi@0 2110 * back as CORBA system exceptions. Also removes subclasses of
aoqi@0 2111 * java.rmi.RemoteException but not java.rmi.RemoteException itself,
aoqi@0 2112 * since this may need to be thrown by the stub.
aoqi@0 2113 */
aoqi@0 2114 public ValueType[] getFilteredStubExceptions(ValueType[] list) {
aoqi@0 2115 ValueType[] result = list;
aoqi@0 2116 int newSize = list.length;
aoqi@0 2117
aoqi@0 2118 try {
aoqi@0 2119
aoqi@0 2120 for (int i = 0; i < list.length; i++) {
aoqi@0 2121 ClassDeclaration decl = list[i].getClassDeclaration();
aoqi@0 2122 if ((env.defRemoteException.superClassOf(env, decl) &&
aoqi@0 2123 !env.defRemoteException.getClassDeclaration().equals(decl)) ||
aoqi@0 2124 env.defRuntimeException.superClassOf(env, decl) ||
aoqi@0 2125 env.defError.superClassOf(env, decl)) {
aoqi@0 2126 list[i] = null;
aoqi@0 2127 newSize--;
aoqi@0 2128 }
aoqi@0 2129 }
aoqi@0 2130
aoqi@0 2131 } catch (ClassNotFound e) {
aoqi@0 2132 classNotFound(stack,e); // Report error but do not stop.
aoqi@0 2133 }
aoqi@0 2134
aoqi@0 2135 // Create new list if we removed anything...
aoqi@0 2136
aoqi@0 2137 if (newSize < list.length) {
aoqi@0 2138 ValueType[] temp = new ValueType[newSize];
aoqi@0 2139 int offset = 0;
aoqi@0 2140 for (int i = 0; i < list.length; i++) {
aoqi@0 2141 if (list[i] != null) {
aoqi@0 2142 temp[offset++] = list[i];
aoqi@0 2143 }
aoqi@0 2144 }
aoqi@0 2145 list = temp;
aoqi@0 2146 }
aoqi@0 2147
aoqi@0 2148 return list;
aoqi@0 2149 }
aoqi@0 2150
aoqi@0 2151 /**
aoqi@0 2152 * Return the string representation of this method.
aoqi@0 2153 */
aoqi@0 2154 public String toString() {
aoqi@0 2155
aoqi@0 2156 if (stringRep == null) {
aoqi@0 2157
aoqi@0 2158 StringBuffer result = new StringBuffer(returnType.toString());
aoqi@0 2159
aoqi@0 2160 // Add name...
aoqi@0 2161
aoqi@0 2162 result.append(" ");
aoqi@0 2163 result.append(getName());
aoqi@0 2164 result.append(" (");
aoqi@0 2165
aoqi@0 2166 // Add arguments...
aoqi@0 2167
aoqi@0 2168 for (int i = 0; i < arguments.length; i++) {
aoqi@0 2169 if (i > 0) {
aoqi@0 2170 result.append(", ");
aoqi@0 2171 }
aoqi@0 2172 result.append(arguments[i]);
aoqi@0 2173 result.append(" ");
aoqi@0 2174 result.append(argumentNames[i]);
aoqi@0 2175 }
aoqi@0 2176
aoqi@0 2177 result.append(")");
aoqi@0 2178
aoqi@0 2179 // Add exceptions...
aoqi@0 2180
aoqi@0 2181 for (int i = 0; i < exceptions.length; i++) {
aoqi@0 2182 if (i == 0) {
aoqi@0 2183 result.append(" throws ");
aoqi@0 2184 } else {
aoqi@0 2185 result.append(", ");
aoqi@0 2186 }
aoqi@0 2187 result.append(exceptions[i]);
aoqi@0 2188 }
aoqi@0 2189
aoqi@0 2190 result.append(";");
aoqi@0 2191
aoqi@0 2192 stringRep = result.toString();
aoqi@0 2193 }
aoqi@0 2194
aoqi@0 2195 return stringRep;
aoqi@0 2196 }
aoqi@0 2197
aoqi@0 2198
aoqi@0 2199 /**
aoqi@0 2200 * Set attribute kind. May only be called during initialization.
aoqi@0 2201 */
aoqi@0 2202 public void setAttributeKind(int kind) {
aoqi@0 2203 attributeKind = kind;
aoqi@0 2204 }
aoqi@0 2205
aoqi@0 2206 /**
aoqi@0 2207 * Set pair index. May only be called during initialization.
aoqi@0 2208 */
aoqi@0 2209 public void setAttributePairIndex(int index) {
aoqi@0 2210 attributePairIndex = index;
aoqi@0 2211 }
aoqi@0 2212
aoqi@0 2213 /**
aoqi@0 2214 * Set attribute name. May only be called during initialization.
aoqi@0 2215 */
aoqi@0 2216 public void setAttributeName(String name) {
aoqi@0 2217 attributeName = name;
aoqi@0 2218 }
aoqi@0 2219
aoqi@0 2220 /**
aoqi@0 2221 * Set the idl name. May only be called during initialization.
aoqi@0 2222 */
aoqi@0 2223 public void setIDLName (String idlName) {
aoqi@0 2224 this.idlName=idlName;
aoqi@0 2225 }
aoqi@0 2226
aoqi@0 2227 /**
aoqi@0 2228 * Set the implExceptions array. May only be called during initialization.
aoqi@0 2229 */
aoqi@0 2230 public void setImplExceptions (ValueType[] exceptions) {
aoqi@0 2231 implExceptions = exceptions;
aoqi@0 2232 }
aoqi@0 2233
aoqi@0 2234 /**
aoqi@0 2235 * Set the declaredBy Identifier. May only be called during initialization.
aoqi@0 2236 */
aoqi@0 2237 public void setDeclaredBy (Identifier by) {
aoqi@0 2238 declaredBy = by;
aoqi@0 2239 }
aoqi@0 2240
aoqi@0 2241 /**
aoqi@0 2242 * Convert all invalid types to valid ones.
aoqi@0 2243 */
aoqi@0 2244 protected void swapInvalidTypes () {
aoqi@0 2245
aoqi@0 2246 // Check return type...
aoqi@0 2247
aoqi@0 2248 if (returnType.getStatus() != STATUS_VALID) {
aoqi@0 2249 returnType = getValidType(returnType);
aoqi@0 2250 }
aoqi@0 2251
aoqi@0 2252 // Check args...
aoqi@0 2253
aoqi@0 2254 for (int i = 0; i < arguments.length; i++) {
aoqi@0 2255 if (arguments[i].getStatus() != STATUS_VALID) {
aoqi@0 2256 arguments[i] = getValidType(arguments[i]);
aoqi@0 2257 }
aoqi@0 2258 }
aoqi@0 2259
aoqi@0 2260 // Check exceptions...
aoqi@0 2261
aoqi@0 2262 for (int i = 0; i < exceptions.length; i++) {
aoqi@0 2263 if (exceptions[i].getStatus() != STATUS_VALID) {
aoqi@0 2264 exceptions[i] = (ValueType)getValidType(exceptions[i]);
aoqi@0 2265 }
aoqi@0 2266 }
aoqi@0 2267
aoqi@0 2268 // Check implExceptions...
aoqi@0 2269
aoqi@0 2270 for (int i = 0; i < implExceptions.length; i++) {
aoqi@0 2271 if (implExceptions[i].getStatus() != STATUS_VALID) {
aoqi@0 2272 implExceptions[i] = (ValueType)getValidType(implExceptions[i]);
aoqi@0 2273 }
aoqi@0 2274 }
aoqi@0 2275 }
aoqi@0 2276
aoqi@0 2277 /**
aoqi@0 2278 * Release all resources.
aoqi@0 2279 */
aoqi@0 2280 public void destroy () {
aoqi@0 2281 if (memberDef != null) {
aoqi@0 2282 memberDef = null;
aoqi@0 2283 enclosing = null;
aoqi@0 2284 if (exceptions != null) {
aoqi@0 2285 for (int i = 0; i < exceptions.length; i++) {
aoqi@0 2286 if (exceptions[i] != null) exceptions[i].destroy();
aoqi@0 2287 exceptions[i] = null;
aoqi@0 2288 }
aoqi@0 2289 exceptions = null;
aoqi@0 2290 }
aoqi@0 2291
aoqi@0 2292 if (implExceptions != null) {
aoqi@0 2293 for (int i = 0; i < implExceptions.length; i++) {
aoqi@0 2294 if (implExceptions[i] != null) implExceptions[i].destroy();
aoqi@0 2295 implExceptions[i] = null;
aoqi@0 2296 }
aoqi@0 2297 implExceptions = null;
aoqi@0 2298 }
aoqi@0 2299
aoqi@0 2300 if (returnType != null) returnType.destroy();
aoqi@0 2301 returnType = null;
aoqi@0 2302
aoqi@0 2303 if (arguments != null) {
aoqi@0 2304 for (int i = 0; i < arguments.length; i++) {
aoqi@0 2305 if (arguments[i] != null) arguments[i].destroy();
aoqi@0 2306 arguments[i] = null;
aoqi@0 2307 }
aoqi@0 2308 arguments = null;
aoqi@0 2309 }
aoqi@0 2310
aoqi@0 2311 if (argumentNames != null) {
aoqi@0 2312 for (int i = 0; i < argumentNames.length; i++) {
aoqi@0 2313 argumentNames[i] = null;
aoqi@0 2314 }
aoqi@0 2315 argumentNames = null;
aoqi@0 2316 }
aoqi@0 2317
aoqi@0 2318 vis = null;
aoqi@0 2319 name = null;
aoqi@0 2320 idlName = null;
aoqi@0 2321 stringRep = null;
aoqi@0 2322 attributeName = null;
aoqi@0 2323 declaredBy = null;
aoqi@0 2324 }
aoqi@0 2325 }
aoqi@0 2326
aoqi@0 2327 private MemberDefinition memberDef;
aoqi@0 2328 private CompoundType enclosing;
aoqi@0 2329 private ValueType[] exceptions;
aoqi@0 2330 private ValueType[] implExceptions;
aoqi@0 2331 private Type returnType;
aoqi@0 2332 private Type[] arguments;
aoqi@0 2333 private String[] argumentNames;
aoqi@0 2334 private String vis;
aoqi@0 2335 private String name;
aoqi@0 2336 private String idlName;
aoqi@0 2337 private String stringRep = null;
aoqi@0 2338 private int attributeKind = ATTRIBUTE_NONE;
aoqi@0 2339 private String attributeName = null;
aoqi@0 2340 private int attributePairIndex = -1;
aoqi@0 2341 private Identifier declaredBy = null;
aoqi@0 2342
aoqi@0 2343 /**
aoqi@0 2344 * Make up an argument name for the given type.
aoqi@0 2345 */
aoqi@0 2346 private String makeArgName (int argNum, Type type) {
aoqi@0 2347 return "arg" + argNum;
aoqi@0 2348 }
aoqi@0 2349
aoqi@0 2350 /**
aoqi@0 2351 * Create a new Method object corresponding to the given
aoqi@0 2352 * method definition.
aoqi@0 2353 */
aoqi@0 2354 public Method (CompoundType enclosing,
aoqi@0 2355 MemberDefinition memberDef,
aoqi@0 2356 boolean quiet,
aoqi@0 2357 ContextStack stack) throws Exception {
aoqi@0 2358
aoqi@0 2359 this.enclosing = enclosing;
aoqi@0 2360 this.memberDef = memberDef;
aoqi@0 2361 vis = getVisibilityString(memberDef);
aoqi@0 2362 idlName = null; // See setIDLName()
aoqi@0 2363 boolean valid = true;
aoqi@0 2364 declaredBy = memberDef.getClassDeclaration().getName();
aoqi@0 2365
aoqi@0 2366 // Set name...
aoqi@0 2367
aoqi@0 2368 name = memberDef.getName().toString();
aoqi@0 2369
aoqi@0 2370 // Update the context...
aoqi@0 2371
aoqi@0 2372 stack.setNewContextCode(ContextStack.METHOD);
aoqi@0 2373 stack.push(this);
aoqi@0 2374
aoqi@0 2375 // Set return type...
aoqi@0 2376
aoqi@0 2377 stack.setNewContextCode(ContextStack.METHOD_RETURN);
aoqi@0 2378 sun.tools.java.Type methodType = memberDef.getType();
aoqi@0 2379 sun.tools.java.Type rtnType = methodType.getReturnType();
aoqi@0 2380
aoqi@0 2381 if (rtnType == sun.tools.java.Type.tVoid) {
aoqi@0 2382 returnType = PrimitiveType.forPrimitive(rtnType,stack);
aoqi@0 2383 } else {
aoqi@0 2384 returnType = makeType(rtnType,null,stack);
aoqi@0 2385 if (returnType == null ||
aoqi@0 2386 !assertNotImpl(returnType,quiet,stack,enclosing,false)) {
aoqi@0 2387 valid = false;
aoqi@0 2388 failedConstraint(24,quiet,stack,enclosing.getName());
aoqi@0 2389 }
aoqi@0 2390 }
aoqi@0 2391
aoqi@0 2392 // Set arguments and argument names...
aoqi@0 2393
aoqi@0 2394 stack.setNewContextCode(ContextStack.METHOD_ARGUMENT);
aoqi@0 2395 sun.tools.java.Type[] args = memberDef.getType().getArgumentTypes();
aoqi@0 2396 arguments = new Type[args.length];
aoqi@0 2397 argumentNames = new String[args.length];
aoqi@0 2398 Vector origArgNames = memberDef.getArguments();
aoqi@0 2399
aoqi@0 2400 for (int i = 0; i < args.length; i++) {
aoqi@0 2401 Type type = null;
aoqi@0 2402 try {
aoqi@0 2403 type = makeType(args[i],null,stack);
aoqi@0 2404 } catch (Exception e) {
aoqi@0 2405 }
aoqi@0 2406
aoqi@0 2407 if (type != null) {
aoqi@0 2408 if (!assertNotImpl(type,quiet,stack,enclosing,false)) {
aoqi@0 2409 valid = false;
aoqi@0 2410 } else {
aoqi@0 2411 arguments[i] = type;
aoqi@0 2412 if (origArgNames != null) {
aoqi@0 2413 LocalMember local = (LocalMember)origArgNames.elementAt(i+1);
aoqi@0 2414 argumentNames[i] = local.getName().toString();
aoqi@0 2415 } else {
aoqi@0 2416 argumentNames[i] = makeArgName(i,type);
aoqi@0 2417 }
aoqi@0 2418 }
aoqi@0 2419 } else {
aoqi@0 2420 valid = false;
aoqi@0 2421 failedConstraint(25,false,stack,enclosing.getQualifiedName(),name);
aoqi@0 2422 }
aoqi@0 2423 }
aoqi@0 2424
aoqi@0 2425 if (!valid) {
aoqi@0 2426 stack.pop(false);
aoqi@0 2427 throw new Exception();
aoqi@0 2428 }
aoqi@0 2429
aoqi@0 2430 // Set exceptions...
aoqi@0 2431
aoqi@0 2432 try {
aoqi@0 2433 exceptions = enclosing.getMethodExceptions(memberDef,quiet,stack);
aoqi@0 2434 implExceptions = exceptions;
aoqi@0 2435 stack.pop(true);
aoqi@0 2436 } catch (Exception e) {
aoqi@0 2437 stack.pop(false);
aoqi@0 2438 throw new Exception();
aoqi@0 2439 }
aoqi@0 2440 }
aoqi@0 2441
aoqi@0 2442 /**
aoqi@0 2443 * Cloning is supported by returning a shallow copy of this object.
aoqi@0 2444 */
aoqi@0 2445 protected Object clone() {
aoqi@0 2446 try {
aoqi@0 2447 return super.clone();
aoqi@0 2448 } catch (CloneNotSupportedException e) {
aoqi@0 2449 throw new Error("clone failed");
aoqi@0 2450 }
aoqi@0 2451 }
aoqi@0 2452 }
aoqi@0 2453
aoqi@0 2454 //_____________________________________________________________________
aoqi@0 2455 // Inner Class "Member"
aoqi@0 2456 //_____________________________________________________________________
aoqi@0 2457
aoqi@0 2458 /**
aoqi@0 2459 * An CompoundType.Member object wraps a Type and a value representing
aoqi@0 2460 * a data member, including constants.
aoqi@0 2461 */
aoqi@0 2462 public class Member implements ContextElement, Cloneable {
aoqi@0 2463
aoqi@0 2464 /**
aoqi@0 2465 * Return context element name.
aoqi@0 2466 */
aoqi@0 2467 public String getElementName() {
aoqi@0 2468 return "\"" + getName() + "\"";
aoqi@0 2469 }
aoqi@0 2470
aoqi@0 2471 /**
aoqi@0 2472 * Return the type of this member.
aoqi@0 2473 */
aoqi@0 2474 public Type getType() {
aoqi@0 2475 return type;
aoqi@0 2476 }
aoqi@0 2477
aoqi@0 2478 /**
aoqi@0 2479 * Return the name of this member.
aoqi@0 2480 */
aoqi@0 2481 public String getName() {
aoqi@0 2482 return name;
aoqi@0 2483 }
aoqi@0 2484
aoqi@0 2485 /**
aoqi@0 2486 * IDL_Naming
aoqi@0 2487 * Return the IDL name of this member.
aoqi@0 2488 */
aoqi@0 2489 public String getIDLName() {
aoqi@0 2490 return idlName;
aoqi@0 2491 }
aoqi@0 2492
aoqi@0 2493 /**
aoqi@0 2494 * Return the visibility (e.g. "public final") of this member.
aoqi@0 2495 */
aoqi@0 2496 public String getVisibility() {
aoqi@0 2497 return vis;
aoqi@0 2498 }
aoqi@0 2499
aoqi@0 2500 /**
aoqi@0 2501 * Methods to check various attributes.
aoqi@0 2502 */
aoqi@0 2503 public boolean isPublic() {
aoqi@0 2504 return member.isPublic();
aoqi@0 2505 }
aoqi@0 2506
aoqi@0 2507 public boolean isPrivate() {
aoqi@0 2508 return member.isPrivate();
aoqi@0 2509 }
aoqi@0 2510
aoqi@0 2511 public boolean isStatic() {
aoqi@0 2512 return member.isStatic();
aoqi@0 2513 }
aoqi@0 2514
aoqi@0 2515 public boolean isFinal() {
aoqi@0 2516 return member.isFinal();
aoqi@0 2517 }
aoqi@0 2518
aoqi@0 2519 public boolean isTransient() {
aoqi@0 2520 if (forceTransient) return true;
aoqi@0 2521 return member.isTransient();
aoqi@0 2522 }
aoqi@0 2523
aoqi@0 2524 /**
aoqi@0 2525 * Return the value of this member. May be null.
aoqi@0 2526 */
aoqi@0 2527 public String getValue() {
aoqi@0 2528 return value;
aoqi@0 2529 }
aoqi@0 2530
aoqi@0 2531 /**
aoqi@0 2532 * Return true if this member represents an inner class declaration,
aoqi@0 2533 * false otherwise.
aoqi@0 2534 */
aoqi@0 2535 public boolean isInnerClassDeclaration() {
aoqi@0 2536 return innerClassDecl;
aoqi@0 2537 }
aoqi@0 2538
aoqi@0 2539 /**
aoqi@0 2540 * Return true if this member represents a constant.
aoqi@0 2541 */
aoqi@0 2542 public boolean isConstant () {
aoqi@0 2543 return constant;
aoqi@0 2544 }
aoqi@0 2545
aoqi@0 2546 /**
aoqi@0 2547 * Return the string representation of this constant.
aoqi@0 2548 */
aoqi@0 2549 public String toString() {
aoqi@0 2550
aoqi@0 2551 String result = type.toString();
aoqi@0 2552
aoqi@0 2553 if (value != null) {
aoqi@0 2554 result += (" = " + value);
aoqi@0 2555 }
aoqi@0 2556
aoqi@0 2557 return result;
aoqi@0 2558 }
aoqi@0 2559
aoqi@0 2560 /**
aoqi@0 2561 * Convert all invalid types to valid ones.
aoqi@0 2562 */
aoqi@0 2563 protected void swapInvalidTypes () {
aoqi@0 2564 if (type.getStatus() != STATUS_VALID) {
aoqi@0 2565 type = getValidType(type);
aoqi@0 2566 }
aoqi@0 2567 }
aoqi@0 2568
aoqi@0 2569 protected void setTransient() {
aoqi@0 2570 if (! isTransient()) {
aoqi@0 2571 forceTransient = true;
aoqi@0 2572 if (vis.length() > 0) {
aoqi@0 2573 vis = vis + " transient";
aoqi@0 2574 } else {
aoqi@0 2575 vis = "transient";
aoqi@0 2576 }
aoqi@0 2577 }
aoqi@0 2578 }
aoqi@0 2579
aoqi@0 2580 protected MemberDefinition getMemberDefinition() {
aoqi@0 2581 return member;
aoqi@0 2582 }
aoqi@0 2583
aoqi@0 2584 /**
aoqi@0 2585 * Release all resources.
aoqi@0 2586 */
aoqi@0 2587 public void destroy () {
aoqi@0 2588 if (type != null) {
aoqi@0 2589 type.destroy();
aoqi@0 2590 type = null;
aoqi@0 2591 vis = null;
aoqi@0 2592 value = null;
aoqi@0 2593 name = null;
aoqi@0 2594 idlName = null;
aoqi@0 2595 member = null;
aoqi@0 2596 }
aoqi@0 2597 }
aoqi@0 2598
aoqi@0 2599 private Type type;
aoqi@0 2600 private String vis;
aoqi@0 2601 private String value;
aoqi@0 2602 private String name;
aoqi@0 2603 private String idlName;
aoqi@0 2604 private boolean innerClassDecl;
aoqi@0 2605 private boolean constant;
aoqi@0 2606 private MemberDefinition member;
aoqi@0 2607 private boolean forceTransient;
aoqi@0 2608
aoqi@0 2609 /**
aoqi@0 2610 * Create a new Member object.
aoqi@0 2611 */
aoqi@0 2612 public Member(MemberDefinition member,
aoqi@0 2613 String value,
aoqi@0 2614 ContextStack stack,
aoqi@0 2615 CompoundType enclosing) {
aoqi@0 2616 this.member = member;
aoqi@0 2617 this.value = value;
aoqi@0 2618 forceTransient = false;
aoqi@0 2619 innerClassDecl = member.getInnerClass() != null;
aoqi@0 2620
aoqi@0 2621 // If we are not an inner class, finish initializing now.
aoqi@0 2622 // Otherwise, wait until outer class is finished, then
aoqi@0 2623 // call init to avoid potential recursion problems...
aoqi@0 2624
aoqi@0 2625 if (!innerClassDecl) {
aoqi@0 2626 init (stack,enclosing);
aoqi@0 2627 }
aoqi@0 2628 }
aoqi@0 2629
aoqi@0 2630 public void init (ContextStack stack, CompoundType enclosing) {
aoqi@0 2631
aoqi@0 2632 constant = false;
aoqi@0 2633 name = member.getName().toString();
aoqi@0 2634 vis = getVisibilityString(member);
aoqi@0 2635 idlName = null;
aoqi@0 2636
aoqi@0 2637 // Add self to stack...
aoqi@0 2638
aoqi@0 2639 int contextCode = ContextStack.MEMBER;
aoqi@0 2640 stack.setNewContextCode(contextCode);
aoqi@0 2641
aoqi@0 2642 // Check for special contextCodes...
aoqi@0 2643
aoqi@0 2644 if (member.isVariable()) {
aoqi@0 2645 if (value != null && member.isConstant()) {
aoqi@0 2646 contextCode = ContextStack.MEMBER_CONSTANT;
aoqi@0 2647 this.constant = true;
aoqi@0 2648 } else if (member.isStatic()) {
aoqi@0 2649 contextCode = ContextStack.MEMBER_STATIC;
aoqi@0 2650 } else if (member.isTransient()) {
aoqi@0 2651 contextCode = ContextStack.MEMBER_TRANSIENT;
aoqi@0 2652 }
aoqi@0 2653 }
aoqi@0 2654
aoqi@0 2655 stack.setNewContextCode(contextCode);
aoqi@0 2656 stack.push(this);
aoqi@0 2657
aoqi@0 2658 type = makeType(member.getType(),null,stack);
aoqi@0 2659
aoqi@0 2660 if (type == null ||
aoqi@0 2661 (!innerClassDecl &&
aoqi@0 2662 !member.isStatic() &&
aoqi@0 2663 !member.isTransient() &&
aoqi@0 2664 !assertNotImpl(type,false,stack,enclosing,true))) {
aoqi@0 2665 stack.pop(false);
aoqi@0 2666 throw new CompilerError("");
aoqi@0 2667 }
aoqi@0 2668
aoqi@0 2669 // Clean up primitive constant values...
aoqi@0 2670
aoqi@0 2671 if (constant && type.isPrimitive()) {
aoqi@0 2672 if (type.isType(TYPE_LONG) || type.isType(TYPE_FLOAT) || type.isType(TYPE_DOUBLE)) {
aoqi@0 2673 int length = value.length();
aoqi@0 2674 char lastChar = value.charAt(length-1);
aoqi@0 2675 if (!Character.isDigit(lastChar)) {
aoqi@0 2676 this.value = value.substring(0,length-1);
aoqi@0 2677 }
aoqi@0 2678 } else if (type.isType(TYPE_BOOLEAN)) {
aoqi@0 2679 value = value.toUpperCase();
aoqi@0 2680 }
aoqi@0 2681 }
aoqi@0 2682 if (constant && type.isType(TYPE_STRING)) {
aoqi@0 2683 value = "L" + value;
aoqi@0 2684 }
aoqi@0 2685 stack.pop(true);
aoqi@0 2686 }
aoqi@0 2687
aoqi@0 2688 public void setIDLName (String name) {
aoqi@0 2689 this.idlName = name;
aoqi@0 2690 }
aoqi@0 2691
aoqi@0 2692 /**
aoqi@0 2693 * Cloning is supported by returning a shallow copy of this object.
aoqi@0 2694 */
aoqi@0 2695 protected Object clone() {
aoqi@0 2696 try {
aoqi@0 2697 return super.clone();
aoqi@0 2698 } catch (CloneNotSupportedException e) {
aoqi@0 2699 throw new Error("clone failed");
aoqi@0 2700 }
aoqi@0 2701 }
aoqi@0 2702 }
aoqi@0 2703 }

mercurial