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

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

mercurial