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

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

author
msheppar
date
Fri, 14 Jun 2013 16:31:55 +0100
changeset 512
81d694b1ab2f
parent 473
5845df371e25
child 553
5ca1b4c282b8
permissions
-rw-r--r--

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

     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.Arrays;
    36 import java.util.Vector;
    37 import sun.tools.java.Identifier;
    38 import sun.tools.java.ClassNotFound;
    39 import sun.tools.java.ClassDefinition;
    40 import sun.tools.java.ClassDeclaration;
    41 import sun.tools.java.MemberDefinition;
    42 import sun.tools.java.CompilerError;
    43 import sun.tools.tree.Node;
    44 import sun.tools.tree.LocalMember;
    45 import sun.tools.tree.CharExpression;
    46 import sun.tools.tree.IntegerExpression;
    47 import sun.rmi.rmic.IndentingWriter;
    48 import java.io.IOException;
    49 import java.util.HashSet;
    50 import java.util.Enumeration;
    51 import java.io.File;
    53 /**
    54  * A CompoundType is an abstract base class for all IIOP class and
    55  * interface types.
    56  *
    57  * @author      Bryan Atsatt
    58  */
    59 public abstract class CompoundType extends Type {
    61     protected Method[] methods;
    62     protected InterfaceType[] interfaces;
    63     protected Member[] members;
    64     protected ClassDefinition classDef;
    65     protected ClassDeclaration classDecl;
    67     protected boolean isCORBAObject = false;
    68     protected boolean isIDLEntity = false;
    69     protected boolean isAbstractBase = false;
    70     protected boolean isValueBase = false;
    71     protected boolean isCORBAUserException = false;
    72     protected boolean isException = false;
    73     protected boolean isCheckedException = false;
    74     protected boolean isRemoteExceptionOrSubclass = false;
    75     protected String idlExceptionName;
    76     protected String qualifiedIDLExceptionName;
    78     //_____________________________________________________________________
    79     // Public Interfaces
    80     //_____________________________________________________________________
    82     /**
    83      * Return true if this type implements
    84      * org.omg.CORBA.Object.
    85      */
    86     public boolean isCORBAObject () {
    87         return isCORBAObject;
    88     }
    90     /**
    91      * Return true if this type implements
    92      * org.omg.CORBA.portable.IDLEntity.
    93      */
    94     public boolean isIDLEntity () {
    95         return isIDLEntity;
    96     }
    98     /**
    99      * Return true if this type implements
   100      * org.omg.CORBA.portable.ValueBase.
   101      */
   102     public boolean isValueBase () {
   103         return isValueBase;
   104     }
   106     /**
   107      * Return true if this type is a CORBA
   108      * abstract interface.
   109      */
   110     public boolean isAbstractBase () {
   111         return isAbstractBase;
   112     }
   114     /**
   115      * Return true if this type is an exception.
   116      */
   117     public boolean isException () {
   118         return isException;
   119     }
   121     /**
   122      * Return true if this type is a "checked" exception.
   123      * Result if valid iff isException() returns true.
   124      */
   125     public boolean isCheckedException () {
   126         return isCheckedException;
   127     }
   129     /**
   130      * Return true if this type is a java.rmi.RemoteException
   131      * or one of its subclasses. Result if valid iff isException()
   132      * returns true.
   133      */
   134     public boolean isRemoteExceptionOrSubclass () {
   135         return isRemoteExceptionOrSubclass;
   136     }
   138     /**
   139      * Return true if this type is exactly
   140      * org.omg.CORBA.UserException.
   141      */
   142     public boolean isCORBAUserException () {
   143         return isCORBAUserException;
   144     }
   146     /**
   147      * Return true if this type implements
   148      * isIDLEntity() && isException().
   149      */
   150     public boolean isIDLEntityException () {
   151         return isIDLEntity() && isException();
   152     }
   153     /**
   154      * Return true if isIDLEntity() && !isValueBase()
   155      * && !isAbstractBase() && !isCORBAObject()
   156      * && !isIDLEntityException().
   157      */
   158     public boolean isBoxed () {
   159         return (isIDLEntity() && !isValueBase() &&
   160                 !isAbstractBase() && !isCORBAObject() &&
   161                 !isIDLEntityException());
   162     }
   164     /**
   165      * If this type represents an exception, return the
   166      * IDL name including the "Ex" mangling, otherwise
   167      * return null.
   168      */
   169     public String getIDLExceptionName () {
   170         return idlExceptionName;
   171     }
   173     /**
   174      * If this type represents an exception, return the
   175      * qualified IDL name including the "Ex" mangling,
   176      * otherwise return null.
   177      * @param global If true, prepends "::".
   178      */
   179     public String getQualifiedIDLExceptionName (boolean global) {
   180         if (qualifiedIDLExceptionName != null &&
   181             global &&
   182             getIDLModuleNames().length > 0) {
   183             return IDL_NAME_SEPARATOR + qualifiedIDLExceptionName;
   184         } else {
   185             return qualifiedIDLExceptionName;
   186         }
   187     }
   189     /**
   190      * Return signature for this type  (e.g. com.acme.Dynamite
   191      * would return "com.acme.Dynamite", byte = "B")
   192      */
   193     public String getSignature() {
   194         String sig = classDecl.getType().getTypeSignature();
   195         if (sig.endsWith(";")) {
   196             sig = sig.substring(0,sig.length()-1);
   197         }
   198         return sig;
   199     }
   201     /**
   202      * Return the ClassDeclaration for this type.
   203      */
   204     public ClassDeclaration getClassDeclaration() {
   205         return classDecl;
   206     }
   208     /**
   209      * Return the ClassDefinition for this type.
   210      */
   211     public ClassDefinition getClassDefinition() {
   212         return classDef;
   213     }
   215     /**
   216      * Return the parent class of this type. Returns null if this
   217      * type is an interface or if there is no parent.
   218      */
   219     public ClassType getSuperclass() {
   220         return null;
   221     }
   223     /**
   224      * Return an array of interfaces directly implemented by this type.
   225      * <p>
   226      * The order of the array returned is arbitrary.
   227      */
   228     public InterfaceType[] getInterfaces() {
   229         if( interfaces != null ) {
   230             return (InterfaceType[]) interfaces.clone();
   231         }
   232         return null;
   233     }
   235     /**
   236      * Return an array of Type.Method objects representing all
   237      * of the methods implemented directly by this type.
   238      */
   239     public Method[] getMethods() {
   240         if( methods != null ) {
   241             return (Method[]) methods.clone();
   242         }
   243         return null;
   244     }
   246     /**
   247      * Return an array of Type.Member objects representing all of
   248      * the data members directly implemented by this interface.
   249      */
   250     public Member[] getMembers() {
   251         if( members != null ) {
   252             return (Member[]) members.clone();
   253         }
   254         return null;
   255     }
   257     /**
   258      * Create a CompoundType object for the given class.
   259      *
   260      * If the class is not a properly formed or if some other error occurs, the
   261      * return value will be null, and errors will have been reported to the
   262      * supplied BatchEnvironment.
   263      */
   264     public static CompoundType forCompound (ClassDefinition classDef,
   265                                             ContextStack stack) {
   266         CompoundType result = null;
   268         try {
   269             result = (CompoundType) makeType(classDef.getType(),classDef,stack);
   270         } catch (ClassCastException e) {}
   272         return result;
   273     }
   276     //_____________________________________________________________________
   277     // Subclass/Internal Interfaces
   278     //_____________________________________________________________________
   280     /**
   281      * Release all resources.
   282      */
   283     protected void destroy () {
   284         if (!destroyed) {
   285             super.destroy();
   287             if (methods != null) {
   288                 for (int i = 0; i < methods.length; i++) {
   289                     if (methods[i] != null) methods[i].destroy();
   290                 }
   291                 methods = null;
   292             }
   294             if (interfaces != null) {
   295                 for (int i = 0; i < interfaces.length; i++) {
   296                     if (interfaces[i] != null) interfaces[i].destroy();
   297                 }
   298                 interfaces = null;
   299             }
   301             if (members != null) {
   302                 for (int i = 0; i < members.length; i++) {
   303                     if (members[i] != null) members[i].destroy();
   304                 }
   305                 members = null;
   306             }
   308             classDef = null;
   309             classDecl = null;
   310         }
   311     }
   313     /*
   314      * Load a Class instance. Return null if fail.
   315      */
   316     protected Class loadClass() {
   318         Class ourClass = null;
   320         // To avoid getting out-of-date Class instances, and
   321         // to ensure that there is an instance, we must compile
   322         // any classes that we've seen and which are not yet
   323         // compiled. We can't just compile this class, 'cuz it
   324         // may have dependencies on classes which have not been
   325         // compiled...
   327         try {
   328             env.getMain().compileAllClasses(env);
   329         } catch (Exception e1) {
   330             for (Enumeration e = env.getClasses() ; e.hasMoreElements() ; ) {
   331                 ClassDeclaration c = (ClassDeclaration)e.nextElement();
   332             }
   333             failedConstraint(26,false,stack,"required classes");
   334             env.flushErrors();
   335         }
   337         // Now try to get the Class...
   338         // The outer try block is there for people who might want to use
   339         // the compiler at run-time of their AS.
   340         // They could set and use their own context class loader for loading
   341         // classes directly.
   342         try {
   343             ClassLoader cl = Thread.currentThread().getContextClassLoader();
   344             ourClass = cl.loadClass(getQualifiedName());
   345         } catch(ClassNotFoundException cfe) {
   347             try {
   348                 ourClass = env.classPathLoader.loadClass(getQualifiedName());
   349             } catch (NullPointerException e) {
   350                 // This should never happen
   351             } catch (ClassNotFoundException e) {
   352                 // Fall through to the next case (which is to look in the
   353                 // output directory for generated files)
   354             }
   355         }
   357         /* This piece of code used to cause the compiler to ignore jar files
   358            on its classpath
   359         try {
   360             ourClass = Util.loadClass(getQualifiedName(),null,null);
   361         } catch (ClassNotFoundException e) {
   362         } catch (LinkageError e) {
   363         }
   364         */
   366         if (ourClass == null) {
   368             // Try one last thing. If the class was compiled into
   369             // a directory that's not in the classpath, the load
   370             // will fail. Let's get the bits off the disk and load
   371             // it directly...
   373             if (env.loader == null) {
   374                 File destDir = env.getMain().getDestinationDir();
   375                 if (destDir == null) {
   376                     destDir = new File(".");
   377                 }
   378                 env.loader = new DirectoryLoader(destDir);
   379             }
   381             try {
   382                 ourClass = env.loader.loadClass(getQualifiedName());
   383             } catch (Exception e) {}
   384         }
   386         return ourClass;
   387     }
   389     // Print "extends XX"
   391     protected boolean printExtends (IndentingWriter writer,
   392                                     boolean useQualifiedNames,
   393                                     boolean useIDLNames,
   394                                     boolean globalIDLNames) throws IOException {
   396         ClassType parent = getSuperclass();
   398         if (parent != null && (!useIDLNames ||
   399                                (!parent.isType(TYPE_ANY) && !parent.isType(TYPE_CORBA_OBJECT)))) {
   400             writer.p(" extends ");
   401             parent.printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   402             return true;
   403         }
   404         return false;
   405     }
   407     // Print "implements XX, YY"
   409     protected void printImplements (IndentingWriter writer,
   410                                     String prefix,
   411                                     boolean useQualifiedNames,
   412                                     boolean useIDLNames,
   413                                     boolean globalIDLNames) throws IOException {
   415         InterfaceType[] interfaces = getInterfaces();
   417         String adjective = " implements";
   419         if (isInterface()) {
   420             adjective = " extends";
   421         }
   423         if (useIDLNames) {
   424             adjective = ":";
   425         }
   427         for (int i = 0; i < interfaces.length; i++) {
   428             if (!useIDLNames || (!interfaces[i].isType(TYPE_ANY) && !interfaces[i].isType(TYPE_CORBA_OBJECT))) {
   429                 if (i == 0) {
   430                     writer.p(prefix + adjective + " ");
   431                 } else {
   432                     writer.p(", ");
   433                 }
   434                 interfaces[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   435             }
   436         }
   437     }
   439     // Print members
   441     protected void printMembers (       IndentingWriter writer,
   442                                         boolean useQualifiedNames,
   443                                         boolean useIDLNames,
   444                                         boolean globalIDLNames) throws IOException {
   446         CompoundType.Member[] members = getMembers();
   448         for (int i = 0; i < members.length; i++) {
   449             if (!members[i].isInnerClassDeclaration()) {
   450                 Type it = members[i].getType();
   451                 String visibility = members[i].getVisibility();
   452                 String name;
   454                 if (useIDLNames) {
   455                     name = members[i].getIDLName();
   456                 } else {
   457                     name = members[i].getName();
   458                 }
   460                 String value = members[i].getValue();
   462                 writer.p(visibility);
   463                 if (visibility.length() > 0) {
   464                     writer.p(" ");
   465                 }
   466                 it.printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   467                 writer.p(" " + name);
   469                 if (value != null) {
   470                     writer.pln(" = " + value + ";");
   471                 } else {
   472                     writer.pln(";");
   473                 }
   474             }
   475         }
   476     }
   478     // Print methods
   480     protected void printMethods (       IndentingWriter writer,
   481                                         boolean useQualifiedNames,
   482                                         boolean useIDLNames,
   483                                         boolean globalIDLNames) throws IOException {
   485         CompoundType.Method[] methods = getMethods();
   487         for (int m = 0; m < methods.length; m++) {
   488             CompoundType.Method theMethod = methods[m];
   489             printMethod(theMethod,writer,useQualifiedNames,useIDLNames,globalIDLNames);
   490         }
   491     }
   493     // Print a method...
   495     protected void printMethod (CompoundType.Method it,
   496                                 IndentingWriter writer,
   497                                 boolean useQualifiedNames,
   498                                 boolean useIDLNames,
   499                                 boolean globalIDLNames) throws IOException {
   502         // Write visibility...
   504         String visibility = it.getVisibility();
   506         writer.p(visibility);
   507         if (visibility.length() > 0) {
   508             writer.p(" ");
   509         }
   511         // Write return type...
   513         it.getReturnType().printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   515         // Write method name...
   517         if (useIDLNames) {
   518             writer.p(" " + it.getIDLName());
   519         } else {
   520             writer.p(" " + it.getName());
   521         }
   523         // Write arguments...
   525         writer.p(" (");
   526         Type[] args = it.getArguments();
   527         String[] argNames = it.getArgumentNames();
   529         for (int i = 0; i < args.length; i++) {
   530             if (i > 0) {
   531                 writer.p(", ");
   532             }
   534             if (useIDLNames) {
   535                 writer.p("in ");
   536             }
   538             args[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   539             writer.p(" " + argNames[i]);
   540         }
   541         writer.p(")");
   543         // Write exceptions...
   545         ClassType[] exceptions;
   547         if (isType(TYPE_IMPLEMENTATION)) {
   548             exceptions = it.getImplExceptions();
   549         } else {
   550             exceptions = it.getExceptions();
   551         }
   553         for (int i = 0; i < exceptions.length; i++) {
   554             if (i == 0) {
   555                 if (useIDLNames) {
   556                     writer.p(" raises (");
   557                 } else {
   558                     writer.p(" throws ");
   559                 }
   560             } else {
   561                 writer.p(", ");
   562             }
   564             if (useIDLNames) {
   565                 if (useQualifiedNames) {
   566                     writer.p(exceptions[i].getQualifiedIDLExceptionName(globalIDLNames));
   567                 } else {
   568                     writer.p(exceptions[i].getIDLExceptionName());
   569                 }
   570                 writer.p(" [a.k.a. ");
   571                 exceptions[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   572                 writer.p("]");
   573             } else {
   574                 exceptions[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
   575             }
   576         }
   578         if (useIDLNames && exceptions.length > 0) {
   579             writer.p(")");
   580         }
   582         if (it.isInherited()) {
   583             writer.p(" // Inherited from ");
   584         writer.p(it.getDeclaredBy());
   585         }
   587         writer.pln(";");
   588     }
   590     /**
   591      * Create a CompoundType instance for the given class. NOTE: This constructor
   592      * is ONLY for SpecialClassType and SpecialInterfaceType.
   593      */
   594     protected CompoundType(ContextStack stack, int typeCode, ClassDefinition classDef) {
   595         super(stack,typeCode);
   596         this.classDef = classDef;
   597         classDecl = classDef.getClassDeclaration();
   598         interfaces = new InterfaceType[0];
   599         methods = new Method[0];
   600         members = new Member[0];
   602         // If we are an inner class/interface, reset the type codes...
   604         if (classDef.isInnerClass()) {
   605             setTypeCode(typeCode | TM_INNER);
   606         }
   608         // Set special flags...
   610         setFlags();
   611     }
   613     private void setFlags() {
   615         try {
   617         // Set our special interface flags...
   619             isCORBAObject = env.defCorbaObject.implementedBy(env,classDecl);
   620             isIDLEntity = env.defIDLEntity.implementedBy(env,classDecl);
   621             isValueBase = env.defValueBase.implementedBy(env,classDecl);
   622             isAbstractBase = isInterface() &&   // Interface, not a class.
   623                              isIDLEntity &&     // Implements IDLEntity.
   624                              !isValueBase &&    // Does not implement ValueBase.
   625                              !isCORBAObject;    // Does not implement org.omg.CORBA.Object;
   626             isCORBAUserException = (classDecl.getName() == idCorbaUserException);
   628             // Is this an exception?
   630             if (env.defThrowable.implementedBy(env, classDecl)) {
   632                 // Yes...
   634                 isException = true;
   636                 // Is it a checked exception?
   638                 if (env.defRuntimeException.implementedBy(env,classDecl) ||
   639                     env.defError.implementedBy(env,classDecl)) {
   640                     isCheckedException = false;
   641                 } else {
   642                     isCheckedException = true;
   643                 }
   645                 // Is it java.rmi.RemoteException or a subclass?
   647                 if (env.defRemoteException.implementedBy(env,classDecl)) {
   648                     isRemoteExceptionOrSubclass = true;
   649                 } else {
   650                     isRemoteExceptionOrSubclass = false;
   651                 }
   652             } else {
   653                 isException = false;
   654             }
   655         } catch (ClassNotFound e) {
   656             classNotFound(stack,e);
   657         }
   658     }
   660     /**
   661      * Create a CompoundType instance for the given class.  The resulting
   662      * object is not yet completely initialized.
   663      */
   664     protected CompoundType(ContextStack stack, ClassDefinition classDef,
   665                            int typeCode) {
   666         super(stack,typeCode);
   667         this.classDef = classDef;
   668         classDecl = classDef.getClassDeclaration();
   670         // If we are an inner class/interface, reset the type codes...
   672         if (classDef.isInnerClass()) {
   673             setTypeCode(typeCode | TM_INNER);
   674         }
   676         // Set special flags...
   678         setFlags();
   680         // Set names...
   682         Identifier id = classDef.getName();
   683         String idlName;
   684         String[] idlModuleNames;
   686         try {
   688             // These can fail if we get case-sensitive name matches...
   690             idlName = IDLNames.getClassOrInterfaceName(id,env);
   691             idlModuleNames = IDLNames.getModuleNames(id,isBoxed(),env);
   693             setNames(id,idlModuleNames,idlName);
   695             // Is this an exception?
   697             if (isException()) {
   699                 // Yes, so set our mangled exception names...
   701                 isException = true;
   702                 idlExceptionName = IDLNames.getExceptionName(getIDLName());
   703                 qualifiedIDLExceptionName =
   704                     IDLNames.getQualifiedName(getIDLModuleNames(),idlExceptionName);
   705             }
   707             // Set interfaces, methods and members...
   709             interfaces = null;          // set in initialize()
   710             methods = null;                     // set in initialize()
   711             members = null;                 // set in initialize()
   713         } catch (Exception e) {
   714             failedConstraint(7,false,stack,id.toString(),e.getMessage());
   715             throw new CompilerError("");
   716         }
   717     }
   719     /**
   720      * Initialize this instance.
   721      */
   722     protected boolean initialize (      Vector directInterfaces,
   723                                         Vector directMethods,
   724                                         Vector directMembers,
   725                                         ContextStack stack,
   726                                         boolean quiet) {
   728         boolean result = true;
   730         // Initialize our arrays...
   732         if (directInterfaces != null && directInterfaces.size() > 0) {
   733             interfaces = new InterfaceType[directInterfaces.size()];
   734             directInterfaces.copyInto(interfaces);
   735         } else {
   736             interfaces = new InterfaceType[0];
   737         }
   739         if (directMethods != null && directMethods.size() > 0) {
   740             methods = new Method[directMethods.size()];
   741             directMethods.copyInto(methods);
   743             // Now set the idl names for each...
   745             try {
   746                 IDLNames.setMethodNames(this, methods,env);
   747             } catch (Exception e) {
   748                 failedConstraint(13,quiet,stack,getQualifiedName(),e.getMessage());
   749                 result = false;
   750             }
   752         } else {
   753             methods = new Method[0];
   754         }
   756         if (directMembers != null && directMembers.size() > 0) {
   757             members = new Member[directMembers.size()];
   758             directMembers.copyInto(members);
   760             // If we have any un-initialized inner classes, now is the time
   761             // to init them...
   763             for (int i = 0; i < members.length; i++) {
   764                 if (members[i].isInnerClassDeclaration()) {
   765                     try {
   766                         members[i].init(stack,this);
   767                     } catch (CompilerError e) {
   768                         return false;
   769                     }
   770                 }
   771             }
   773             // Now set the idl names for each...
   775             try {
   776                 IDLNames.setMemberNames(this, members,methods,env);
   777             } catch (Exception e) {
   778                 int constraint = classDef.isInterface() ? 19 : 20;
   779                 failedConstraint(constraint,quiet,stack,getQualifiedName(),e.getMessage());
   780                 result = false;
   781             }
   783         } else {
   784             members = new Member[0];
   785         }
   787         // Set our repositoryID...
   789         if (result) {
   790             result = setRepositoryID();
   791         }
   793         return result;
   794     }
   796     /*
   797      * Return Type or null if error. classDef may be null.
   798      */
   799     protected static Type makeType (sun.tools.java.Type theType,
   800                                     ClassDefinition classDef,
   801                                     ContextStack stack) {
   803         if (stack.anyErrors()) return null;
   805         // See if we can find this type in the cache.  If so, return it...
   807         String key = theType.toString();
   809         Type result = getType(key,stack);
   811         if (result != null) {
   812             return result;
   813         }
   815         // Gotta try with context...
   817         result = getType(key + stack.getContextCodeString(),stack);
   819         if (result != null) {
   820             return result;
   821         }
   823         // Gotta map it...
   825         BatchEnvironment env = stack.getEnv();
   826         int typeCode = theType.getTypeCode();
   827         switch (typeCode) {
   828         case TC_BOOLEAN:
   829         case TC_BYTE:
   830         case TC_CHAR:
   831         case TC_SHORT:
   832         case TC_INT:
   833         case TC_LONG:
   834         case TC_FLOAT:
   835         case TC_DOUBLE:
   836             {
   837                 // Primitive...
   839                 result = PrimitiveType.forPrimitive(theType,stack);
   840                 break;
   841             }
   843         case TC_ARRAY:
   844             {
   845                 // Array.
   847                 result = ArrayType.forArray(theType,stack);
   848                 break;
   849             }
   851         case TC_CLASS:
   852             {
   853                 try {
   854                                 // First, make sure we have the class definition...
   856                     ClassDefinition theClass = classDef;
   858                     if (theClass == null) {
   859                         theClass = env.getClassDeclaration(theType).getClassDefinition(env);
   860                     }
   862                                 // Is it an interface or a class?
   864                     if (theClass.isInterface()) {
   866                         // An interface. Is it a special case?
   868                         result = SpecialInterfaceType.forSpecial(theClass,stack);
   870                         if (result == null) {
   872                             // No, does it implement java.rmi.Remote?
   874                             if (env.defRemote.implementedBy(env,theClass.getClassDeclaration())) {
   876                                 // Yep, so just see if we can create an instance of RemoteType
   877                                 // from it...
   879                                 boolean parentIsValue = stack.isParentAValue();
   880                                 result = RemoteType.forRemote(theClass,stack,parentIsValue);
   882                                 // If we did not succeed AND we are in a value context, then
   883                                 // go ahead and make an NC type out of it...
   885                                 if (result == null && parentIsValue) {
   886                                     result = NCInterfaceType.forNCInterface(theClass,stack);
   887                                 }
   888                             } else {
   890                                 // Nope, is it an AbstractType?
   892                                 result = AbstractType.forAbstract(theClass,stack,true);
   894                                 if (result == null) {
   896                                     // No, so treat it as a non-conforming interface type...
   898                                     result = NCInterfaceType.forNCInterface(theClass,stack);
   899                                 }
   900                             }
   901                         }
   902                     } else {
   904                         // A class. Is it a special case?
   906                         result = SpecialClassType.forSpecial(theClass,stack);
   908                         if (result == null) {
   910                             ClassDeclaration classDecl = theClass.getClassDeclaration();
   912                             // Nope, does it implement java.rmi.Remote?
   914                             if (env.defRemote.implementedBy(env,classDecl)) {
   916                                 // Yep, so just see if we can create an instance of
   917                                 // ImplementationType from it...
   919                                 boolean parentIsValue = stack.isParentAValue();
   920                                 result = ImplementationType.forImplementation(theClass,stack,parentIsValue);
   922                                 // If we did not succeed AND inValue is true, then
   923                                 // go ahead and make an NC type out of it...
   925                                 if (result == null && parentIsValue) {
   926                                     result = NCClassType.forNCClass(theClass,stack);
   927                                 }
   928                             } else {
   930                                 // No, does it implement Serializable?
   932                                 if (env.defSerializable.implementedBy(env,classDecl)) {
   934                                     // Yep, so just see if we can create an instance of ValueType
   935                                     // from it...
   937                                     result = ValueType.forValue(theClass,stack,true);
   938                                 }
   940                                 if (result == null) {
   942                                     // Treat it as a non-conforming class type...
   944                                     result = NCClassType.forNCClass(theClass,stack);
   945                                 }
   946                             }
   947                         }
   948                     }
   949                 } catch (ClassNotFound e) {
   950                     classNotFound(stack,e);
   951                 }
   952                 break;
   953             }
   955         default: throw new CompilerError("Unknown typecode (" + typeCode + ") for " + theType.getTypeSignature());
   956         }
   958         return result;
   959     }
   961     /*
   962      * Check if exception is RemoteException or one of its parents.
   963      */
   964     public static boolean isRemoteException (ClassType ex,
   965                                              BatchEnvironment env) {
   966         sun.tools.java.Type exceptionType = ex.getClassDeclaration().getType();
   968         if (exceptionType.equals(env.typeRemoteException) ||
   969             exceptionType.equals(env.typeIOException) ||
   970             exceptionType.equals(env.typeException) ||
   971             exceptionType.equals(env.typeThrowable)) {
   973             return true;
   974         }
   975         return false;
   976     }
   978     /*
   979      * Check if method is conforming.
   980      */
   981     protected boolean isConformingRemoteMethod (Method method, boolean quiet)
   982         throws ClassNotFound {
   984         // Do we have one exception that is RemoteException or
   985         // a superclass of RemoteException?
   987         boolean haveRemote = false;
   988         ClassType[] exceptions = method.getExceptions();
   990         for (int i = 0; i < exceptions.length; i++) {
   992             // Is it a conforming exception?
   994             if (isRemoteException(exceptions[i],env)) {
   996                 // Got it.
   998                 haveRemote = true;
   999                 break;
  1003         // Do we have our exception?
  1005         if (!haveRemote) {
  1007             // No, so report failure...
  1009             failedConstraint(5,quiet,stack,method.getEnclosing(), method.toString());
  1012         // Are any of the arguments exceptions which implement IDLEntity?
  1013         // If so, report failure...
  1015         boolean noIDLEntity = !isIDLEntityException(method.getReturnType(),method,quiet);
  1016         if (noIDLEntity) {
  1017             Type[] args = method.getArguments();
  1018             for (int i = 0; i < args.length; i++) {
  1019                 if (isIDLEntityException(args[i],method,quiet)) {
  1020                     noIDLEntity = false;
  1021                     break;
  1026         return (haveRemote && noIDLEntity);
  1029     protected boolean isIDLEntityException(Type type, CompoundType.Method method,boolean quiet)
  1030         throws ClassNotFound {
  1031         if (type.isArray()) {
  1032             type = type.getElementType();
  1034         if (type.isCompound()){
  1035             if (((CompoundType)type).isIDLEntityException()) {
  1036                 failedConstraint(18,quiet,stack,method.getEnclosing(), method.toString());
  1037                 return true;
  1040         return false;
  1043     /**
  1044      * Convert all invalid types to valid ones.
  1045      */
  1046     protected void swapInvalidTypes () {
  1048         // Walk all interfaces and check them...
  1050         for (int i = 0; i < interfaces.length; i++) {
  1051             if (interfaces[i].getStatus() != STATUS_VALID) {
  1052                 interfaces[i] = (InterfaceType)getValidType(interfaces[i]);
  1056         // Update methods...
  1058         for (int i = 0; i < methods.length; i++) {
  1059             methods[i].swapInvalidTypes();
  1062         // Update members...
  1064         for (int i = 0; i < members.length; i++) {
  1065             members[i].swapInvalidTypes();
  1069     /*
  1070      * Add matching types to list. Return true if this type has not
  1071      * been previously checked, false otherwise.
  1072      */
  1073     protected boolean addTypes (int typeCodeFilter,
  1074                                 HashSet checked,
  1075                                 Vector matching) {
  1077         // Check self.
  1079         boolean result = super.addTypes(typeCodeFilter,checked,matching);
  1081         // Have we been checked before?
  1083         if (result) {
  1085             // Nope, so walk parent(s) and check them...
  1087             ClassType parent = getSuperclass();
  1089             if (parent != null) {
  1090                 parent.addTypes(typeCodeFilter,checked,matching);
  1093             // Walk all interfaces and check them...
  1095             //if (interfaces == null) System.out.println("NULL for " +getQualifiedName() + " interfaces");
  1096             for (int i = 0; i < interfaces.length; i++) {
  1098                 // Now recurse and add it and any referenced types...
  1100                 //if (interfaces[i] == null) System.out.println("NULL for " +getQualifiedName() + " interfaces[" + i + "]");
  1101                 interfaces[i].addTypes(typeCodeFilter,checked,matching);
  1104             // Walk all methods and check arguments...
  1106             //if (methods == null) System.out.println("NULL for " +getQualifiedName() + " methods");
  1107             for (int i = 0; i < methods.length; i++) {
  1109                 // Add return type...
  1110                 //if (methods[i] == null) System.out.println("NULL for " +getQualifiedName() + " methods[" + i + "]");
  1111                 //if (methods[i].getReturnType() == null) System.out.println("NULL for " +getQualifiedName() + methods[i]);
  1112                 methods[i].getReturnType().addTypes(typeCodeFilter,checked,matching);
  1114                 // Add args...
  1116                 Type[] args = methods[i].getArguments();
  1117                 //if (args == null) System.out.println("NULL for " + getQualifiedName() + " args");
  1119                 for (int j = 0; j < args.length; j++) {
  1121                     Type arg = args[j];
  1122                     //if (arg == null) System.out.println("NULL for " + getQualifiedName() + " arg[" +j+"]");
  1124                                 // Add argument...
  1126                     arg.addTypes(typeCodeFilter,checked,matching);
  1129                 // Add exceptions...
  1131                 ClassType[] exceptions = methods[i].getExceptions();
  1132                 //if (exceptions == null) System.out.println("NULL for " + getQualifiedName() + " exceptions");
  1134                 for (int j = 0; j < exceptions.length; j++) {
  1136                     ClassType ex = exceptions[j];
  1138                                 // Add argument...
  1140                     ex.addTypes(typeCodeFilter,checked,matching);
  1144             // Walk all members and add em...
  1146             //if (members == null) System.out.println("NULL for " +getQualifiedName() + " members");
  1147             for (int i = 0; i < members.length; i++) {
  1148                 //if (members[i] == null) System.out.println("NULL for " +getQualifiedName() + " members[" + i + "]");
  1149                 Type cType = members[i].getType();
  1150                 //if (cType == null) System.out.println("NULL for " + getQualifiedName() + " cType");
  1152                 // Add it...
  1154                 cType.addTypes(typeCodeFilter,checked,matching);
  1158         return result;
  1161     /*
  1162      * Return true if theType is a conforming constant type.
  1163      */
  1164     private boolean isConformingConstantType (MemberDefinition member) {
  1165         return isConformingConstantType(member.getType(),member);
  1168     /*
  1169      * Return true if theType is a conforming constant type.
  1170      */
  1171     private boolean isConformingConstantType (sun.tools.java.Type theType,MemberDefinition member) {
  1173         // Constraint 3:    Constants must be either primitives or String.
  1175         boolean result = true;
  1176         int typeCode = theType.getTypeCode();
  1177         switch (typeCode) {
  1178         case TC_BOOLEAN:
  1179         case TC_BYTE:
  1180         case TC_CHAR:
  1181         case TC_SHORT:
  1182         case TC_INT:
  1183         case TC_LONG:
  1184         case TC_FLOAT:
  1185         case TC_DOUBLE: // Primitive, so OK...
  1187                 break;
  1190         case TC_CLASS:  // Must be java.lang.String
  1192                 if (theType.getClassName() != idJavaLangString) {
  1193                     failedConstraint(3,false,stack,member.getClassDefinition(),member.getName());
  1194                     result = false;
  1196                 break;
  1199         case TC_ARRAY: // Array constants are not allowed.
  1201                 failedConstraint(3,false,stack,member.getClassDefinition(),member.getName());
  1202                 result = false;
  1203                 break;
  1206         default:
  1207             throw new Error("unexpected type code: " + typeCode);
  1210         return result;
  1214     /*
  1215      * Update any method from 'currentMethods' which is defined in a
  1216      * parent class so that it's 'declaredBy' field specifies the
  1217      * parent.
  1218      * @param current The class or interface to gather methods from.
  1219      * @param currentMethods The list into which to put the methods.
  1220      *  for contraint 6.
  1221      * @param quiet true if silent errors.
  1222      * @param stack the context stack.
  1223      * @return currentMethods or null if failed a constraint check.
  1224      */
  1225     protected Vector updateParentClassMethods(ClassDefinition current,
  1226                                               Vector currentMethods,
  1227                                               boolean quiet,
  1228                                               ContextStack stack)
  1229         throws ClassNotFound {
  1231         ClassDeclaration parentDecl = current.getSuperClass(env);
  1233         while (parentDecl != null) {
  1235             ClassDefinition parentDef = parentDecl.getClassDefinition(env);
  1236             Identifier currentID = parentDecl.getName();
  1238             if ( currentID == idJavaLangObject ) break;
  1240             // Walk all members of this class and update any that
  1241             // already exist in currentMethods...
  1243             for (MemberDefinition member = parentDef.getFirstMember();
  1244                  member != null;
  1245                  member = member.getNextMember()) {
  1247                 if (member.isMethod() &&
  1248                     !member.isInitializer() &&
  1249                     !member.isConstructor() &&
  1250                     !member.isPrivate()) {
  1252                     // It's a method.  Is it valid?
  1254                     Method method;
  1255                     try {
  1256                         method = new Method((CompoundType)this,member,quiet,stack);
  1257                     } catch (Exception e) {
  1258                         // Don't report anything here, it's already been reported...
  1259                         return null;
  1262                     // Have we already seen it?
  1264                     int index = currentMethods.indexOf(method);
  1265                     if (index >= 0) {
  1267                         // Yes, so update it...
  1269                         Method currentMethod = (Method)currentMethods.elementAt(index);
  1270                         currentMethod.setDeclaredBy(currentID);
  1272                     else currentMethods.addElement(method);
  1276             // Update parent and keep walking up the chain...
  1278             parentDecl = parentDef.getSuperClass(env);
  1281         return currentMethods;
  1284     /*
  1285      * Add all of the public and protected methods defined in
  1286      * current (other than initializers) to allMethods. If a sub-interface
  1287      * re-declares an inherited method, it will not be added.
  1288      * @param current The class or interface to gather methods from.
  1289      * @param directMethods The list into which to put the methods.
  1290      * @param noMultiInheritedMethods A flag to enable/disable checking
  1291      *  for contraint 6.
  1292      * @param quiet true if silent errors.
  1293      * @param stack the context stack.
  1294      * @return directMethods or null if failed a constraint check.
  1295      */
  1296     protected Vector addAllMethods (ClassDefinition current, Vector directMethods,
  1297                                     boolean noMultiInheritedMethods,
  1298                                     boolean quiet,
  1299                                     ContextStack stack)
  1300         throws ClassNotFound {
  1302         // Constraint 6:    Multiple inherited interfaces may not
  1303         //                  declare the same method.
  1305         ClassDeclaration[] interfaces = current.getInterfaces();
  1307         // We want to add members starting at the _least_ derived
  1308         // interfaces.  To do so, recurse until we have no more
  1309         // interfaces...
  1311         for (int i = 0; i < interfaces.length; i++) {
  1313             Vector result = addAllMethods(interfaces[i].getClassDefinition(env),
  1314                                           directMethods,
  1315                                           noMultiInheritedMethods,quiet,stack);
  1316             if (result == null) {
  1317                 return null;
  1321         // Walk all members of this interface, adding any unique methods
  1322         // other than initializers and private methods...
  1324         for (MemberDefinition member = current.getFirstMember();
  1325              member != null;
  1326              member = member.getNextMember())
  1328                 if (member.isMethod() &&
  1329                     !member.isInitializer() &&
  1330                     !member.isPrivate()) {
  1332                     // It's a method.  Is it valid?
  1334                     Method method;
  1335                     try {
  1336                         method = new Method((CompoundType)this,member,quiet,stack);
  1337                     } catch (Exception e) {
  1338                         // Don't report anything here, it's already been reported...
  1339                         return null;
  1342                                 // Have we already seen it?
  1344                     if (!directMethods.contains(method)) {
  1346                         // Nope, so add it...
  1348                         directMethods.addElement(method);
  1350                     } else {
  1352                         // Yes. This is an error unless we are looking at the
  1353                         // target interface (or this is a ValueType). Are we?
  1355                         if (noMultiInheritedMethods && current != classDef  &&
  1356                             !stack.isParentAValue() && !stack.getContext().isValue()) {
  1358                             // Nope. Say so and signal error by returning null..
  1360                             Method existingMethod = (Method) directMethods.elementAt(directMethods.indexOf(method));
  1361                             ClassDefinition existingMemberClassDef = existingMethod.getMemberDefinition().getClassDefinition();
  1363                             // There are more legal cases to consider here.
  1364                             // If the two methods belong to interfaces that inherit from each other
  1365                             // then it is just a redefinition which is legal.
  1366                             if ( current != existingMemberClassDef &&
  1367                                  ! inheritsFrom(current, existingMemberClassDef) &&
  1368                                  ! inheritsFrom(existingMemberClassDef, current))
  1370                                 //Identifier int1 = existingMethod.getEnclosing().getIdentifier();
  1371                                 //Identifier int2 = current.getName();
  1372                                 //String message = int1.toString() + " and " + int2.toString();
  1373                                 String message = existingMemberClassDef.getName() + " and " + current.getName();
  1374                                 failedConstraint(6,quiet,stack,classDef,message,method);
  1375                                 return null;
  1379                         // Bug fix 5014329
  1381                         // find a matching method.
  1382                         int index = directMethods.indexOf(method);
  1383                         Method other = (Method) directMethods.get(index);
  1385                         // merge the two methods, such that the new method
  1386                         // will contain only those exception that can be thrown
  1387                         // by both these methods, not just one of them.
  1388                         Method newMethod = method.mergeWith(other);
  1390                         // replace the old method with the new.
  1391                         directMethods.set(index, newMethod);
  1396         return directMethods;
  1399     // This should really be a method on ClassDefinition, but it takes too long to change the shared source.
  1400     // Works for both, classes and interfaces.
  1401     protected boolean inheritsFrom(ClassDefinition def, ClassDefinition otherDef) {
  1402         if (def == otherDef)
  1403             return true;
  1405         ClassDefinition superDef;
  1406         if (def.getSuperClass() != null) {
  1407             superDef = def.getSuperClass().getClassDefinition();
  1408             if (inheritsFrom(superDef, otherDef))
  1409                 return true;
  1412         ClassDeclaration[] interfaces = def.getInterfaces();
  1413         for (int i=0; i<interfaces.length; i++) {
  1414             superDef = interfaces[i].getClassDefinition();
  1415             if (inheritsFrom(superDef, otherDef))
  1416                 return true;
  1418         return false;
  1421     /*
  1422      * Add all of the interfaces implemented directly by current
  1423      * to the list. Returns null if any are non-conforming.
  1424      */
  1425     protected Vector addRemoteInterfaces (Vector list,
  1426                                           boolean allowNonConforming,
  1427                                           ContextStack stack) throws ClassNotFound {
  1429         // Add all the interfaces of current...
  1431         ClassDefinition theInterface = getClassDefinition();
  1432         ClassDeclaration[] interfaces = theInterface.getInterfaces();
  1434         stack.setNewContextCode(ContextStack.IMPLEMENTS);
  1436         for (int i = 0; i < interfaces.length; i++) {
  1438             ClassDefinition def = interfaces[i].getClassDefinition(env);
  1440             // Is it a SpecialInterfaceType...
  1442             InterfaceType it = SpecialInterfaceType.forSpecial(def,stack);;
  1444             if (it == null) {
  1446                 // No, is it Remote?
  1448                 if (env.defRemote.implementedBy(env, interfaces[i])) {
  1450                     // Yes, so it must be a RemoteType.
  1452                     it = RemoteType.forRemote(def,stack,false);
  1454                 } else {
  1456                     // Then try Abstract...
  1458                     it = AbstractType.forAbstract(def,stack,true);
  1460                     if (it == null && allowNonConforming) {
  1462                         // Must be non-conforming...
  1464                         it = NCInterfaceType.forNCInterface(def,stack);
  1469             if (it != null) {
  1470                 list.addElement(it);
  1471             } else {
  1472                 return null;
  1476         return list;
  1479     /*
  1480      * Add all of the interfaces implemented directly by current
  1481      * to the list.
  1482      */
  1483     protected Vector addNonRemoteInterfaces (Vector list,
  1484                                              ContextStack stack) throws ClassNotFound {
  1486         // Add all the interfaces of current...
  1488         ClassDefinition theInterface = getClassDefinition();
  1489         ClassDeclaration[] interfaces = theInterface.getInterfaces();
  1491         stack.setNewContextCode(ContextStack.IMPLEMENTS);
  1493         for (int i = 0; i < interfaces.length; i++) {
  1495             ClassDefinition def = interfaces[i].getClassDefinition(env);
  1497             // First try SpecialInterfaceType...
  1499             InterfaceType it = SpecialInterfaceType.forSpecial(def,stack);
  1501             if (it == null) {
  1503                 // Then try AbstractType...
  1505                 it = AbstractType.forAbstract(def,stack,true);
  1507                 if (it == null) {
  1509                     // Then try NCInterfaceType...
  1511                     it = NCInterfaceType.forNCInterface(def,stack);
  1515             if (it != null) {
  1516                 list.addElement(it);
  1517             } else {
  1518                 return null;
  1522         return list;
  1526     /*
  1527      * Walk self, adding constants and data members.
  1528      * @return true if all conform, false otherwise.
  1529      */
  1530     protected boolean addAllMembers (Vector allMembers,
  1531                                      boolean onlyConformingConstants,   // AND inner classes.
  1532                                      boolean quiet,
  1533                                      ContextStack stack) {
  1535         boolean result = true;
  1537         // Walk all members of this interface...
  1539         for (MemberDefinition member = getClassDefinition().getFirstMember();
  1540              member != null && result;
  1541              member = member.getNextMember())
  1543                 if (!member.isMethod()) {
  1545                     try {
  1546                         String value = null;
  1548                         // Prod it to setValue if it is a constant...
  1550                         member.getValue(env);
  1552                                 // Get the value, if any...
  1554                         Node node = member.getValue();
  1556                         if (node != null) {
  1557                             // We don't want to change the code in CharExpression,
  1558                             // which is shared among tools, to return the right string
  1559                             // in case the type is char, so we treat it special here.
  1560                             if (member.getType().getTypeCode() == TC_CHAR) {
  1561                                 Integer intValue = (Integer)((IntegerExpression)node).getValue();
  1562                                 value = "L'" + String.valueOf((char)intValue.intValue()) + "'";
  1563                             } else {
  1564                                 value = node.toString();
  1568                         // Are we supposed to allow only conforming constants?
  1570                         if (onlyConformingConstants && member.getInnerClass() == null) {
  1572                                 // Yep, so check it...
  1574                             if (value == null || !isConformingConstantType(member)) {
  1575                                 failedConstraint(3,quiet,stack,member.getClassDefinition(),member.getName());
  1576                                 result = false;
  1577                                 break;
  1581                         // Make member and add to list...
  1583                         try {
  1584                             Member newMember = new Member(member,value,stack,this);
  1585                             allMembers.addElement(newMember);
  1586                         } catch (CompilerError e) {
  1587                             result = false;
  1590                     } catch (ClassNotFound e) {
  1591                         classNotFound(stack,e);
  1592                         result = false;
  1597         return result;
  1599     /*
  1600      * Walk self, adding constants.
  1601      * @return true if all conform, false otherwise.
  1602      */
  1603     protected boolean addConformingConstants (Vector allMembers,
  1604                                               boolean quiet,
  1605                                               ContextStack stack) {
  1607         boolean result = true;
  1609         // Walk all members of this interface...
  1611         for (MemberDefinition member = getClassDefinition().getFirstMember();
  1612              member != null && result;
  1613              member = member.getNextMember())
  1615                 if (!member.isMethod()) {
  1617                     try {
  1618                         String value = null;
  1620                         // Prod it to setValue if it is a constant...
  1622                         member.getValue(env);
  1624                                 // Get the value, if any...
  1626                         Node node = member.getValue();
  1628                         if (node != null) {
  1629                             value = node.toString();
  1633                         // Is it a constant?
  1635                         if (value != null) {
  1637                             // Yes, is it conforming?
  1639                             if (!isConformingConstantType(member)) {
  1640                                 failedConstraint(3,quiet,stack,member.getClassDefinition(),member.getName());
  1641                                 result = false;
  1642                                 break;
  1645                             // Yes, so make a member and add to list...
  1647                             try {
  1648                                 Member newMember = new Member(member,value,stack,this);
  1649                                 allMembers.addElement(newMember);
  1650                             } catch (CompilerError e) {
  1651                                 result = false;
  1654                     } catch (ClassNotFound e) {
  1655                         classNotFound(stack,e);
  1656                         result = false;
  1661         return result;
  1664     protected ValueType[] getMethodExceptions (MemberDefinition member,
  1665                                                boolean quiet,
  1666                                                ContextStack stack) throws Exception {
  1668         boolean result = true;
  1669         stack.setNewContextCode(ContextStack.METHOD_EXCEPTION);
  1670         ClassDeclaration[] except = member.getExceptions(env);
  1671         ValueType[] exceptions = new ValueType[except.length];
  1673         try {
  1674             for (int i = 0; i < except.length; i++) {
  1675                 ClassDefinition theClass = except[i].getClassDefinition(env);
  1676                 try {
  1677                     ValueType type = ValueType.forValue(theClass,stack,false);
  1678                     if (type != null) {
  1679                             exceptions[i] = type;
  1680                         } else {
  1681                             result = false;
  1683                 } catch (ClassCastException e1) {
  1684                     failedConstraint(22,quiet,stack,getQualifiedName());
  1685                     throw new CompilerError("Method: exception " + theClass.getName() + " not a class type!");
  1686                 } catch (NullPointerException e2) {
  1687                     failedConstraint(23,quiet,stack,getQualifiedName());
  1688                     throw new CompilerError("Method: caught null pointer exception");
  1691         } catch (ClassNotFound e) {
  1692             classNotFound(quiet,stack,e);
  1693             result = false;
  1696         if (!result) {
  1697             throw new Exception();
  1700         // Remove any duplicates (javac seems to allow them, but rmic will
  1701         // generate bad ties)...
  1703         int dupCount = 0;
  1704         for (int i = 0; i < exceptions.length; i++) {
  1705             for (int j = 0; j < exceptions.length; j++) {
  1706                 if (i != j && exceptions[i] != null && exceptions[i] == exceptions[j]) {
  1707                     exceptions[j] = null;
  1708                     dupCount++;
  1712         if (dupCount > 0) {
  1713             int offset = 0;
  1714             ValueType[] temp = new ValueType[exceptions.length - dupCount];
  1715             for (int i = 0; i < exceptions.length; i++) {
  1716                 if (exceptions[i] != null) {
  1717                     temp[offset++] = exceptions[i];
  1720             exceptions = temp;
  1723         return exceptions;
  1727     protected static String getVisibilityString (MemberDefinition member) {
  1728         String vis = "";
  1729         String prefix = "";
  1731         if (member.isPublic()) {
  1732             vis += "public";
  1733             prefix = " ";
  1734         } else if (member.isProtected()) {
  1735             vis += "protected";
  1736             prefix = " ";
  1737         } else if (member.isPrivate()) {
  1738             vis += "private";
  1739             prefix = " ";
  1742         if (member.isStatic()) {
  1743             vis += prefix;
  1744             vis += "static";
  1745             prefix = " ";
  1748         if (member.isFinal()) {
  1749             vis += prefix;
  1750             vis += "final";
  1751             prefix = " ";
  1754         return vis;
  1757     protected boolean assertNotImpl(Type type,
  1758                                     boolean quiet,
  1759                                     ContextStack stack,
  1760                                     CompoundType enclosing,
  1761                                     boolean dataMember) {
  1763         if (type.isType(TYPE_IMPLEMENTATION)) {
  1764             int constraint = dataMember ? 28 : 21;
  1765             failedConstraint(constraint,quiet,stack,type,enclosing.getName());
  1766             return false;
  1768         return true;
  1771     //_____________________________________________________________________
  1772     // Inner Class "Method"
  1773     //_____________________________________________________________________
  1775     /**
  1776      * A CompoundType.Method object encapsulates IIOP-specific information
  1777      * about a particular method in the interface represented by the outer
  1778      * instance.
  1779      */
  1780     public class Method implements ContextElement, Cloneable {
  1782         /**
  1783          * Is this method inherited?
  1784          */
  1785         public boolean isInherited () {
  1786             return declaredBy != enclosing.getIdentifier();
  1789         /**
  1790          * Is this method an attribute?
  1791          * Return true if getAttributeKind != ATTRIBUTE_NONE.
  1792          */
  1793         public boolean isAttribute () {
  1794             return attributeKind != ATTRIBUTE_NONE;
  1797         /**
  1798          * Is this method a read-write attribute?
  1799          */
  1800         public boolean isReadWriteAttribute () {
  1801             return attributeKind == ATTRIBUTE_IS_RW ||
  1802                 attributeKind == ATTRIBUTE_GET_RW;
  1805         /**
  1806          * Return the attribute kind.
  1807          */
  1808         public int getAttributeKind() {
  1809             return attributeKind;
  1812         /**
  1813          * Return the attribute name. Will be null if
  1814          * attribute kind == ATTRIBUTE_NONE.
  1815          */
  1816         public String getAttributeName() {
  1817             return attributeName;
  1820         /**
  1821          * For kinds ATTRIBUTE_GET_RW or ATTRIBUTE_IS_RW, return
  1822          * the index of the matching ATTRIBUTE_SET method, and
  1823          * vice-versa. For all other cases, return -1.
  1824          */
  1825         public int getAttributePairIndex() {
  1826             return attributePairIndex;
  1829         /**
  1830          * Return context element name.
  1831          */
  1832         public String getElementName() {
  1833             return memberDef.toString();
  1836         /**
  1837          * Equality check based on method signature.
  1838          */
  1839         public boolean equals(Object obj) {
  1840             Method other = (Method) obj;
  1842             if (getName().equals(other.getName()) &&
  1843                 arguments.length == other.arguments.length) {
  1845                 for (int i = 0; i < arguments.length; i++) {
  1846                     if (! arguments[i].equals(other.arguments[i])) {
  1847                         return false;
  1850                 return true;
  1852             return false;
  1855         public int hashCode() {
  1856             return getName().hashCode() ^ Arrays.hashCode(arguments);
  1859         /**
  1860          * Return a new Method object that is a legal combination of
  1861          * this method object and another one.
  1863          * This requires determining the exceptions declared by the
  1864          * combined method, which must be only those exceptions
  1865          * that may thrown by both of the old methods.
  1866          */
  1867         public Method mergeWith(Method other) {
  1868             if (!equals(other)) {
  1869                 env.error(0, "attempt to merge method failed:", getName(),
  1870                           enclosing.getClassDefinition().getName());
  1873             Vector legalExceptions = new Vector();
  1874             try {
  1875                 collectCompatibleExceptions(
  1876                       other.exceptions, exceptions, legalExceptions);
  1877                 collectCompatibleExceptions(
  1878                       exceptions, other.exceptions, legalExceptions);
  1879             } catch (ClassNotFound e) {
  1880                 env.error(0, "class.not.found", e.name,
  1881                           enclosing.getClassDefinition().getName());
  1882                 return null;
  1885             Method merged = (Method) clone();
  1886             merged.exceptions = new ValueType[legalExceptions.size()];
  1887             legalExceptions.copyInto(merged.exceptions);
  1888             merged.implExceptions = merged.exceptions;
  1890             return merged;
  1893         /**
  1894          * Add to the supplied list all exceptions in the "from" array
  1895          * that are subclasses of an exception in the "with" array.
  1896          */
  1897         private void collectCompatibleExceptions(
  1898                 ValueType[] from, ValueType[] with, Vector list)
  1899                 throws ClassNotFound {
  1901             for (int i = 0; i < from.length; i++) {
  1902                 ClassDefinition exceptionDef = from[i].getClassDefinition();
  1903                 if (!list.contains(from[i])) {
  1904                     for (int j = 0; j < with.length; j++) {
  1905                         if (exceptionDef.subClassOf(
  1906                                 enclosing.getEnv(),
  1907                                 with[j].getClassDeclaration())) {
  1908                             list.addElement(from[i]);
  1909                             break;
  1916         /**
  1917          * Return the compound type which contains this method.
  1918          */
  1919         public CompoundType getEnclosing() {
  1920             return enclosing;
  1923         /**
  1924          * Return the identifier for the class or interface which
  1925          * declares this method.
  1926          */
  1927         public Identifier getDeclaredBy() {
  1928             return declaredBy;
  1931         /**
  1932          * Return the visibility (e.g. "public final") of this member.
  1933          */
  1934         public String getVisibility() {
  1935             return vis;
  1938         /**
  1939          * Methods to check various attributes.
  1940          */
  1941         public boolean isPublic() {
  1942             return memberDef.isPublic();
  1945         public boolean isProtected() {
  1946             return memberDef.isPrivate();
  1949         public boolean isPrivate() {
  1950             return memberDef.isPrivate();
  1953         public boolean isStatic() {
  1954             return memberDef.isStatic();
  1957         /**
  1958          * Return the name of this method.
  1959          */
  1960         public String getName() {
  1961             return name;
  1964         /**
  1965          * IDL_Naming
  1966          * Return the IDL name of this method.
  1967          */
  1968         public String getIDLName() {
  1969             return idlName;
  1972         /**
  1973          * Return the type of this method.
  1974          */
  1975         public sun.tools.java.Type getType() {
  1976             return memberDef.getType();
  1979         /**
  1980          * Return true if this is a constructor.
  1981          */
  1982         public boolean isConstructor () {
  1983             return memberDef.isConstructor();
  1986         /**
  1987          * Return true if this is NOT a constructor && is not
  1988          * an attribute.
  1989          */
  1990         public boolean isNormalMethod () {
  1991             return (!memberDef.isConstructor()) && attributeKind == ATTRIBUTE_NONE;
  1994         /**
  1995          * Get the return type of this method. May be null.
  1996          */
  1997         public Type getReturnType() {
  1998             return returnType;
  2001         /**
  2002          * Return the argument types of this method.
  2003          */
  2004         public Type[] getArguments() {
  2005             return (Type[]) arguments.clone();
  2008         /**
  2009          * Return the names of the argument types of this method.
  2010          */
  2011         public String[] getArgumentNames() {
  2012             return argumentNames;
  2015         /**
  2016          * Return the MemberDefinition from which this method was created.
  2017          */
  2018         public MemberDefinition getMemberDefinition() {
  2019             return memberDef;
  2022         /**
  2023          * Return an array of the exception classes declared to be
  2024          * thrown by this remote method.
  2026          * For methods with the same name and type signature inherited
  2027          * from multiple remote interfaces, the array will contain
  2028          * the set of exceptions declared in all of the interfaces'
  2029          * methods that can be legally thrown in each of them.
  2030          */
  2031         public ValueType[] getExceptions() {
  2032             return (ValueType[]) exceptions.clone();
  2035         /**
  2036          * Same as getExceptions(), except when method is in an
  2037          * ImplementationType and the exceptions list is narrower.
  2038          */
  2039         public ValueType[] getImplExceptions() {
  2040             return (ValueType[]) implExceptions.clone();
  2043         /**
  2044          * Return an array containing only those exceptions which
  2045          * need to be caught.  Removes java.rmi.RemoteException,
  2046          * java.lang.RuntimeException, java.lang.Error, and their
  2047          * subclasses, then removes any exceptions which are more
  2048          * derived than another in the list. Returns null if no
  2049          * exceptions need to be caught.
  2050          */
  2051         public ValueType[] getUniqueCatchList(ValueType[] list) {
  2052             ValueType[] result = list;
  2053             int newSize = list.length;
  2055             try {
  2057                 // First, remove RemoteException, RuntimeException, Error, and their subclasses...
  2058                 for (int i = 0; i < list.length; i++) {
  2059                     ClassDeclaration decl = list[i].getClassDeclaration();
  2060                     if (env.defRemoteException.superClassOf(env, decl) ||
  2061                         env.defRuntimeException.superClassOf(env, decl) ||
  2062                         env.defError.superClassOf(env, decl)) {
  2063                         list[i] = null;
  2064                         newSize--;
  2068                 // Now remove derived types...
  2069                 for (int i = 0; i < list.length; i++) {
  2070                     if (list[i] != null) {
  2071                         ClassDefinition current = list[i].getClassDefinition();
  2072                         for (int j = 0; j < list.length; j++) {
  2073                             if (j != i && list[i] != null && list[j] != null &&
  2074                                 current.superClassOf(env, list[j].getClassDeclaration())) {
  2075                                 list[j] = null;
  2076                                 newSize--;
  2082             } catch (ClassNotFound e) {
  2083                 classNotFound(stack,e); // Report error but do not stop.
  2086             // Create new list if we removed anything...
  2088             if (newSize < list.length) {
  2089                 ValueType[] temp = new ValueType[newSize];
  2090                 int offset = 0;
  2091                 for (int i = 0; i < list.length; i++) {
  2092                     if (list[i] != null) {
  2093                         temp[offset++] = list[i];
  2096                 list = temp;
  2099             if (list.length == 0) {
  2100                 return null;
  2101             } else {
  2102                 return list;
  2106         /**
  2107          * Return an array containing only those exceptions which need to be
  2108          * handled explicitly by the stub.  Removes java.lang.RuntimeException,
  2109          * java.lang.Error, and their subclasses, since these are all passed
  2110          * back as CORBA system exceptions.  Also removes subclasses of
  2111          * java.rmi.RemoteException but not java.rmi.RemoteException itself,
  2112          * since this may need to be thrown by the stub.
  2113          */
  2114         public ValueType[] getFilteredStubExceptions(ValueType[] list) {
  2115             ValueType[] result = list;
  2116             int newSize = list.length;
  2118             try {
  2120                 for (int i = 0; i < list.length; i++) {
  2121                     ClassDeclaration decl = list[i].getClassDeclaration();
  2122                     if ((env.defRemoteException.superClassOf(env, decl) &&
  2123                          !env.defRemoteException.getClassDeclaration().equals(decl)) ||
  2124                         env.defRuntimeException.superClassOf(env, decl) ||
  2125                         env.defError.superClassOf(env, decl)) {
  2126                         list[i] = null;
  2127                         newSize--;
  2131             } catch (ClassNotFound e) {
  2132                 classNotFound(stack,e); // Report error but do not stop.
  2135             // Create new list if we removed anything...
  2137             if (newSize < list.length) {
  2138                 ValueType[] temp = new ValueType[newSize];
  2139                 int offset = 0;
  2140                 for (int i = 0; i < list.length; i++) {
  2141                     if (list[i] != null) {
  2142                         temp[offset++] = list[i];
  2145                 list = temp;
  2148             return list;
  2151         /**
  2152          * Return the string representation of this method.
  2153          */
  2154         public String toString() {
  2156             if (stringRep == null) {
  2158                 StringBuffer result = new StringBuffer(returnType.toString());
  2160                 // Add name...
  2162                 result.append(" ");
  2163                 result.append(getName());
  2164                 result.append(" (");
  2166                 // Add arguments...
  2168                 for (int i = 0; i < arguments.length; i++) {
  2169                     if (i > 0) {
  2170                         result.append(", ");
  2172                     result.append(arguments[i]);
  2173                     result.append(" ");
  2174                     result.append(argumentNames[i]);
  2177                 result.append(")");
  2179                 // Add exceptions...
  2181                 for (int i = 0; i < exceptions.length; i++) {
  2182                     if (i == 0) {
  2183                         result.append(" throws ");
  2184                     } else {
  2185                         result.append(", ");
  2187                     result.append(exceptions[i]);
  2190                 result.append(";");
  2192                 stringRep = result.toString();
  2195             return stringRep;
  2199         /**
  2200          * Set attribute kind. May only be called during initialization.
  2201          */
  2202         public void setAttributeKind(int kind) {
  2203             attributeKind = kind;
  2206         /**
  2207          * Set pair index. May only be called during initialization.
  2208          */
  2209         public void setAttributePairIndex(int index) {
  2210             attributePairIndex = index;
  2213         /**
  2214          * Set attribute name. May only be called during initialization.
  2215          */
  2216         public void setAttributeName(String name) {
  2217             attributeName = name;
  2220         /**
  2221          * Set the idl name. May only be called during initialization.
  2222          */
  2223         public void setIDLName (String idlName) {
  2224             this.idlName=idlName;
  2227         /**
  2228          * Set the implExceptions array. May only be called during initialization.
  2229          */
  2230         public void setImplExceptions (ValueType[] exceptions) {
  2231             implExceptions = exceptions;
  2234         /**
  2235          * Set the declaredBy Identifier. May only be called during initialization.
  2236          */
  2237         public void setDeclaredBy (Identifier by) {
  2238             declaredBy = by;
  2241         /**
  2242          * Convert all invalid types to valid ones.
  2243          */
  2244         protected void swapInvalidTypes () {
  2246             // Check return type...
  2248             if (returnType.getStatus() != STATUS_VALID) {
  2249                 returnType = getValidType(returnType);
  2252             // Check args...
  2254             for (int i = 0; i < arguments.length; i++) {
  2255                 if (arguments[i].getStatus() != STATUS_VALID) {
  2256                     arguments[i] = getValidType(arguments[i]);
  2260             // Check exceptions...
  2262             for (int i = 0; i < exceptions.length; i++) {
  2263                 if (exceptions[i].getStatus() != STATUS_VALID) {
  2264                     exceptions[i] = (ValueType)getValidType(exceptions[i]);
  2268             // Check implExceptions...
  2270             for (int i = 0; i < implExceptions.length; i++) {
  2271                 if (implExceptions[i].getStatus() != STATUS_VALID) {
  2272                     implExceptions[i] = (ValueType)getValidType(implExceptions[i]);
  2277         /**
  2278          * Release all resources.
  2279          */
  2280         public void destroy () {
  2281             if (memberDef != null) {
  2282                 memberDef = null;
  2283                 enclosing = null;
  2284                 if (exceptions != null) {
  2285                     for (int i = 0; i < exceptions.length; i++) {
  2286                         if (exceptions[i] != null) exceptions[i].destroy();
  2287                         exceptions[i] = null;
  2289                     exceptions = null;
  2292                 if (implExceptions != null) {
  2293                     for (int i = 0; i < implExceptions.length; i++) {
  2294                         if (implExceptions[i] != null) implExceptions[i].destroy();
  2295                         implExceptions[i] = null;
  2297                     implExceptions = null;
  2300                 if (returnType != null) returnType.destroy();
  2301                 returnType = null;
  2303                 if (arguments != null) {
  2304                     for (int i = 0; i < arguments.length; i++) {
  2305                         if (arguments[i] != null) arguments[i].destroy();
  2306                         arguments[i] = null;
  2308                     arguments = null;
  2311                 if (argumentNames != null) {
  2312                     for (int i = 0; i < argumentNames.length; i++) {
  2313                         argumentNames[i] = null;
  2315                     argumentNames = null;
  2318                 vis = null;
  2319                 name = null;
  2320                 idlName = null;
  2321                 stringRep = null;
  2322                 attributeName = null;
  2323                 declaredBy = null;
  2327         private MemberDefinition memberDef;
  2328         private CompoundType enclosing;
  2329         private ValueType[] exceptions;
  2330         private ValueType[] implExceptions;
  2331         private Type returnType;
  2332         private Type[] arguments;
  2333         private String[] argumentNames;
  2334         private String vis;
  2335         private String name;
  2336         private String idlName;
  2337         private String stringRep = null;
  2338         private int attributeKind = ATTRIBUTE_NONE;
  2339         private String attributeName = null;
  2340         private int attributePairIndex = -1;
  2341         private Identifier declaredBy = null;
  2343         /**
  2344          * Make up an argument name for the given type.
  2345          */
  2346         private String makeArgName (int argNum, Type type) {
  2347             return "arg" + argNum;
  2350         /**
  2351          * Create a new Method object corresponding to the given
  2352          * method definition.
  2353          */
  2354         public Method (CompoundType enclosing,
  2355                        MemberDefinition memberDef,
  2356                        boolean quiet,
  2357                        ContextStack stack) throws Exception {
  2359             this.enclosing = enclosing;
  2360             this.memberDef = memberDef;
  2361             vis = getVisibilityString(memberDef);
  2362             idlName = null; // See setIDLName()
  2363             boolean valid = true;
  2364             declaredBy = memberDef.getClassDeclaration().getName();
  2366             // Set name...
  2368             name = memberDef.getName().toString();
  2370             // Update the context...
  2372             stack.setNewContextCode(ContextStack.METHOD);
  2373             stack.push(this);
  2375             // Set return type...
  2377             stack.setNewContextCode(ContextStack.METHOD_RETURN);
  2378             sun.tools.java.Type methodType = memberDef.getType();
  2379             sun.tools.java.Type rtnType = methodType.getReturnType();
  2381             if (rtnType == sun.tools.java.Type.tVoid) {
  2382                 returnType = PrimitiveType.forPrimitive(rtnType,stack);
  2383             } else {
  2384                 returnType = makeType(rtnType,null,stack);
  2385                 if (returnType == null ||
  2386                     !assertNotImpl(returnType,quiet,stack,enclosing,false)) {
  2387                     valid = false;
  2388                     failedConstraint(24,quiet,stack,enclosing.getName());
  2392             // Set arguments and argument names...
  2394             stack.setNewContextCode(ContextStack.METHOD_ARGUMENT);
  2395             sun.tools.java.Type[] args = memberDef.getType().getArgumentTypes();
  2396             arguments = new Type[args.length];
  2397             argumentNames = new String[args.length];
  2398             Vector origArgNames = memberDef.getArguments();
  2400             for (int i = 0; i < args.length; i++) {
  2401                 Type type = null;
  2402                 try {
  2403                     type = makeType(args[i],null,stack);
  2404                 } catch (Exception e) {
  2407                 if (type != null) {
  2408                     if (!assertNotImpl(type,quiet,stack,enclosing,false)) {
  2409                         valid = false;
  2410                     } else {
  2411                     arguments[i] = type;
  2412                     if (origArgNames != null) {
  2413                         LocalMember local = (LocalMember)origArgNames.elementAt(i+1);
  2414                         argumentNames[i] = local.getName().toString();
  2415                     } else {
  2416                         argumentNames[i] = makeArgName(i,type);
  2419                 } else {
  2420                     valid = false;
  2421                     failedConstraint(25,false,stack,enclosing.getQualifiedName(),name);
  2425             if (!valid) {
  2426                 stack.pop(false);
  2427                 throw new Exception();
  2430             // Set exceptions...
  2432             try {
  2433                 exceptions = enclosing.getMethodExceptions(memberDef,quiet,stack);
  2434                 implExceptions = exceptions;
  2435                 stack.pop(true);
  2436             } catch (Exception e) {
  2437                 stack.pop(false);
  2438                 throw new Exception();
  2442         /**
  2443          * Cloning is supported by returning a shallow copy of this object.
  2444          */
  2445         protected Object clone() {
  2446             try {
  2447                 return super.clone();
  2448             } catch (CloneNotSupportedException e) {
  2449                 throw new Error("clone failed");
  2454     //_____________________________________________________________________
  2455     // Inner Class "Member"
  2456     //_____________________________________________________________________
  2458     /**
  2459      * An CompoundType.Member object wraps a Type and a value representing
  2460      * a data member, including constants.
  2461      */
  2462     public class Member implements ContextElement, Cloneable {
  2464         /**
  2465          * Return context element name.
  2466          */
  2467         public String getElementName() {
  2468             return "\"" + getName() + "\"";
  2471         /**
  2472          * Return the type of this member.
  2473          */
  2474         public Type getType() {
  2475             return type;
  2478         /**
  2479          * Return the name of this member.
  2480          */
  2481         public String getName() {
  2482             return name;
  2485         /**
  2486          * IDL_Naming
  2487          * Return the IDL name of this member.
  2488          */
  2489         public String getIDLName() {
  2490             return idlName;
  2493         /**
  2494          * Return the visibility (e.g. "public final") of this member.
  2495          */
  2496         public String getVisibility() {
  2497             return vis;
  2500         /**
  2501          * Methods to check various attributes.
  2502          */
  2503         public boolean isPublic() {
  2504             return member.isPublic();
  2507         public boolean isPrivate() {
  2508             return member.isPrivate();
  2511         public boolean isStatic() {
  2512             return member.isStatic();
  2515         public boolean isFinal() {
  2516             return member.isFinal();
  2519         public boolean isTransient() {
  2520             if (forceTransient) return true;
  2521             return member.isTransient();
  2524         /**
  2525          * Return the value of this member. May be null.
  2526          */
  2527         public String getValue() {
  2528             return value;
  2531         /**
  2532          * Return true if this member represents an inner class declaration,
  2533          * false otherwise.
  2534          */
  2535         public boolean isInnerClassDeclaration() {
  2536             return innerClassDecl;
  2539         /**
  2540          * Return true if this member represents a constant.
  2541          */
  2542         public boolean isConstant () {
  2543             return constant;
  2546         /**
  2547          * Return the string representation of this constant.
  2548          */
  2549         public String toString() {
  2551             String result = type.toString();
  2553             if (value != null) {
  2554                 result += (" = " + value);
  2557             return result;
  2560         /**
  2561          * Convert all invalid types to valid ones.
  2562          */
  2563         protected void swapInvalidTypes () {
  2564             if (type.getStatus() != STATUS_VALID) {
  2565                 type = getValidType(type);
  2569         protected void setTransient() {
  2570             if (! isTransient()) {
  2571                 forceTransient = true;
  2572                 if (vis.length() > 0) {
  2573                     vis = vis + " transient";
  2574                 } else {
  2575                     vis = "transient";
  2580         protected MemberDefinition getMemberDefinition() {
  2581             return member;
  2584         /**
  2585          * Release all resources.
  2586          */
  2587         public void destroy () {
  2588             if (type != null) {
  2589                 type.destroy();
  2590                 type = null;
  2591                 vis = null;
  2592                 value = null;
  2593                 name = null;
  2594                 idlName = null;
  2595                 member = null;
  2599         private Type type;
  2600         private String vis;
  2601         private String value;
  2602         private String name;
  2603         private String idlName;
  2604         private boolean innerClassDecl;
  2605         private boolean constant;
  2606         private MemberDefinition member;
  2607         private boolean forceTransient;
  2609         /**
  2610          * Create a new Member object.
  2611          */
  2612         public Member(MemberDefinition member,
  2613                       String value,
  2614                       ContextStack stack,
  2615                       CompoundType enclosing) {
  2616             this.member = member;
  2617             this.value = value;
  2618             forceTransient = false;
  2619             innerClassDecl = member.getInnerClass() != null;
  2621             // If we are not an inner class, finish initializing now.
  2622             // Otherwise, wait until outer class is finished, then
  2623             // call init to avoid potential recursion problems...
  2625             if (!innerClassDecl) {
  2626                 init (stack,enclosing);
  2630         public void init (ContextStack stack, CompoundType enclosing) {
  2632             constant = false;
  2633             name = member.getName().toString();
  2634             vis = getVisibilityString(member);
  2635             idlName = null;
  2637             // Add self to stack...
  2639             int contextCode = ContextStack.MEMBER;
  2640             stack.setNewContextCode(contextCode);
  2642             // Check for special contextCodes...
  2644             if (member.isVariable()) {
  2645                 if (value != null && member.isConstant()) {
  2646                     contextCode = ContextStack.MEMBER_CONSTANT;
  2647                     this.constant = true;
  2648                 } else if (member.isStatic()) {
  2649                     contextCode = ContextStack.MEMBER_STATIC;
  2650                 } else if (member.isTransient()) {
  2651                     contextCode = ContextStack.MEMBER_TRANSIENT;
  2655             stack.setNewContextCode(contextCode);
  2656             stack.push(this);
  2658             type = makeType(member.getType(),null,stack);
  2660             if (type == null ||
  2661                 (!innerClassDecl &&
  2662                  !member.isStatic() &&
  2663                  !member.isTransient() &&
  2664                  !assertNotImpl(type,false,stack,enclosing,true))) {
  2665                 stack.pop(false);
  2666                 throw new CompilerError("");
  2669             // Clean up primitive constant values...
  2671             if (constant && type.isPrimitive()) {
  2672                 if (type.isType(TYPE_LONG) || type.isType(TYPE_FLOAT) || type.isType(TYPE_DOUBLE)) {
  2673                     int length = value.length();
  2674                     char lastChar = value.charAt(length-1);
  2675                     if (!Character.isDigit(lastChar)) {
  2676                         this.value = value.substring(0,length-1);
  2678                 } else if (type.isType(TYPE_BOOLEAN)) {
  2679                     value = value.toUpperCase();
  2682             if (constant && type.isType(TYPE_STRING)) {
  2683                 value = "L" + value;
  2685             stack.pop(true);
  2688         public void setIDLName (String name) {
  2689             this.idlName = name;
  2692         /**
  2693          * Cloning is supported by returning a shallow copy of this object.
  2694          */
  2695         protected Object clone() {
  2696             try {
  2697                 return super.clone();
  2698             } catch (CloneNotSupportedException e) {
  2699                 throw new Error("clone failed");

mercurial