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

Mon, 26 Mar 2012 14:01:40 +0100

author
coffeys
date
Mon, 26 Mar 2012 14:01:40 +0100
changeset 370
5222b7d658d4
parent 158
91006f157c46
child 473
5845df371e25
permissions
-rw-r--r--

7143851: Improve IIOP stub and tie generation in RMIC
7149048: Changes to corba rmic stubGenerator class are not used during jdk build process
Reviewed-by: mschoene, robm

     1 /*
     2  * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 /*
    27  * Licensed Materials - Property of IBM
    28  * RMI-IIOP v1.0
    29  * Copyright IBM Corp. 1998 1999  All Rights Reserved
    30  *
    31  */
    33 package sun.rmi.rmic.iiop;
    35 import java.util.Vector;
    36 import sun.tools.java.Identifier;
    37 import sun.tools.java.ClassNotFound;
    38 import sun.tools.java.ClassDefinition;
    39 import sun.tools.java.ClassDeclaration;
    40 import sun.tools.java.MemberDefinition;
    41 import sun.tools.java.CompilerError;
    42 import sun.tools.tree.Node;
    43 import sun.tools.tree.LocalMember;
    44 import sun.tools.tree.CharExpression;
    45 import sun.tools.tree.IntegerExpression;
    46 import sun.rmi.rmic.IndentingWriter;
    47 import java.io.IOException;
    48 import java.util.HashSet;
    49 import java.util.Enumeration;
    50 import java.io.File;
    52 /**
    53  * A CompoundType is an abstract base class for all IIOP class and
    54  * interface types.
    55  *
    56  * @author      Bryan Atsatt
    57  */
    58 public abstract class CompoundType extends Type {
    60     protected Method[] methods;
    61     protected InterfaceType[] interfaces;
    62     protected Member[] members;
    63     protected ClassDefinition classDef;
    64     protected ClassDeclaration classDecl;
    66     protected boolean isCORBAObject = false;
    67     protected boolean isIDLEntity = false;
    68     protected boolean isAbstractBase = false;
    69     protected boolean isValueBase = false;
    70     protected boolean isCORBAUserException = false;
    71     protected boolean isException = false;
    72     protected boolean isCheckedException = false;
    73     protected boolean isRemoteExceptionOrSubclass = false;
    74     protected String idlExceptionName;
    75     protected String qualifiedIDLExceptionName;
    77     //_____________________________________________________________________
    78     // Public Interfaces
    79     //_____________________________________________________________________
    81     /**
    82      * Return true if this type implements
    83      * org.omg.CORBA.Object.
    84      */
    85     public boolean isCORBAObject () {
    86         return isCORBAObject;
    87     }
    89     /**
    90      * Return true if this type implements
    91      * org.omg.CORBA.portable.IDLEntity.
    92      */
    93     public boolean isIDLEntity () {
    94         return isIDLEntity;
    95     }
    97     /**
    98      * Return true if this type implements
    99      * org.omg.CORBA.portable.ValueBase.
   100      */
   101     public boolean isValueBase () {
   102         return isValueBase;
   103     }
   105     /**
   106      * Return true if this type is a CORBA
   107      * abstract interface.
   108      */
   109     public boolean isAbstractBase () {
   110         return isAbstractBase;
   111     }
   113     /**
   114      * Return true if this type is an exception.
   115      */
   116     public boolean isException () {
   117         return isException;
   118     }
   120     /**
   121      * Return true if this type is a "checked" exception.
   122      * Result if valid iff isException() returns true.
   123      */
   124     public boolean isCheckedException () {
   125         return isCheckedException;
   126     }
   128     /**
   129      * Return true if this type is a java.rmi.RemoteException
   130      * or one of its subclasses. Result if valid iff isException()
   131      * returns true.
   132      */
   133     public boolean isRemoteExceptionOrSubclass () {
   134         return isRemoteExceptionOrSubclass;
   135     }
   137     /**
   138      * Return true if this type is exactly
   139      * org.omg.CORBA.UserException.
   140      */
   141     public boolean isCORBAUserException () {
   142         return isCORBAUserException;
   143     }
   145     /**
   146      * Return true if this type implements
   147      * isIDLEntity() && isException().
   148      */
   149     public boolean isIDLEntityException () {
   150         return isIDLEntity() && isException();
   151     }
   152     /**
   153      * Return true if isIDLEntity() && !isValueBase()
   154      * && !isAbstractBase() && !isCORBAObject()
   155      * && !isIDLEntityException().
   156      */
   157     public boolean isBoxed () {
   158         return (isIDLEntity() && !isValueBase() &&
   159                 !isAbstractBase() && !isCORBAObject() &&
   160                 !isIDLEntityException());
   161     }
   163     /**
   164      * If this type represents an exception, return the
   165      * IDL name including the "Ex" mangling, otherwise
   166      * return null.
   167      */
   168     public String getIDLExceptionName () {
   169         return idlExceptionName;
   170     }
   172     /**
   173      * If this type represents an exception, return the
   174      * qualified IDL name including the "Ex" mangling,
   175      * otherwise return null.
   176      * @param global If true, prepends "::".
   177      */
   178     public String getQualifiedIDLExceptionName (boolean global) {
   179         if (qualifiedIDLExceptionName != null &&
   180             global &&
   181             getIDLModuleNames().length > 0) {
   182             return IDL_NAME_SEPARATOR + qualifiedIDLExceptionName;
   183         } else {
   184             return qualifiedIDLExceptionName;
   185         }
   186     }
   188     /**
   189      * Return signature for this type  (e.g. com.acme.Dynamite
   190      * would return "com.acme.Dynamite", byte = "B")
   191      */
   192     public String getSignature() {
   193         String sig = classDecl.getType().getTypeSignature();
   194         if (sig.endsWith(";")) {
   195             sig = sig.substring(0,sig.length()-1);
   196         }
   197         return sig;
   198     }
   200     /**
   201      * Return the ClassDeclaration for this type.
   202      */
   203     public ClassDeclaration getClassDeclaration() {
   204         return classDecl;
   205     }
   207     /**
   208      * Return the ClassDefinition for this type.
   209      */
   210     public ClassDefinition getClassDefinition() {
   211         return classDef;
   212     }
   214     /**
   215      * Return the parent class of this type. Returns null if this
   216      * type is an interface or if there is no parent.
   217      */
   218     public ClassType getSuperclass() {
   219         return null;
   220     }
   222     /**
   223      * Return an array of interfaces directly implemented by this type.
   224      * <p>
   225      * The order of the array returned is arbitrary.
   226      */
   227     public InterfaceType[] getInterfaces() {
   228         if( interfaces != null ) {
   229             return (InterfaceType[]) interfaces.clone();
   230         }
   231         return null;
   232     }
   234     /**
   235      * Return an array of Type.Method objects representing all
   236      * of the methods implemented directly by this type.
   237      */
   238     public Method[] getMethods() {
   239         if( methods != null ) {
   240             return (Method[]) methods.clone();
   241         }
   242         return null;
   243     }
   245     /**
   246      * Return an array of Type.Member objects representing all of
   247      * the data members directly implemented by this interface.
   248      */
   249     public Member[] getMembers() {
   250         if( members != null ) {
   251             return (Member[]) members.clone();
   252         }
   253         return null;
   254     }
   256     /**
   257      * Create a CompoundType object for the given class.
   258      *
   259      * If the class is not a properly formed or if some other error occurs, the
   260      * return value will be null, and errors will have been reported to the
   261      * supplied BatchEnvironment.
   262      */
   263     public static CompoundType forCompound (ClassDefinition classDef,
   264                                             ContextStack stack) {
   265         CompoundType result = null;
   267         try {
   268             result = (CompoundType) makeType(classDef.getType(),classDef,stack);
   269         } catch (ClassCastException e) {}
   271         return result;
   272     }
   275     //_____________________________________________________________________
   276     // Subclass/Internal Interfaces
   277     //_____________________________________________________________________
   279     /**
   280      * Release all resources.
   281      */
   282     protected void destroy () {
   283         if (!destroyed) {
   284             super.destroy();
   286             if (methods != null) {
   287                 for (int i = 0; i < methods.length; i++) {
   288                     if (methods[i] != null) methods[i].destroy();
   289                 }
   290                 methods = null;
   291             }
   293             if (interfaces != null) {
   294                 for (int i = 0; i < interfaces.length; i++) {
   295                     if (interfaces[i] != null) interfaces[i].destroy();
   296                 }
   297                 interfaces = null;
   298             }
   300             if (members != null) {
   301                 for (int i = 0; i < members.length; i++) {
   302                     if (members[i] != null) members[i].destroy();
   303                 }
   304                 members = null;
   305             }
   307             classDef = null;
   308             classDecl = null;
   309         }
   310     }
   312     /*
   313      * Load a Class instance. Return null if fail.
   314      */
   315     protected Class loadClass() {
   317         Class ourClass = null;
   319         // To avoid getting out-of-date Class instances, and
   320         // to ensure that there is an instance, we must compile
   321         // any classes that we've seen and which are not yet
   322         // compiled. We can't just compile this class, 'cuz it
   323         // may have dependencies on classes which have not been
   324         // compiled...
   326         try {
   327             env.getMain().compileAllClasses(env);
   328         } catch (Exception e1) {
   329             for (Enumeration e = env.getClasses() ; e.hasMoreElements() ; ) {
   330                 ClassDeclaration c = (ClassDeclaration)e.nextElement();
   331             }
   332             failedConstraint(26,false,stack,"required classes");
   333             env.flushErrors();
   334         }
   336         // Now try to get the Class...
   337         // The outer try block is there for people who might want to use
   338         // the compiler at run-time of their AS.
   339         // They could set and use their own context class loader for loading
   340         // classes directly.
   341         try {
   342             ClassLoader cl = Thread.currentThread().getContextClassLoader();
   343             ourClass = cl.loadClass(getQualifiedName());
   344         } catch(ClassNotFoundException cfe) {
   346             try {
   347                 ourClass = env.classPathLoader.loadClass(getQualifiedName());
   348             } catch (NullPointerException e) {
   349                 // This should never happen
   350             } catch (ClassNotFoundException e) {
   351                 // Fall through to the next case (which is to look in the
   352                 // output directory for generated files)
   353             }
   354         }
   356         /* This piece of code used to cause the compiler to ignore jar files
   357            on its classpath
   358         try {
   359             ourClass = Util.loadClass(getQualifiedName(),null,null);
   360         } catch (ClassNotFoundException e) {
   361         } catch (LinkageError e) {
   362         }
   363         */
   365         if (ourClass == null) {
   367             // Try one last thing. If the class was compiled into
   368             // a directory that's not in the classpath, the load
   369             // will fail. Let's get the bits off the disk and load
   370             // it directly...
   372             if (env.loader == null) {
   373                 File destDir = env.getMain().getDestinationDir();
   374                 if (destDir == null) {
   375                     destDir = new File(".");
   376                 }
   377                 env.loader = new DirectoryLoader(destDir);
   378             }
   380             try {
   381                 ourClass = env.loader.loadClass(getQualifiedName());
   382             } catch (Exception e) {}
   383         }
   385         return ourClass;
   386     }
   388     // Print "extends XX"
   390     protected boolean printExtends (IndentingWriter writer,
   391                                     boolean useQualifiedNames,
   392                                     boolean useIDLNames,
   393                                     boolean globalIDLNames) throws IOException {
   395         ClassType parent = getSuperclass();
   397         if (parent != null && (!useIDLNames ||
   398                                (!parent.isType(TYPE_ANY) && !parent.isType(TYPE_CORBA_OBJECT)))) {
   399             writer.p(" extends ");
   400             parent.printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   401             return true;
   402         }
   403         return false;
   404     }
   406     // Print "implements XX, YY"
   408     protected void printImplements (IndentingWriter writer,
   409                                     String prefix,
   410                                     boolean useQualifiedNames,
   411                                     boolean useIDLNames,
   412                                     boolean globalIDLNames) throws IOException {
   414         InterfaceType[] interfaces = getInterfaces();
   416         String adjective = " implements";
   418         if (isInterface()) {
   419             adjective = " extends";
   420         }
   422         if (useIDLNames) {
   423             adjective = ":";
   424         }
   426         for (int i = 0; i < interfaces.length; i++) {
   427             if (!useIDLNames || (!interfaces[i].isType(TYPE_ANY) && !interfaces[i].isType(TYPE_CORBA_OBJECT))) {
   428                 if (i == 0) {
   429                     writer.p(prefix + adjective + " ");
   430                 } else {
   431                     writer.p(", ");
   432                 }
   433                 interfaces[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   434             }
   435         }
   436     }
   438     // Print members
   440     protected void printMembers (       IndentingWriter writer,
   441                                         boolean useQualifiedNames,
   442                                         boolean useIDLNames,
   443                                         boolean globalIDLNames) throws IOException {
   445         CompoundType.Member[] members = getMembers();
   447         for (int i = 0; i < members.length; i++) {
   448             if (!members[i].isInnerClassDeclaration()) {
   449                 Type it = members[i].getType();
   450                 String visibility = members[i].getVisibility();
   451                 String name;
   453                 if (useIDLNames) {
   454                     name = members[i].getIDLName();
   455                 } else {
   456                     name = members[i].getName();
   457                 }
   459                 String value = members[i].getValue();
   461                 writer.p(visibility);
   462                 if (visibility.length() > 0) {
   463                     writer.p(" ");
   464                 }
   465                 it.printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   466                 writer.p(" " + name);
   468                 if (value != null) {
   469                     writer.pln(" = " + value + ";");
   470                 } else {
   471                     writer.pln(";");
   472                 }
   473             }
   474         }
   475     }
   477     // Print methods
   479     protected void printMethods (       IndentingWriter writer,
   480                                         boolean useQualifiedNames,
   481                                         boolean useIDLNames,
   482                                         boolean globalIDLNames) throws IOException {
   484         CompoundType.Method[] methods = getMethods();
   486         for (int m = 0; m < methods.length; m++) {
   487             CompoundType.Method theMethod = methods[m];
   488             printMethod(theMethod,writer,useQualifiedNames,useIDLNames,globalIDLNames);
   489         }
   490     }
   492     // Print a method...
   494     protected void printMethod (CompoundType.Method it,
   495                                 IndentingWriter writer,
   496                                 boolean useQualifiedNames,
   497                                 boolean useIDLNames,
   498                                 boolean globalIDLNames) throws IOException {
   501         // Write visibility...
   503         String visibility = it.getVisibility();
   505         writer.p(visibility);
   506         if (visibility.length() > 0) {
   507             writer.p(" ");
   508         }
   510         // Write return type...
   512         it.getReturnType().printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   514         // Write method name...
   516         if (useIDLNames) {
   517             writer.p(" " + it.getIDLName());
   518         } else {
   519             writer.p(" " + it.getName());
   520         }
   522         // Write arguments...
   524         writer.p(" (");
   525         Type[] args = it.getArguments();
   526         String[] argNames = it.getArgumentNames();
   528         for (int i = 0; i < args.length; i++) {
   529             if (i > 0) {
   530                 writer.p(", ");
   531             }
   533             if (useIDLNames) {
   534                 writer.p("in ");
   535             }
   537             args[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   538             writer.p(" " + argNames[i]);
   539         }
   540         writer.p(")");
   542         // Write exceptions...
   544         ClassType[] exceptions;
   546         if (isType(TYPE_IMPLEMENTATION)) {
   547             exceptions = it.getImplExceptions();
   548         } else {
   549             exceptions = it.getExceptions();
   550         }
   552         for (int i = 0; i < exceptions.length; i++) {
   553             if (i == 0) {
   554                 if (useIDLNames) {
   555                     writer.p(" raises (");
   556                 } else {
   557                     writer.p(" throws ");
   558                 }
   559             } else {
   560                 writer.p(", ");
   561             }
   563             if (useIDLNames) {
   564                 if (useQualifiedNames) {
   565                     writer.p(exceptions[i].getQualifiedIDLExceptionName(globalIDLNames));
   566                 } else {
   567                     writer.p(exceptions[i].getIDLExceptionName());
   568                 }
   569                 writer.p(" [a.k.a. ");
   570                 exceptions[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   571                 writer.p("]");
   572             } else {
   573                 exceptions[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   574             }
   575         }
   577         if (useIDLNames && exceptions.length > 0) {
   578             writer.p(")");
   579         }
   581         if (it.isInherited()) {
   582             writer.p(" // Inherited from ");
   583         writer.p(it.getDeclaredBy());
   584         }
   586         writer.pln(";");
   587     }
   589     /**
   590      * Create a CompoundType instance for the given class. NOTE: This constructor
   591      * is ONLY for SpecialClassType and SpecialInterfaceType.
   592      */
   593     protected CompoundType(ContextStack stack, int typeCode, ClassDefinition classDef) {
   594         super(stack,typeCode);
   595         this.classDef = classDef;
   596         classDecl = classDef.getClassDeclaration();
   597         interfaces = new InterfaceType[0];
   598         methods = new Method[0];
   599         members = new Member[0];
   601         // If we are an inner class/interface, reset the type codes...
   603         if (classDef.isInnerClass()) {
   604             setTypeCode(typeCode | TM_INNER);
   605         }
   607         // Set special flags...
   609         setFlags();
   610     }
   612     private void setFlags() {
   614         try {
   616         // Set our special interface flags...
   618             isCORBAObject = env.defCorbaObject.implementedBy(env,classDecl);
   619             isIDLEntity = env.defIDLEntity.implementedBy(env,classDecl);
   620             isValueBase = env.defValueBase.implementedBy(env,classDecl);
   621             isAbstractBase = isInterface() &&   // Interface, not a class.
   622                              isIDLEntity &&     // Implements IDLEntity.
   623                              !isValueBase &&    // Does not implement ValueBase.
   624                              !isCORBAObject;    // Does not implement org.omg.CORBA.Object;
   625             isCORBAUserException = (classDecl.getName() == idCorbaUserException);
   627             // Is this an exception?
   629             if (env.defThrowable.implementedBy(env, classDecl)) {
   631                 // Yes...
   633                 isException = true;
   635                 // Is it a checked exception?
   637                 if (env.defRuntimeException.implementedBy(env,classDecl) ||
   638                     env.defError.implementedBy(env,classDecl)) {
   639                     isCheckedException = false;
   640                 } else {
   641                     isCheckedException = true;
   642                 }
   644                 // Is it java.rmi.RemoteException or a subclass?
   646                 if (env.defRemoteException.implementedBy(env,classDecl)) {
   647                     isRemoteExceptionOrSubclass = true;
   648                 } else {
   649                     isRemoteExceptionOrSubclass = false;
   650                 }
   651             } else {
   652                 isException = false;
   653             }
   654         } catch (ClassNotFound e) {
   655             classNotFound(stack,e);
   656         }
   657     }
   659     /**
   660      * Create a CompoundType instance for the given class.  The resulting
   661      * object is not yet completely initialized.
   662      */
   663     protected CompoundType(ContextStack stack, ClassDefinition classDef,
   664                            int typeCode) {
   665         super(stack,typeCode);
   666         this.classDef = classDef;
   667         classDecl = classDef.getClassDeclaration();
   669         // If we are an inner class/interface, reset the type codes...
   671         if (classDef.isInnerClass()) {
   672             setTypeCode(typeCode | TM_INNER);
   673         }
   675         // Set special flags...
   677         setFlags();
   679         // Set names...
   681         Identifier id = classDef.getName();
   682         String idlName;
   683         String[] idlModuleNames;
   685         try {
   687             // These can fail if we get case-sensitive name matches...
   689             idlName = IDLNames.getClassOrInterfaceName(id,env);
   690             idlModuleNames = IDLNames.getModuleNames(id,isBoxed(),env);
   692             setNames(id,idlModuleNames,idlName);
   694             // Is this an exception?
   696             if (isException()) {
   698                 // Yes, so set our mangled exception names...
   700                 isException = true;
   701                 idlExceptionName = IDLNames.getExceptionName(getIDLName());
   702                 qualifiedIDLExceptionName =
   703                     IDLNames.getQualifiedName(getIDLModuleNames(),idlExceptionName);
   704             }
   706             // Set interfaces, methods and members...
   708             interfaces = null;          // set in initialize()
   709             methods = null;                     // set in initialize()
   710             members = null;                 // set in initialize()
   712         } catch (Exception e) {
   713             failedConstraint(7,false,stack,id.toString(),e.getMessage());
   714             throw new CompilerError("");
   715         }
   716     }
   718     /**
   719      * Initialize this instance.
   720      */
   721     protected boolean initialize (      Vector directInterfaces,
   722                                         Vector directMethods,
   723                                         Vector directMembers,
   724                                         ContextStack stack,
   725                                         boolean quiet) {
   727         boolean result = true;
   729         // Initialize our arrays...
   731         if (directInterfaces != null && directInterfaces.size() > 0) {
   732             interfaces = new InterfaceType[directInterfaces.size()];
   733             directInterfaces.copyInto(interfaces);
   734         } else {
   735             interfaces = new InterfaceType[0];
   736         }
   738         if (directMethods != null && directMethods.size() > 0) {
   739             methods = new Method[directMethods.size()];
   740             directMethods.copyInto(methods);
   742             // Now set the idl names for each...
   744             try {
   745                 IDLNames.setMethodNames(this, methods,env);
   746             } catch (Exception e) {
   747                 failedConstraint(13,quiet,stack,getQualifiedName(),e.getMessage());
   748                 result = false;
   749             }
   751         } else {
   752             methods = new Method[0];
   753         }
   755         if (directMembers != null && directMembers.size() > 0) {
   756             members = new Member[directMembers.size()];
   757             directMembers.copyInto(members);
   759             // If we have any un-initialized inner classes, now is the time
   760             // to init them...
   762             for (int i = 0; i < members.length; i++) {
   763                 if (members[i].isInnerClassDeclaration()) {
   764                     try {
   765                         members[i].init(stack,this);
   766                     } catch (CompilerError e) {
   767                         return false;
   768                     }
   769                 }
   770             }
   772             // Now set the idl names for each...
   774             try {
   775                 IDLNames.setMemberNames(this, members,methods,env);
   776             } catch (Exception e) {
   777                 int constraint = classDef.isInterface() ? 19 : 20;
   778                 failedConstraint(constraint,quiet,stack,getQualifiedName(),e.getMessage());
   779                 result = false;
   780             }
   782         } else {
   783             members = new Member[0];
   784         }
   786         // Set our repositoryID...
   788         if (result) {
   789             result = setRepositoryID();
   790         }
   792         return result;
   793     }
   795     /*
   796      * Return Type or null if error. classDef may be null.
   797      */
   798     protected static Type makeType (sun.tools.java.Type theType,
   799                                     ClassDefinition classDef,
   800                                     ContextStack stack) {
   802         if (stack.anyErrors()) return null;
   804         // See if we can find this type in the cache.  If so, return it...
   806         String key = theType.toString();
   808         Type result = getType(key,stack);
   810         if (result != null) {
   811             return result;
   812         }
   814         // Gotta try with context...
   816         result = getType(key + stack.getContextCodeString(),stack);
   818         if (result != null) {
   819             return result;
   820         }
   822         // Gotta map it...
   824         BatchEnvironment env = stack.getEnv();
   825         int typeCode = theType.getTypeCode();
   826         switch (typeCode) {
   827         case TC_BOOLEAN:
   828         case TC_BYTE:
   829         case TC_CHAR:
   830         case TC_SHORT:
   831         case TC_INT:
   832         case TC_LONG:
   833         case TC_FLOAT:
   834         case TC_DOUBLE:
   835             {
   836                 // Primitive...
   838                 result = PrimitiveType.forPrimitive(theType,stack);
   839                 break;
   840             }
   842         case TC_ARRAY:
   843             {
   844                 // Array.
   846                 result = ArrayType.forArray(theType,stack);
   847                 break;
   848             }
   850         case TC_CLASS:
   851             {
   852                 try {
   853                                 // First, make sure we have the class definition...
   855                     ClassDefinition theClass = classDef;
   857                     if (theClass == null) {
   858                         theClass = env.getClassDeclaration(theType).getClassDefinition(env);
   859                     }
   861                                 // Is it an interface or a class?
   863                     if (theClass.isInterface()) {
   865                         // An interface. Is it a special case?
   867                         result = SpecialInterfaceType.forSpecial(theClass,stack);
   869                         if (result == null) {
   871                             // No, does it implement java.rmi.Remote?
   873                             if (env.defRemote.implementedBy(env,theClass.getClassDeclaration())) {
   875                                 // Yep, so just see if we can create an instance of RemoteType
   876                                 // from it...
   878                                 boolean parentIsValue = stack.isParentAValue();
   879                                 result = RemoteType.forRemote(theClass,stack,parentIsValue);
   881                                 // If we did not succeed AND we are in a value context, then
   882                                 // go ahead and make an NC type out of it...
   884                                 if (result == null && parentIsValue) {
   885                                     result = NCInterfaceType.forNCInterface(theClass,stack);
   886                                 }
   887                             } else {
   889                                 // Nope, is it an AbstractType?
   891                                 result = AbstractType.forAbstract(theClass,stack,true);
   893                                 if (result == null) {
   895                                     // No, so treat it as a non-conforming interface type...
   897                                     result = NCInterfaceType.forNCInterface(theClass,stack);
   898                                 }
   899                             }
   900                         }
   901                     } else {
   903                         // A class. Is it a special case?
   905                         result = SpecialClassType.forSpecial(theClass,stack);
   907                         if (result == null) {
   909                             ClassDeclaration classDecl = theClass.getClassDeclaration();
   911                             // Nope, does it implement java.rmi.Remote?
   913                             if (env.defRemote.implementedBy(env,classDecl)) {
   915                                 // Yep, so just see if we can create an instance of
   916                                 // ImplementationType from it...
   918                                 boolean parentIsValue = stack.isParentAValue();
   919                                 result = ImplementationType.forImplementation(theClass,stack,parentIsValue);
   921                                 // If we did not succeed AND inValue is true, then
   922                                 // go ahead and make an NC type out of it...
   924                                 if (result == null && parentIsValue) {
   925                                     result = NCClassType.forNCClass(theClass,stack);
   926                                 }
   927                             } else {
   929                                 // No, does it implement Serializable?
   931                                 if (env.defSerializable.implementedBy(env,classDecl)) {
   933                                     // Yep, so just see if we can create an instance of ValueType
   934                                     // from it...
   936                                     result = ValueType.forValue(theClass,stack,true);
   937                                 }
   939                                 if (result == null) {
   941                                     // Treat it as a non-conforming class type...
   943                                     result = NCClassType.forNCClass(theClass,stack);
   944                                 }
   945                             }
   946                         }
   947                     }
   948                 } catch (ClassNotFound e) {
   949                     classNotFound(stack,e);
   950                 }
   951                 break;
   952             }
   954         default: throw new CompilerError("Unknown typecode (" + typeCode + ") for " + theType.getTypeSignature());
   955         }
   957         return result;
   958     }
   960     /*
   961      * Check if exception is RemoteException or one of its parents.
   962      */
   963     public static boolean isRemoteException (ClassType ex,
   964                                              BatchEnvironment env) {
   965         sun.tools.java.Type exceptionType = ex.getClassDeclaration().getType();
   967         if (exceptionType.equals(env.typeRemoteException) ||
   968             exceptionType.equals(env.typeIOException) ||
   969             exceptionType.equals(env.typeException) ||
   970             exceptionType.equals(env.typeThrowable)) {
   972             return true;
   973         }
   974         return false;
   975     }
   977     /*
   978      * Check if method is conforming.
   979      */
   980     protected boolean isConformingRemoteMethod (Method method, boolean quiet)
   981         throws ClassNotFound {
   983         // Do we have one exception that is RemoteException or
   984         // a superclass of RemoteException?
   986         boolean haveRemote = false;
   987         ClassType[] exceptions = method.getExceptions();
   989         for (int i = 0; i < exceptions.length; i++) {
   991             // Is it a conforming exception?
   993             if (isRemoteException(exceptions[i],env)) {
   995                 // Got it.
   997                 haveRemote = true;
   998                 break;
   999             }
  1002         // Do we have our exception?
  1004         if (!haveRemote) {
  1006             // No, so report failure...
  1008             failedConstraint(5,quiet,stack,method.getEnclosing(), method.toString());
  1011         // Are any of the arguments exceptions which implement IDLEntity?
  1012         // If so, report failure...
  1014         boolean noIDLEntity = !isIDLEntityException(method.getReturnType(),method,quiet);
  1015         if (noIDLEntity) {
  1016             Type[] args = method.getArguments();
  1017             for (int i = 0; i < args.length; i++) {
  1018                 if (isIDLEntityException(args[i],method,quiet)) {
  1019                     noIDLEntity = false;
  1020                     break;
  1025         return (haveRemote && noIDLEntity);
  1028     protected boolean isIDLEntityException(Type type, CompoundType.Method method,boolean quiet)
  1029         throws ClassNotFound {
  1030         if (type.isArray()) {
  1031             type = type.getElementType();
  1033         if (type.isCompound()){
  1034             if (((CompoundType)type).isIDLEntityException()) {
  1035                 failedConstraint(18,quiet,stack,method.getEnclosing(), method.toString());
  1036                 return true;
  1039         return false;
  1042     /**
  1043      * Convert all invalid types to valid ones.
  1044      */
  1045     protected void swapInvalidTypes () {
  1047         // Walk all interfaces and check them...
  1049         for (int i = 0; i < interfaces.length; i++) {
  1050             if (interfaces[i].getStatus() != STATUS_VALID) {
  1051                 interfaces[i] = (InterfaceType)getValidType(interfaces[i]);
  1055         // Update methods...
  1057         for (int i = 0; i < methods.length; i++) {
  1058             methods[i].swapInvalidTypes();
  1061         // Update members...
  1063         for (int i = 0; i < members.length; i++) {
  1064             members[i].swapInvalidTypes();
  1068     /*
  1069      * Add matching types to list. Return true if this type has not
  1070      * been previously checked, false otherwise.
  1071      */
  1072     protected boolean addTypes (int typeCodeFilter,
  1073                                 HashSet checked,
  1074                                 Vector matching) {
  1076         // Check self.
  1078         boolean result = super.addTypes(typeCodeFilter,checked,matching);
  1080         // Have we been checked before?
  1082         if (result) {
  1084             // Nope, so walk parent(s) and check them...
  1086             ClassType parent = getSuperclass();
  1088             if (parent != null) {
  1089                 parent.addTypes(typeCodeFilter,checked,matching);
  1092             // Walk all interfaces and check them...
  1094             //if (interfaces == null) System.out.println("NULL for " +getQualifiedName() + " interfaces");
  1095             for (int i = 0; i < interfaces.length; i++) {
  1097                 // Now recurse and add it and any referenced types...
  1099                 //if (interfaces[i] == null) System.out.println("NULL for " +getQualifiedName() + " interfaces[" + i + "]");
  1100                 interfaces[i].addTypes(typeCodeFilter,checked,matching);
  1103             // Walk all methods and check arguments...
  1105             //if (methods == null) System.out.println("NULL for " +getQualifiedName() + " methods");
  1106             for (int i = 0; i < methods.length; i++) {
  1108                 // Add return type...
  1109                 //if (methods[i] == null) System.out.println("NULL for " +getQualifiedName() + " methods[" + i + "]");
  1110                 //if (methods[i].getReturnType() == null) System.out.println("NULL for " +getQualifiedName() + methods[i]);
  1111                 methods[i].getReturnType().addTypes(typeCodeFilter,checked,matching);
  1113                 // Add args...
  1115                 Type[] args = methods[i].getArguments();
  1116                 //if (args == null) System.out.println("NULL for " + getQualifiedName() + " args");
  1118                 for (int j = 0; j < args.length; j++) {
  1120                     Type arg = args[j];
  1121                     //if (arg == null) System.out.println("NULL for " + getQualifiedName() + " arg[" +j+"]");
  1123                                 // Add argument...
  1125                     arg.addTypes(typeCodeFilter,checked,matching);
  1128                 // Add exceptions...
  1130                 ClassType[] exceptions = methods[i].getExceptions();
  1131                 //if (exceptions == null) System.out.println("NULL for " + getQualifiedName() + " exceptions");
  1133                 for (int j = 0; j < exceptions.length; j++) {
  1135                     ClassType ex = exceptions[j];
  1137                                 // Add argument...
  1139                     ex.addTypes(typeCodeFilter,checked,matching);
  1143             // Walk all members and add em...
  1145             //if (members == null) System.out.println("NULL for " +getQualifiedName() + " members");
  1146             for (int i = 0; i < members.length; i++) {
  1147                 //if (members[i] == null) System.out.println("NULL for " +getQualifiedName() + " members[" + i + "]");
  1148                 Type cType = members[i].getType();
  1149                 //if (cType == null) System.out.println("NULL for " + getQualifiedName() + " cType");
  1151                 // Add it...
  1153                 cType.addTypes(typeCodeFilter,checked,matching);
  1157         return result;
  1160     /*
  1161      * Return true if theType is a conforming constant type.
  1162      */
  1163     private boolean isConformingConstantType (MemberDefinition member) {
  1164         return isConformingConstantType(member.getType(),member);
  1167     /*
  1168      * Return true if theType is a conforming constant type.
  1169      */
  1170     private boolean isConformingConstantType (sun.tools.java.Type theType,MemberDefinition member) {
  1172         // Constraint 3:    Constants must be either primitives or String.
  1174         boolean result = true;
  1175         int typeCode = theType.getTypeCode();
  1176         switch (typeCode) {
  1177         case TC_BOOLEAN:
  1178         case TC_BYTE:
  1179         case TC_CHAR:
  1180         case TC_SHORT:
  1181         case TC_INT:
  1182         case TC_LONG:
  1183         case TC_FLOAT:
  1184         case TC_DOUBLE: // Primitive, so OK...
  1186                 break;
  1189         case TC_CLASS:  // Must be java.lang.String
  1191                 if (theType.getClassName() != idJavaLangString) {
  1192                     failedConstraint(3,false,stack,member.getClassDefinition(),member.getName());
  1193                     result = false;
  1195                 break;
  1198         case TC_ARRAY: // Array constants are not allowed.
  1200                 failedConstraint(3,false,stack,member.getClassDefinition(),member.getName());
  1201                 result = false;
  1202                 break;
  1205         default:
  1206             throw new Error("unexpected type code: " + typeCode);
  1209         return result;
  1213     /*
  1214      * Update any method from 'currentMethods' which is defined in a
  1215      * parent class so that it's 'declaredBy' field specifies the
  1216      * parent.
  1217      * @param current The class or interface to gather methods from.
  1218      * @param currentMethods The list into which to put the methods.
  1219      *  for contraint 6.
  1220      * @param quiet true if silent errors.
  1221      * @param stack the context stack.
  1222      * @return currentMethods or null if failed a constraint check.
  1223      */
  1224     protected Vector updateParentClassMethods(ClassDefinition current,
  1225                                               Vector currentMethods,
  1226                                               boolean quiet,
  1227                                               ContextStack stack)
  1228         throws ClassNotFound {
  1230         ClassDeclaration parentDecl = current.getSuperClass(env);
  1232         while (parentDecl != null) {
  1234             ClassDefinition parentDef = parentDecl.getClassDefinition(env);
  1235             Identifier currentID = parentDecl.getName();
  1237             if ( currentID == idJavaLangObject ) break;
  1239             // Walk all members of this class and update any that
  1240             // already exist in currentMethods...
  1242             for (MemberDefinition member = parentDef.getFirstMember();
  1243                  member != null;
  1244                  member = member.getNextMember()) {
  1246                 if (member.isMethod() &&
  1247                     !member.isInitializer() &&
  1248                     !member.isConstructor() &&
  1249                     !member.isPrivate()) {
  1251                     // It's a method.  Is it valid?
  1253                     Method method;
  1254                     try {
  1255                         method = new Method((CompoundType)this,member,quiet,stack);
  1256                     } catch (Exception e) {
  1257                         // Don't report anything here, it's already been reported...
  1258                         return null;
  1261                     // Have we already seen it?
  1263                     int index = currentMethods.indexOf(method);
  1264                     if (index >= 0) {
  1266                         // Yes, so update it...
  1268                         Method currentMethod = (Method)currentMethods.elementAt(index);
  1269                         currentMethod.setDeclaredBy(currentID);
  1271                     else currentMethods.addElement(method);
  1275             // Update parent and keep walking up the chain...
  1277             parentDecl = parentDef.getSuperClass(env);
  1280         return currentMethods;
  1283     /*
  1284      * Add all of the public and protected methods defined in
  1285      * current (other than initializers) to allMethods. If a sub-interface
  1286      * re-declares an inherited method, it will not be added.
  1287      * @param current The class or interface to gather methods from.
  1288      * @param directMethods The list into which to put the methods.
  1289      * @param noMultiInheritedMethods A flag to enable/disable checking
  1290      *  for contraint 6.
  1291      * @param quiet true if silent errors.
  1292      * @param stack the context stack.
  1293      * @return directMethods or null if failed a constraint check.
  1294      */
  1295     protected Vector addAllMethods (ClassDefinition current, Vector directMethods,
  1296                                     boolean noMultiInheritedMethods,
  1297                                     boolean quiet,
  1298                                     ContextStack stack)
  1299         throws ClassNotFound {
  1301         // Constraint 6:    Multiple inherited interfaces may not
  1302         //                  declare the same method.
  1304         ClassDeclaration[] interfaces = current.getInterfaces();
  1306         // We want to add members starting at the _least_ derived
  1307         // interfaces.  To do so, recurse until we have no more
  1308         // interfaces...
  1310         for (int i = 0; i < interfaces.length; i++) {
  1312             Vector result = addAllMethods(interfaces[i].getClassDefinition(env),
  1313                                           directMethods,
  1314                                           noMultiInheritedMethods,quiet,stack);
  1315             if (result == null) {
  1316                 return null;
  1320         // Walk all members of this interface, adding any unique methods
  1321         // other than initializers and private methods...
  1323         for (MemberDefinition member = current.getFirstMember();
  1324              member != null;
  1325              member = member.getNextMember())
  1327                 if (member.isMethod() &&
  1328                     !member.isInitializer() &&
  1329                     !member.isPrivate()) {
  1331                     // It's a method.  Is it valid?
  1333                     Method method;
  1334                     try {
  1335                         method = new Method((CompoundType)this,member,quiet,stack);
  1336                     } catch (Exception e) {
  1337                         // Don't report anything here, it's already been reported...
  1338                         return null;
  1341                                 // Have we already seen it?
  1343                     if (!directMethods.contains(method)) {
  1345                         // Nope, so add it...
  1347                         directMethods.addElement(method);
  1349                     } else {
  1351                         // Yes. This is an error unless we are looking at the
  1352                         // target interface (or this is a ValueType). Are we?
  1354                         if (noMultiInheritedMethods && current != classDef  &&
  1355                             !stack.isParentAValue() && !stack.getContext().isValue()) {
  1357                             // Nope. Say so and signal error by returning null..
  1359                             Method existingMethod = (Method) directMethods.elementAt(directMethods.indexOf(method));
  1360                             ClassDefinition existingMemberClassDef = existingMethod.getMemberDefinition().getClassDefinition();
  1362                             // There are more legal cases to consider here.
  1363                             // If the two methods belong to interfaces that inherit from each other
  1364                             // then it is just a redefinition which is legal.
  1365                             if ( current != existingMemberClassDef &&
  1366                                  ! inheritsFrom(current, existingMemberClassDef) &&
  1367                                  ! inheritsFrom(existingMemberClassDef, current))
  1369                                 //Identifier int1 = existingMethod.getEnclosing().getIdentifier();
  1370                                 //Identifier int2 = current.getName();
  1371                                 //String message = int1.toString() + " and " + int2.toString();
  1372                                 String message = existingMemberClassDef.getName() + " and " + current.getName();
  1373                                 failedConstraint(6,quiet,stack,classDef,message,method);
  1374                                 return null;
  1378                         // Bug fix 5014329
  1380                         // find a matching method.
  1381                         int index = directMethods.indexOf(method);
  1382                         Method other = (Method) directMethods.get(index);
  1384                         // merge the two methods, such that the new method
  1385                         // will contain only those exception that can be thrown
  1386                         // by both these methods, not just one of them.
  1387                         Method newMethod = method.mergeWith(other);
  1389                         // replace the old method with the new.
  1390                         directMethods.set(index, newMethod);
  1395         return directMethods;
  1398     // This should really be a method on ClassDefinition, but it takes too long to change the shared source.
  1399     // Works for both, classes and interfaces.
  1400     protected boolean inheritsFrom(ClassDefinition def, ClassDefinition otherDef) {
  1401         if (def == otherDef)
  1402             return true;
  1404         ClassDefinition superDef;
  1405         if (def.getSuperClass() != null) {
  1406             superDef = def.getSuperClass().getClassDefinition();
  1407             if (inheritsFrom(superDef, otherDef))
  1408                 return true;
  1411         ClassDeclaration[] interfaces = def.getInterfaces();
  1412         for (int i=0; i<interfaces.length; i++) {
  1413             superDef = interfaces[i].getClassDefinition();
  1414             if (inheritsFrom(superDef, otherDef))
  1415                 return true;
  1417         return false;
  1420     /*
  1421      * Add all of the interfaces implemented directly by current
  1422      * to the list. Returns null if any are non-conforming.
  1423      */
  1424     protected Vector addRemoteInterfaces (Vector list,
  1425                                           boolean allowNonConforming,
  1426                                           ContextStack stack) throws ClassNotFound {
  1428         // Add all the interfaces of current...
  1430         ClassDefinition theInterface = getClassDefinition();
  1431         ClassDeclaration[] interfaces = theInterface.getInterfaces();
  1433         stack.setNewContextCode(ContextStack.IMPLEMENTS);
  1435         for (int i = 0; i < interfaces.length; i++) {
  1437             ClassDefinition def = interfaces[i].getClassDefinition(env);
  1439             // Is it a SpecialInterfaceType...
  1441             InterfaceType it = SpecialInterfaceType.forSpecial(def,stack);;
  1443             if (it == null) {
  1445                 // No, is it Remote?
  1447                 if (env.defRemote.implementedBy(env, interfaces[i])) {
  1449                     // Yes, so it must be a RemoteType.
  1451                     it = RemoteType.forRemote(def,stack,false);
  1453                 } else {
  1455                     // Then try Abstract...
  1457                     it = AbstractType.forAbstract(def,stack,true);
  1459                     if (it == null && allowNonConforming) {
  1461                         // Must be non-conforming...
  1463                         it = NCInterfaceType.forNCInterface(def,stack);
  1468             if (it != null) {
  1469                 list.addElement(it);
  1470             } else {
  1471                 return null;
  1475         return list;
  1478     /*
  1479      * Add all of the interfaces implemented directly by current
  1480      * to the list.
  1481      */
  1482     protected Vector addNonRemoteInterfaces (Vector list,
  1483                                              ContextStack stack) throws ClassNotFound {
  1485         // Add all the interfaces of current...
  1487         ClassDefinition theInterface = getClassDefinition();
  1488         ClassDeclaration[] interfaces = theInterface.getInterfaces();
  1490         stack.setNewContextCode(ContextStack.IMPLEMENTS);
  1492         for (int i = 0; i < interfaces.length; i++) {
  1494             ClassDefinition def = interfaces[i].getClassDefinition(env);
  1496             // First try SpecialInterfaceType...
  1498             InterfaceType it = SpecialInterfaceType.forSpecial(def,stack);
  1500             if (it == null) {
  1502                 // Then try AbstractType...
  1504                 it = AbstractType.forAbstract(def,stack,true);
  1506                 if (it == null) {
  1508                     // Then try NCInterfaceType...
  1510                     it = NCInterfaceType.forNCInterface(def,stack);
  1514             if (it != null) {
  1515                 list.addElement(it);
  1516             } else {
  1517                 return null;
  1521         return list;
  1525     /*
  1526      * Walk self, adding constants and data members.
  1527      * @return true if all conform, false otherwise.
  1528      */
  1529     protected boolean addAllMembers (Vector allMembers,
  1530                                      boolean onlyConformingConstants,   // AND inner classes.
  1531                                      boolean quiet,
  1532                                      ContextStack stack) {
  1534         boolean result = true;
  1536         // Walk all members of this interface...
  1538         for (MemberDefinition member = getClassDefinition().getFirstMember();
  1539              member != null && result;
  1540              member = member.getNextMember())
  1542                 if (!member.isMethod()) {
  1544                     try {
  1545                         String value = null;
  1547                         // Prod it to setValue if it is a constant...
  1549                         member.getValue(env);
  1551                                 // Get the value, if any...
  1553                         Node node = member.getValue();
  1555                         if (node != null) {
  1556                             // We don't want to change the code in CharExpression,
  1557                             // which is shared among tools, to return the right string
  1558                             // in case the type is char, so we treat it special here.
  1559                             if (member.getType().getTypeCode() == TC_CHAR) {
  1560                                 Integer intValue = (Integer)((IntegerExpression)node).getValue();
  1561                                 value = "L'" + String.valueOf((char)intValue.intValue()) + "'";
  1562                             } else {
  1563                                 value = node.toString();
  1567                         // Are we supposed to allow only conforming constants?
  1569                         if (onlyConformingConstants && member.getInnerClass() == null) {
  1571                                 // Yep, so check it...
  1573                             if (value == null || !isConformingConstantType(member)) {
  1574                                 failedConstraint(3,quiet,stack,member.getClassDefinition(),member.getName());
  1575                                 result = false;
  1576                                 break;
  1580                         // Make member and add to list...
  1582                         try {
  1583                             Member newMember = new Member(member,value,stack,this);
  1584                             allMembers.addElement(newMember);
  1585                         } catch (CompilerError e) {
  1586                             result = false;
  1589                     } catch (ClassNotFound e) {
  1590                         classNotFound(stack,e);
  1591                         result = false;
  1596         return result;
  1598     /*
  1599      * Walk self, adding constants.
  1600      * @return true if all conform, false otherwise.
  1601      */
  1602     protected boolean addConformingConstants (Vector allMembers,
  1603                                               boolean quiet,
  1604                                               ContextStack stack) {
  1606         boolean result = true;
  1608         // Walk all members of this interface...
  1610         for (MemberDefinition member = getClassDefinition().getFirstMember();
  1611              member != null && result;
  1612              member = member.getNextMember())
  1614                 if (!member.isMethod()) {
  1616                     try {
  1617                         String value = null;
  1619                         // Prod it to setValue if it is a constant...
  1621                         member.getValue(env);
  1623                                 // Get the value, if any...
  1625                         Node node = member.getValue();
  1627                         if (node != null) {
  1628                             value = node.toString();
  1632                         // Is it a constant?
  1634                         if (value != null) {
  1636                             // Yes, is it conforming?
  1638                             if (!isConformingConstantType(member)) {
  1639                                 failedConstraint(3,quiet,stack,member.getClassDefinition(),member.getName());
  1640                                 result = false;
  1641                                 break;
  1644                             // Yes, so make a member and add to list...
  1646                             try {
  1647                                 Member newMember = new Member(member,value,stack,this);
  1648                                 allMembers.addElement(newMember);
  1649                             } catch (CompilerError e) {
  1650                                 result = false;
  1653                     } catch (ClassNotFound e) {
  1654                         classNotFound(stack,e);
  1655                         result = false;
  1660         return result;
  1663     protected ValueType[] getMethodExceptions (MemberDefinition member,
  1664                                                boolean quiet,
  1665                                                ContextStack stack) throws Exception {
  1667         boolean result = true;
  1668         stack.setNewContextCode(ContextStack.METHOD_EXCEPTION);
  1669         ClassDeclaration[] except = member.getExceptions(env);
  1670         ValueType[] exceptions = new ValueType[except.length];
  1672         try {
  1673             for (int i = 0; i < except.length; i++) {
  1674                 ClassDefinition theClass = except[i].getClassDefinition(env);
  1675                 try {
  1676                     ValueType type = ValueType.forValue(theClass,stack,false);
  1677                     if (type != null) {
  1678                             exceptions[i] = type;
  1679                         } else {
  1680                             result = false;
  1682                 } catch (ClassCastException e1) {
  1683                     failedConstraint(22,quiet,stack,getQualifiedName());
  1684                     throw new CompilerError("Method: exception " + theClass.getName() + " not a class type!");
  1685                 } catch (NullPointerException e2) {
  1686                     failedConstraint(23,quiet,stack,getQualifiedName());
  1687                     throw new CompilerError("Method: caught null pointer exception");
  1690         } catch (ClassNotFound e) {
  1691             classNotFound(quiet,stack,e);
  1692             result = false;
  1695         if (!result) {
  1696             throw new Exception();
  1699         // Remove any duplicates (javac seems to allow them, but rmic will
  1700         // generate bad ties)...
  1702         int dupCount = 0;
  1703         for (int i = 0; i < exceptions.length; i++) {
  1704             for (int j = 0; j < exceptions.length; j++) {
  1705                 if (i != j && exceptions[i] != null && exceptions[i] == exceptions[j]) {
  1706                     exceptions[j] = null;
  1707                     dupCount++;
  1711         if (dupCount > 0) {
  1712             int offset = 0;
  1713             ValueType[] temp = new ValueType[exceptions.length - dupCount];
  1714             for (int i = 0; i < exceptions.length; i++) {
  1715                 if (exceptions[i] != null) {
  1716                     temp[offset++] = exceptions[i];
  1719             exceptions = temp;
  1722         return exceptions;
  1726     protected static String getVisibilityString (MemberDefinition member) {
  1727         String vis = "";
  1728         String prefix = "";
  1730         if (member.isPublic()) {
  1731             vis += "public";
  1732             prefix = " ";
  1733         } else if (member.isProtected()) {
  1734             vis += "protected";
  1735             prefix = " ";
  1736         } else if (member.isPrivate()) {
  1737             vis += "private";
  1738             prefix = " ";
  1741         if (member.isStatic()) {
  1742             vis += prefix;
  1743             vis += "static";
  1744             prefix = " ";
  1747         if (member.isFinal()) {
  1748             vis += prefix;
  1749             vis += "final";
  1750             prefix = " ";
  1753         return vis;
  1756     protected boolean assertNotImpl(Type type,
  1757                                     boolean quiet,
  1758                                     ContextStack stack,
  1759                                     CompoundType enclosing,
  1760                                     boolean dataMember) {
  1762         if (type.isType(TYPE_IMPLEMENTATION)) {
  1763             int constraint = dataMember ? 28 : 21;
  1764             failedConstraint(constraint,quiet,stack,type,enclosing.getName());
  1765             return false;
  1767         return true;
  1770     //_____________________________________________________________________
  1771     // Inner Class "Method"
  1772     //_____________________________________________________________________
  1774     /**
  1775      * A CompoundType.Method object encapsulates IIOP-specific information
  1776      * about a particular method in the interface represented by the outer
  1777      * instance.
  1778      */
  1779     public class Method implements ContextElement, Cloneable {
  1781         /**
  1782          * Is this method inherited?
  1783          */
  1784         public boolean isInherited () {
  1785             return declaredBy != enclosing.getIdentifier();
  1788         /**
  1789          * Is this method an attribute?
  1790          * Return true if getAttributeKind != ATTRIBUTE_NONE.
  1791          */
  1792         public boolean isAttribute () {
  1793             return attributeKind != ATTRIBUTE_NONE;
  1796         /**
  1797          * Is this method a read-write attribute?
  1798          */
  1799         public boolean isReadWriteAttribute () {
  1800             return attributeKind == ATTRIBUTE_IS_RW ||
  1801                 attributeKind == ATTRIBUTE_GET_RW;
  1804         /**
  1805          * Return the attribute kind.
  1806          */
  1807         public int getAttributeKind() {
  1808             return attributeKind;
  1811         /**
  1812          * Return the attribute name. Will be null if
  1813          * attribute kind == ATTRIBUTE_NONE.
  1814          */
  1815         public String getAttributeName() {
  1816             return attributeName;
  1819         /**
  1820          * For kinds ATTRIBUTE_GET_RW or ATTRIBUTE_IS_RW, return
  1821          * the index of the matching ATTRIBUTE_SET method, and
  1822          * vice-versa. For all other cases, return -1.
  1823          */
  1824         public int getAttributePairIndex() {
  1825             return attributePairIndex;
  1828         /**
  1829          * Return context element name.
  1830          */
  1831         public String getElementName() {
  1832             return memberDef.toString();
  1835         /**
  1836          * Equality check based on method signature.
  1837          */
  1838         public boolean equals(Object obj) {
  1839             Method other = (Method) obj;
  1841             if (getName().equals(other.getName()) &&
  1842                 arguments.length == other.arguments.length) {
  1844                 for (int i = 0; i < arguments.length; i++) {
  1845                     if (! arguments[i].equals(other.arguments[i])) {
  1846                         return false;
  1849                 return true;
  1851             return false;
  1854         /**
  1855          * Return a new Method object that is a legal combination of
  1856          * this method object and another one.
  1858          * This requires determining the exceptions declared by the
  1859          * combined method, which must be only those exceptions
  1860          * that may thrown by both of the old methods.
  1861          */
  1862         public Method mergeWith(Method other) {
  1863             if (!equals(other)) {
  1864                 env.error(0, "attempt to merge method failed:", getName(),
  1865                           enclosing.getClassDefinition().getName());
  1868             Vector legalExceptions = new Vector();
  1869             try {
  1870                 collectCompatibleExceptions(
  1871                       other.exceptions, exceptions, legalExceptions);
  1872                 collectCompatibleExceptions(
  1873                       exceptions, other.exceptions, legalExceptions);
  1874             } catch (ClassNotFound e) {
  1875                 env.error(0, "class.not.found", e.name,
  1876                           enclosing.getClassDefinition().getName());
  1877                 return null;
  1880             Method merged = (Method) clone();
  1881             merged.exceptions = new ValueType[legalExceptions.size()];
  1882             legalExceptions.copyInto(merged.exceptions);
  1883             merged.implExceptions = merged.exceptions;
  1885             return merged;
  1888         /**
  1889          * Add to the supplied list all exceptions in the "from" array
  1890          * that are subclasses of an exception in the "with" array.
  1891          */
  1892         private void collectCompatibleExceptions(
  1893                 ValueType[] from, ValueType[] with, Vector list)
  1894                 throws ClassNotFound {
  1896             for (int i = 0; i < from.length; i++) {
  1897                 ClassDefinition exceptionDef = from[i].getClassDefinition();
  1898                 if (!list.contains(from[i])) {
  1899                     for (int j = 0; j < with.length; j++) {
  1900                         if (exceptionDef.subClassOf(
  1901                                 enclosing.getEnv(),
  1902                                 with[j].getClassDeclaration())) {
  1903                             list.addElement(from[i]);
  1904                             break;
  1911         /**
  1912          * Return the compound type which contains this method.
  1913          */
  1914         public CompoundType getEnclosing() {
  1915             return enclosing;
  1918         /**
  1919          * Return the identifier for the class or interface which
  1920          * declares this method.
  1921          */
  1922         public Identifier getDeclaredBy() {
  1923             return declaredBy;
  1926         /**
  1927          * Return the visibility (e.g. "public final") of this member.
  1928          */
  1929         public String getVisibility() {
  1930             return vis;
  1933         /**
  1934          * Methods to check various attributes.
  1935          */
  1936         public boolean isPublic() {
  1937             return memberDef.isPublic();
  1940         public boolean isProtected() {
  1941             return memberDef.isPrivate();
  1944         public boolean isPrivate() {
  1945             return memberDef.isPrivate();
  1948         public boolean isStatic() {
  1949             return memberDef.isStatic();
  1952         /**
  1953          * Return the name of this method.
  1954          */
  1955         public String getName() {
  1956             return name;
  1959         /**
  1960          * IDL_Naming
  1961          * Return the IDL name of this method.
  1962          */
  1963         public String getIDLName() {
  1964             return idlName;
  1967         /**
  1968          * Return the type of this method.
  1969          */
  1970         public sun.tools.java.Type getType() {
  1971             return memberDef.getType();
  1974         /**
  1975          * Return true if this is a constructor.
  1976          */
  1977         public boolean isConstructor () {
  1978             return memberDef.isConstructor();
  1981         /**
  1982          * Return true if this is NOT a constructor && is not
  1983          * an attribute.
  1984          */
  1985         public boolean isNormalMethod () {
  1986             return (!memberDef.isConstructor()) && attributeKind == ATTRIBUTE_NONE;
  1989         /**
  1990          * Get the return type of this method. May be null.
  1991          */
  1992         public Type getReturnType() {
  1993             return returnType;
  1996         /**
  1997          * Return the argument types of this method.
  1998          */
  1999         public Type[] getArguments() {
  2000             return (Type[]) arguments.clone();
  2003         /**
  2004          * Return the names of the argument types of this method.
  2005          */
  2006         public String[] getArgumentNames() {
  2007             return argumentNames;
  2010         /**
  2011          * Return the MemberDefinition from which this method was created.
  2012          */
  2013         public MemberDefinition getMemberDefinition() {
  2014             return memberDef;
  2017         /**
  2018          * Return an array of the exception classes declared to be
  2019          * thrown by this remote method.
  2021          * For methods with the same name and type signature inherited
  2022          * from multiple remote interfaces, the array will contain
  2023          * the set of exceptions declared in all of the interfaces'
  2024          * methods that can be legally thrown in each of them.
  2025          */
  2026         public ValueType[] getExceptions() {
  2027             return (ValueType[]) exceptions.clone();
  2030         /**
  2031          * Same as getExceptions(), except when method is in an
  2032          * ImplementationType and the exceptions list is narrower.
  2033          */
  2034         public ValueType[] getImplExceptions() {
  2035             return (ValueType[]) implExceptions.clone();
  2038         /**
  2039          * Return an array containing only those exceptions which
  2040          * need to be caught.  Removes java.rmi.RemoteException,
  2041          * java.lang.RuntimeException, java.lang.Error, and their
  2042          * subclasses, then removes any exceptions which are more
  2043          * derived than another in the list. Returns null if no
  2044          * exceptions need to be caught.
  2045          */
  2046         public ValueType[] getUniqueCatchList(ValueType[] list) {
  2047             ValueType[] result = list;
  2048             int newSize = list.length;
  2050             try {
  2052                 // First, remove RemoteException, RuntimeException, Error, and their subclasses...
  2053                 for (int i = 0; i < list.length; i++) {
  2054                     ClassDeclaration decl = list[i].getClassDeclaration();
  2055                     if (env.defRemoteException.superClassOf(env, decl) ||
  2056                         env.defRuntimeException.superClassOf(env, decl) ||
  2057                         env.defError.superClassOf(env, decl)) {
  2058                         list[i] = null;
  2059                         newSize--;
  2063                 // Now remove derived types...
  2064                 for (int i = 0; i < list.length; i++) {
  2065                     if (list[i] != null) {
  2066                         ClassDefinition current = list[i].getClassDefinition();
  2067                         for (int j = 0; j < list.length; j++) {
  2068                             if (j != i && list[i] != null && list[j] != null &&
  2069                                 current.superClassOf(env, list[j].getClassDeclaration())) {
  2070                                 list[j] = null;
  2071                                 newSize--;
  2077             } catch (ClassNotFound e) {
  2078                 classNotFound(stack,e); // Report error but do not stop.
  2081             // Create new list if we removed anything...
  2083             if (newSize < list.length) {
  2084                 ValueType[] temp = new ValueType[newSize];
  2085                 int offset = 0;
  2086                 for (int i = 0; i < list.length; i++) {
  2087                     if (list[i] != null) {
  2088                         temp[offset++] = list[i];
  2091                 list = temp;
  2094             if (list.length == 0) {
  2095                 return null;
  2096             } else {
  2097                 return list;
  2101         /**
  2102          * Return an array containing only those exceptions which need to be
  2103          * handled explicitly by the stub.  Removes java.lang.RuntimeException,
  2104          * java.lang.Error, and their subclasses, since these are all passed
  2105          * back as CORBA system exceptions.  Also removes subclasses of
  2106          * java.rmi.RemoteException but not java.rmi.RemoteException itself,
  2107          * since this may need to be thrown by the stub.
  2108          */
  2109         public ValueType[] getFilteredStubExceptions(ValueType[] list) {
  2110             ValueType[] result = list;
  2111             int newSize = list.length;
  2113             try {
  2115                 for (int i = 0; i < list.length; i++) {
  2116                     ClassDeclaration decl = list[i].getClassDeclaration();
  2117                     if ((env.defRemoteException.superClassOf(env, decl) &&
  2118                          !env.defRemoteException.getClassDeclaration().equals(decl)) ||
  2119                         env.defRuntimeException.superClassOf(env, decl) ||
  2120                         env.defError.superClassOf(env, decl)) {
  2121                         list[i] = null;
  2122                         newSize--;
  2126             } catch (ClassNotFound e) {
  2127                 classNotFound(stack,e); // Report error but do not stop.
  2130             // Create new list if we removed anything...
  2132             if (newSize < list.length) {
  2133                 ValueType[] temp = new ValueType[newSize];
  2134                 int offset = 0;
  2135                 for (int i = 0; i < list.length; i++) {
  2136                     if (list[i] != null) {
  2137                         temp[offset++] = list[i];
  2140                 list = temp;
  2143             return list;
  2146         /**
  2147          * Return the string representation of this method.
  2148          */
  2149         public String toString() {
  2151             if (stringRep == null) {
  2153                 StringBuffer result = new StringBuffer(returnType.toString());
  2155                 // Add name...
  2157                 result.append(" ");
  2158                 result.append(getName());
  2159                 result.append(" (");
  2161                 // Add arguments...
  2163                 for (int i = 0; i < arguments.length; i++) {
  2164                     if (i > 0) {
  2165                         result.append(", ");
  2167                     result.append(arguments[i]);
  2168                     result.append(" ");
  2169                     result.append(argumentNames[i]);
  2172                 result.append(")");
  2174                 // Add exceptions...
  2176                 for (int i = 0; i < exceptions.length; i++) {
  2177                     if (i == 0) {
  2178                         result.append(" throws ");
  2179                     } else {
  2180                         result.append(", ");
  2182                     result.append(exceptions[i]);
  2185                 result.append(";");
  2187                 stringRep = result.toString();
  2190             return stringRep;
  2194         /**
  2195          * Set attribute kind. May only be called during initialization.
  2196          */
  2197         public void setAttributeKind(int kind) {
  2198             attributeKind = kind;
  2201         /**
  2202          * Set pair index. May only be called during initialization.
  2203          */
  2204         public void setAttributePairIndex(int index) {
  2205             attributePairIndex = index;
  2208         /**
  2209          * Set attribute name. May only be called during initialization.
  2210          */
  2211         public void setAttributeName(String name) {
  2212             attributeName = name;
  2215         /**
  2216          * Set the idl name. May only be called during initialization.
  2217          */
  2218         public void setIDLName (String idlName) {
  2219             this.idlName=idlName;
  2222         /**
  2223          * Set the implExceptions array. May only be called during initialization.
  2224          */
  2225         public void setImplExceptions (ValueType[] exceptions) {
  2226             implExceptions = exceptions;
  2229         /**
  2230          * Set the declaredBy Identifier. May only be called during initialization.
  2231          */
  2232         public void setDeclaredBy (Identifier by) {
  2233             declaredBy = by;
  2236         /**
  2237          * Convert all invalid types to valid ones.
  2238          */
  2239         protected void swapInvalidTypes () {
  2241             // Check return type...
  2243             if (returnType.getStatus() != STATUS_VALID) {
  2244                 returnType = getValidType(returnType);
  2247             // Check args...
  2249             for (int i = 0; i < arguments.length; i++) {
  2250                 if (arguments[i].getStatus() != STATUS_VALID) {
  2251                     arguments[i] = getValidType(arguments[i]);
  2255             // Check exceptions...
  2257             for (int i = 0; i < exceptions.length; i++) {
  2258                 if (exceptions[i].getStatus() != STATUS_VALID) {
  2259                     exceptions[i] = (ValueType)getValidType(exceptions[i]);
  2263             // Check implExceptions...
  2265             for (int i = 0; i < implExceptions.length; i++) {
  2266                 if (implExceptions[i].getStatus() != STATUS_VALID) {
  2267                     implExceptions[i] = (ValueType)getValidType(implExceptions[i]);
  2272         /**
  2273          * Release all resources.
  2274          */
  2275         public void destroy () {
  2276             if (memberDef != null) {
  2277                 memberDef = null;
  2278                 enclosing = null;
  2279                 if (exceptions != null) {
  2280                     for (int i = 0; i < exceptions.length; i++) {
  2281                         if (exceptions[i] != null) exceptions[i].destroy();
  2282                         exceptions[i] = null;
  2284                     exceptions = null;
  2287                 if (implExceptions != null) {
  2288                     for (int i = 0; i < implExceptions.length; i++) {
  2289                         if (implExceptions[i] != null) implExceptions[i].destroy();
  2290                         implExceptions[i] = null;
  2292                     implExceptions = null;
  2295                 if (returnType != null) returnType.destroy();
  2296                 returnType = null;
  2298                 if (arguments != null) {
  2299                     for (int i = 0; i < arguments.length; i++) {
  2300                         if (arguments[i] != null) arguments[i].destroy();
  2301                         arguments[i] = null;
  2303                     arguments = null;
  2306                 if (argumentNames != null) {
  2307                     for (int i = 0; i < argumentNames.length; i++) {
  2308                         argumentNames[i] = null;
  2310                     argumentNames = null;
  2313                 vis = null;
  2314                 name = null;
  2315                 idlName = null;
  2316                 stringRep = null;
  2317                 attributeName = null;
  2318                 declaredBy = null;
  2322         private MemberDefinition memberDef;
  2323         private CompoundType enclosing;
  2324         private ValueType[] exceptions;
  2325         private ValueType[] implExceptions;
  2326         private Type returnType;
  2327         private Type[] arguments;
  2328         private String[] argumentNames;
  2329         private String vis;
  2330         private String name;
  2331         private String idlName;
  2332         private String stringRep = null;
  2333         private int attributeKind = ATTRIBUTE_NONE;
  2334         private String attributeName = null;
  2335         private int attributePairIndex = -1;
  2336         private Identifier declaredBy = null;
  2338         /**
  2339          * Make up an argument name for the given type.
  2340          */
  2341         private String makeArgName (int argNum, Type type) {
  2342             return "arg" + argNum;
  2345         /**
  2346          * Create a new Method object corresponding to the given
  2347          * method definition.
  2348          */
  2349         public Method (CompoundType enclosing,
  2350                        MemberDefinition memberDef,
  2351                        boolean quiet,
  2352                        ContextStack stack) throws Exception {
  2354             this.enclosing = enclosing;
  2355             this.memberDef = memberDef;
  2356             vis = getVisibilityString(memberDef);
  2357             idlName = null; // See setIDLName()
  2358             boolean valid = true;
  2359             declaredBy = memberDef.getClassDeclaration().getName();
  2361             // Set name...
  2363             name = memberDef.getName().toString();
  2365             // Update the context...
  2367             stack.setNewContextCode(ContextStack.METHOD);
  2368             stack.push(this);
  2370             // Set return type...
  2372             stack.setNewContextCode(ContextStack.METHOD_RETURN);
  2373             sun.tools.java.Type methodType = memberDef.getType();
  2374             sun.tools.java.Type rtnType = methodType.getReturnType();
  2376             if (rtnType == sun.tools.java.Type.tVoid) {
  2377                 returnType = PrimitiveType.forPrimitive(rtnType,stack);
  2378             } else {
  2379                 returnType = makeType(rtnType,null,stack);
  2380                 if (returnType == null ||
  2381                     !assertNotImpl(returnType,quiet,stack,enclosing,false)) {
  2382                     valid = false;
  2383                     failedConstraint(24,quiet,stack,enclosing.getName());
  2387             // Set arguments and argument names...
  2389             stack.setNewContextCode(ContextStack.METHOD_ARGUMENT);
  2390             sun.tools.java.Type[] args = memberDef.getType().getArgumentTypes();
  2391             arguments = new Type[args.length];
  2392             argumentNames = new String[args.length];
  2393             Vector origArgNames = memberDef.getArguments();
  2395             for (int i = 0; i < args.length; i++) {
  2396                 Type type = null;
  2397                 try {
  2398                     type = makeType(args[i],null,stack);
  2399                 } catch (Exception e) {
  2402                 if (type != null) {
  2403                     if (!assertNotImpl(type,quiet,stack,enclosing,false)) {
  2404                         valid = false;
  2405                     } else {
  2406                     arguments[i] = type;
  2407                     if (origArgNames != null) {
  2408                         LocalMember local = (LocalMember)origArgNames.elementAt(i+1);
  2409                         argumentNames[i] = local.getName().toString();
  2410                     } else {
  2411                         argumentNames[i] = makeArgName(i,type);
  2414                 } else {
  2415                     valid = false;
  2416                     failedConstraint(25,false,stack,enclosing.getQualifiedName(),name);
  2420             if (!valid) {
  2421                 stack.pop(false);
  2422                 throw new Exception();
  2425             // Set exceptions...
  2427             try {
  2428                 exceptions = enclosing.getMethodExceptions(memberDef,quiet,stack);
  2429                 implExceptions = exceptions;
  2430                 stack.pop(true);
  2431             } catch (Exception e) {
  2432                 stack.pop(false);
  2433                 throw new Exception();
  2437         /**
  2438          * Cloning is supported by returning a shallow copy of this object.
  2439          */
  2440         protected Object clone() {
  2441             try {
  2442                 return super.clone();
  2443             } catch (CloneNotSupportedException e) {
  2444                 throw new Error("clone failed");
  2449     //_____________________________________________________________________
  2450     // Inner Class "Member"
  2451     //_____________________________________________________________________
  2453     /**
  2454      * An CompoundType.Member object wraps a Type and a value representing
  2455      * a data member, including constants.
  2456      */
  2457     public class Member implements ContextElement, Cloneable {
  2459         /**
  2460          * Return context element name.
  2461          */
  2462         public String getElementName() {
  2463             return "\"" + getName() + "\"";
  2466         /**
  2467          * Return the type of this member.
  2468          */
  2469         public Type getType() {
  2470             return type;
  2473         /**
  2474          * Return the name of this member.
  2475          */
  2476         public String getName() {
  2477             return name;
  2480         /**
  2481          * IDL_Naming
  2482          * Return the IDL name of this member.
  2483          */
  2484         public String getIDLName() {
  2485             return idlName;
  2488         /**
  2489          * Return the visibility (e.g. "public final") of this member.
  2490          */
  2491         public String getVisibility() {
  2492             return vis;
  2495         /**
  2496          * Methods to check various attributes.
  2497          */
  2498         public boolean isPublic() {
  2499             return member.isPublic();
  2502         public boolean isPrivate() {
  2503             return member.isPrivate();
  2506         public boolean isStatic() {
  2507             return member.isStatic();
  2510         public boolean isFinal() {
  2511             return member.isFinal();
  2514         public boolean isTransient() {
  2515             if (forceTransient) return true;
  2516             return member.isTransient();
  2519         /**
  2520          * Return the value of this member. May be null.
  2521          */
  2522         public String getValue() {
  2523             return value;
  2526         /**
  2527          * Return true if this member represents an inner class declaration,
  2528          * false otherwise.
  2529          */
  2530         public boolean isInnerClassDeclaration() {
  2531             return innerClassDecl;
  2534         /**
  2535          * Return true if this member represents a constant.
  2536          */
  2537         public boolean isConstant () {
  2538             return constant;
  2541         /**
  2542          * Return the string representation of this constant.
  2543          */
  2544         public String toString() {
  2546             String result = type.toString();
  2548             if (value != null) {
  2549                 result += (" = " + value);
  2552             return result;
  2555         /**
  2556          * Convert all invalid types to valid ones.
  2557          */
  2558         protected void swapInvalidTypes () {
  2559             if (type.getStatus() != STATUS_VALID) {
  2560                 type = getValidType(type);
  2564         protected void setTransient() {
  2565             if (! isTransient()) {
  2566                 forceTransient = true;
  2567                 if (vis.length() > 0) {
  2568                     vis = vis + " transient";
  2569                 } else {
  2570                     vis = "transient";
  2575         protected MemberDefinition getMemberDefinition() {
  2576             return member;
  2579         /**
  2580          * Release all resources.
  2581          */
  2582         public void destroy () {
  2583             if (type != null) {
  2584                 type.destroy();
  2585                 type = null;
  2586                 vis = null;
  2587                 value = null;
  2588                 name = null;
  2589                 idlName = null;
  2590                 member = null;
  2594         private Type type;
  2595         private String vis;
  2596         private String value;
  2597         private String name;
  2598         private String idlName;
  2599         private boolean innerClassDecl;
  2600         private boolean constant;
  2601         private MemberDefinition member;
  2602         private boolean forceTransient;
  2604         /**
  2605          * Create a new Member object.
  2606          */
  2607         public Member(MemberDefinition member,
  2608                       String value,
  2609                       ContextStack stack,
  2610                       CompoundType enclosing) {
  2611             this.member = member;
  2612             this.value = value;
  2613             forceTransient = false;
  2614             innerClassDecl = member.getInnerClass() != null;
  2616             // If we are not an inner class, finish initializing now.
  2617             // Otherwise, wait until outer class is finished, then
  2618             // call init to avoid potential recursion problems...
  2620             if (!innerClassDecl) {
  2621                 init (stack,enclosing);
  2625         public void init (ContextStack stack, CompoundType enclosing) {
  2627             constant = false;
  2628             name = member.getName().toString();
  2629             vis = getVisibilityString(member);
  2630             idlName = null;
  2632             // Add self to stack...
  2634             int contextCode = ContextStack.MEMBER;
  2635             stack.setNewContextCode(contextCode);
  2637             // Check for special contextCodes...
  2639             if (member.isVariable()) {
  2640                 if (value != null && member.isConstant()) {
  2641                     contextCode = ContextStack.MEMBER_CONSTANT;
  2642                     this.constant = true;
  2643                 } else if (member.isStatic()) {
  2644                     contextCode = ContextStack.MEMBER_STATIC;
  2645                 } else if (member.isTransient()) {
  2646                     contextCode = ContextStack.MEMBER_TRANSIENT;
  2650             stack.setNewContextCode(contextCode);
  2651             stack.push(this);
  2653             type = makeType(member.getType(),null,stack);
  2655             if (type == null ||
  2656                 (!innerClassDecl &&
  2657                  !member.isStatic() &&
  2658                  !member.isTransient() &&
  2659                  !assertNotImpl(type,false,stack,enclosing,true))) {
  2660                 stack.pop(false);
  2661                 throw new CompilerError("");
  2664             // Clean up primitive constant values...
  2666             if (constant && type.isPrimitive()) {
  2667                 if (type.isType(TYPE_LONG) || type.isType(TYPE_FLOAT) || type.isType(TYPE_DOUBLE)) {
  2668                     int length = value.length();
  2669                     char lastChar = value.charAt(length-1);
  2670                     if (!Character.isDigit(lastChar)) {
  2671                         this.value = value.substring(0,length-1);
  2673                 } else if (type.isType(TYPE_BOOLEAN)) {
  2674                     value = value.toUpperCase();
  2677             if (constant && type.isType(TYPE_STRING)) {
  2678                 value = "L" + value;
  2680             stack.pop(true);
  2683         public void setIDLName (String name) {
  2684             this.idlName = name;
  2687         /**
  2688          * Cloning is supported by returning a shallow copy of this object.
  2689          */
  2690         protected Object clone() {
  2691             try {
  2692                 return super.clone();
  2693             } catch (CloneNotSupportedException e) {
  2694                 throw new Error("clone failed");

mercurial