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

changeset 0
7ef37b2cdcad
child 748
6845b95cba6b
equal deleted inserted replaced
-1:000000000000 0:7ef37b2cdcad
1 /*
2 * Copyright (c) 1998, 2013, 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 */
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.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;
52
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 {
60
61 protected Method[] methods;
62 protected InterfaceType[] interfaces;
63 protected Member[] members;
64 protected ClassDefinition classDef;
65 protected ClassDeclaration classDecl;
66
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;
77
78 //_____________________________________________________________________
79 // Public Interfaces
80 //_____________________________________________________________________
81
82 /**
83 * Return true if this type implements
84 * org.omg.CORBA.Object.
85 */
86 public boolean isCORBAObject () {
87 return isCORBAObject;
88 }
89
90 /**
91 * Return true if this type implements
92 * org.omg.CORBA.portable.IDLEntity.
93 */
94 public boolean isIDLEntity () {
95 return isIDLEntity;
96 }
97
98 /**
99 * Return true if this type implements
100 * org.omg.CORBA.portable.ValueBase.
101 */
102 public boolean isValueBase () {
103 return isValueBase;
104 }
105
106 /**
107 * Return true if this type is a CORBA
108 * abstract interface.
109 */
110 public boolean isAbstractBase () {
111 return isAbstractBase;
112 }
113
114 /**
115 * Return true if this type is an exception.
116 */
117 public boolean isException () {
118 return isException;
119 }
120
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 }
128
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 }
137
138 /**
139 * Return true if this type is exactly
140 * org.omg.CORBA.UserException.
141 */
142 public boolean isCORBAUserException () {
143 return isCORBAUserException;
144 }
145
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 }
163
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 }
172
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 }
188
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 }
200
201 /**
202 * Return the ClassDeclaration for this type.
203 */
204 public ClassDeclaration getClassDeclaration() {
205 return classDecl;
206 }
207
208 /**
209 * Return the ClassDefinition for this type.
210 */
211 public ClassDefinition getClassDefinition() {
212 return classDef;
213 }
214
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 }
222
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 }
234
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 }
245
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 }
256
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;
267
268 try {
269 result = (CompoundType) makeType(classDef.getType(),classDef,stack);
270 } catch (ClassCastException e) {}
271
272 return result;
273 }
274
275
276 //_____________________________________________________________________
277 // Subclass/Internal Interfaces
278 //_____________________________________________________________________
279
280 /**
281 * Release all resources.
282 */
283 protected void destroy () {
284 if (!destroyed) {
285 super.destroy();
286
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 }
293
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 }
300
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 }
307
308 classDef = null;
309 classDecl = null;
310 }
311 }
312
313 /*
314 * Load a Class instance. Return null if fail.
315 */
316 protected Class loadClass() {
317
318 Class ourClass = null;
319
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...
326
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 }
336
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) {
346
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 }
356
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 */
365
366 if (ourClass == null) {
367
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...
372
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 }
380
381 try {
382 ourClass = env.loader.loadClass(getQualifiedName());
383 } catch (Exception e) {}
384 }
385
386 return ourClass;
387 }
388
389 // Print "extends XX"
390
391 protected boolean printExtends (IndentingWriter writer,
392 boolean useQualifiedNames,
393 boolean useIDLNames,
394 boolean globalIDLNames) throws IOException {
395
396 ClassType parent = getSuperclass();
397
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 }
406
407 // Print "implements XX, YY"
408
409 protected void printImplements (IndentingWriter writer,
410 String prefix,
411 boolean useQualifiedNames,
412 boolean useIDLNames,
413 boolean globalIDLNames) throws IOException {
414
415 InterfaceType[] interfaces = getInterfaces();
416
417 String adjective = " implements";
418
419 if (isInterface()) {
420 adjective = " extends";
421 }
422
423 if (useIDLNames) {
424 adjective = ":";
425 }
426
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 }
438
439 // Print members
440
441 protected void printMembers ( IndentingWriter writer,
442 boolean useQualifiedNames,
443 boolean useIDLNames,
444 boolean globalIDLNames) throws IOException {
445
446 CompoundType.Member[] members = getMembers();
447
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;
453
454 if (useIDLNames) {
455 name = members[i].getIDLName();
456 } else {
457 name = members[i].getName();
458 }
459
460 String value = members[i].getValue();
461
462 writer.p(visibility);
463 if (visibility.length() > 0) {
464 writer.p(" ");
465 }
466 it.printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
467 writer.p(" " + name);
468
469 if (value != null) {
470 writer.pln(" = " + value + ";");
471 } else {
472 writer.pln(";");
473 }
474 }
475 }
476 }
477
478 // Print methods
479
480 protected void printMethods ( IndentingWriter writer,
481 boolean useQualifiedNames,
482 boolean useIDLNames,
483 boolean globalIDLNames) throws IOException {
484
485 CompoundType.Method[] methods = getMethods();
486
487 for (int m = 0; m < methods.length; m++) {
488 CompoundType.Method theMethod = methods[m];
489 printMethod(theMethod,writer,useQualifiedNames,useIDLNames,globalIDLNames);
490 }
491 }
492
493 // Print a method...
494
495 protected void printMethod (CompoundType.Method it,
496 IndentingWriter writer,
497 boolean useQualifiedNames,
498 boolean useIDLNames,
499 boolean globalIDLNames) throws IOException {
500
501
502 // Write visibility...
503
504 String visibility = it.getVisibility();
505
506 writer.p(visibility);
507 if (visibility.length() > 0) {
508 writer.p(" ");
509 }
510
511 // Write return type...
512
513 it.getReturnType().printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
514
515 // Write method name...
516
517 if (useIDLNames) {
518 writer.p(" " + it.getIDLName());
519 } else {
520 writer.p(" " + it.getName());
521 }
522
523 // Write arguments...
524
525 writer.p(" (");
526 Type[] args = it.getArguments();
527 String[] argNames = it.getArgumentNames();
528
529 for (int i = 0; i < args.length; i++) {
530 if (i > 0) {
531 writer.p(", ");
532 }
533
534 if (useIDLNames) {
535 writer.p("in ");
536 }
537
538 args[i].printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames);
539 writer.p(" " + argNames[i]);
540 }
541 writer.p(")");
542
543 // Write exceptions...
544
545 ClassType[] exceptions;
546
547 if (isType(TYPE_IMPLEMENTATION)) {
548 exceptions = it.getImplExceptions();
549 } else {
550 exceptions = it.getExceptions();
551 }
552
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 }
563
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 }
577
578 if (useIDLNames && exceptions.length > 0) {
579 writer.p(")");
580 }
581
582 if (it.isInherited()) {
583 writer.p(" // Inherited from ");
584 writer.p(it.getDeclaredBy());
585 }
586
587 writer.pln(";");
588 }
589
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];
601
602 // If we are an inner class/interface, reset the type codes...
603
604 if (classDef.isInnerClass()) {
605 setTypeCode(typeCode | TM_INNER);
606 }
607
608 // Set special flags...
609
610 setFlags();
611 }
612
613 private void setFlags() {
614
615 try {
616
617 // Set our special interface flags...
618
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);
627
628 // Is this an exception?
629
630 if (env.defThrowable.implementedBy(env, classDecl)) {
631
632 // Yes...
633
634 isException = true;
635
636 // Is it a checked exception?
637
638 if (env.defRuntimeException.implementedBy(env,classDecl) ||
639 env.defError.implementedBy(env,classDecl)) {
640 isCheckedException = false;
641 } else {
642 isCheckedException = true;
643 }
644
645 // Is it java.rmi.RemoteException or a subclass?
646
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 }
659
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();
669
670 // If we are an inner class/interface, reset the type codes...
671
672 if (classDef.isInnerClass()) {
673 setTypeCode(typeCode | TM_INNER);
674 }
675
676 // Set special flags...
677
678 setFlags();
679
680 // Set names...
681
682 Identifier id = classDef.getName();
683 String idlName;
684 String[] idlModuleNames;
685
686 try {
687
688 // These can fail if we get case-sensitive name matches...
689
690 idlName = IDLNames.getClassOrInterfaceName(id,env);
691 idlModuleNames = IDLNames.getModuleNames(id,isBoxed(),env);
692
693 setNames(id,idlModuleNames,idlName);
694
695 // Is this an exception?
696
697 if (isException()) {
698
699 // Yes, so set our mangled exception names...
700
701 isException = true;
702 idlExceptionName = IDLNames.getExceptionName(getIDLName());
703 qualifiedIDLExceptionName =
704 IDLNames.getQualifiedName(getIDLModuleNames(),idlExceptionName);
705 }
706
707 // Set interfaces, methods and members...
708
709 interfaces = null; // set in initialize()
710 methods = null; // set in initialize()
711 members = null; // set in initialize()
712
713 } catch (Exception e) {
714 failedConstraint(7,false,stack,id.toString(),e.getMessage());
715 throw new CompilerError("");
716 }
717 }
718
719 /**
720 * Initialize this instance.
721 */
722 protected boolean initialize ( Vector directInterfaces,
723 Vector directMethods,
724 Vector directMembers,
725 ContextStack stack,
726 boolean quiet) {
727
728 boolean result = true;
729
730 // Initialize our arrays...
731
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 }
738
739 if (directMethods != null && directMethods.size() > 0) {
740 methods = new Method[directMethods.size()];
741 directMethods.copyInto(methods);
742
743 // Now set the idl names for each...
744
745 try {
746 IDLNames.setMethodNames(this, methods,env);
747 } catch (Exception e) {
748 failedConstraint(13,quiet,stack,getQualifiedName(),e.getMessage());
749 result = false;
750 }
751
752 } else {
753 methods = new Method[0];
754 }
755
756 if (directMembers != null && directMembers.size() > 0) {
757 members = new Member[directMembers.size()];
758 directMembers.copyInto(members);
759
760 // If we have any un-initialized inner classes, now is the time
761 // to init them...
762
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 }
772
773 // Now set the idl names for each...
774
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 }
782
783 } else {
784 members = new Member[0];
785 }
786
787 // Set our repositoryID...
788
789 if (result) {
790 result = setRepositoryID();
791 }
792
793 return result;
794 }
795
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) {
802
803 if (stack.anyErrors()) return null;
804
805 // See if we can find this type in the cache. If so, return it...
806
807 String key = theType.toString();
808
809 Type result = getType(key,stack);
810
811 if (result != null) {
812 return result;
813 }
814
815 // Gotta try with context...
816
817 result = getType(key + stack.getContextCodeString(),stack);
818
819 if (result != null) {
820 return result;
821 }
822
823 // Gotta map it...
824
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...
838
839 result = PrimitiveType.forPrimitive(theType,stack);
840 break;
841 }
842
843 case TC_ARRAY:
844 {
845 // Array.
846
847 result = ArrayType.forArray(theType,stack);
848 break;
849 }
850
851 case TC_CLASS:
852 {
853 try {
854 // First, make sure we have the class definition...
855
856 ClassDefinition theClass = classDef;
857
858 if (theClass == null) {
859 theClass = env.getClassDeclaration(theType).getClassDefinition(env);
860 }
861
862 // Is it an interface or a class?
863
864 if (theClass.isInterface()) {
865
866 // An interface. Is it a special case?
867
868 result = SpecialInterfaceType.forSpecial(theClass,stack);
869
870 if (result == null) {
871
872 // No, does it implement java.rmi.Remote?
873
874 if (env.defRemote.implementedBy(env,theClass.getClassDeclaration())) {
875
876 // Yep, so just see if we can create an instance of RemoteType
877 // from it...
878
879 boolean parentIsValue = stack.isParentAValue();
880 result = RemoteType.forRemote(theClass,stack,parentIsValue);
881
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...
884
885 if (result == null && parentIsValue) {
886 result = NCInterfaceType.forNCInterface(theClass,stack);
887 }
888 } else {
889
890 // Nope, is it an AbstractType?
891
892 result = AbstractType.forAbstract(theClass,stack,true);
893
894 if (result == null) {
895
896 // No, so treat it as a non-conforming interface type...
897
898 result = NCInterfaceType.forNCInterface(theClass,stack);
899 }
900 }
901 }
902 } else {
903
904 // A class. Is it a special case?
905
906 result = SpecialClassType.forSpecial(theClass,stack);
907
908 if (result == null) {
909
910 ClassDeclaration classDecl = theClass.getClassDeclaration();
911
912 // Nope, does it implement java.rmi.Remote?
913
914 if (env.defRemote.implementedBy(env,classDecl)) {
915
916 // Yep, so just see if we can create an instance of
917 // ImplementationType from it...
918
919 boolean parentIsValue = stack.isParentAValue();
920 result = ImplementationType.forImplementation(theClass,stack,parentIsValue);
921
922 // If we did not succeed AND inValue is true, then
923 // go ahead and make an NC type out of it...
924
925 if (result == null && parentIsValue) {
926 result = NCClassType.forNCClass(theClass,stack);
927 }
928 } else {
929
930 // No, does it implement Serializable?
931
932 if (env.defSerializable.implementedBy(env,classDecl)) {
933
934 // Yep, so just see if we can create an instance of ValueType
935 // from it...
936
937 result = ValueType.forValue(theClass,stack,true);
938 }
939
940 if (result == null) {
941
942 // Treat it as a non-conforming class type...
943
944 result = NCClassType.forNCClass(theClass,stack);
945 }
946 }
947 }
948 }
949 } catch (ClassNotFound e) {
950 classNotFound(stack,e);
951 }
952 break;
953 }
954
955 default: throw new CompilerError("Unknown typecode (" + typeCode + ") for " + theType.getTypeSignature());
956 }
957
958 return result;
959 }
960
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();
967
968 if (exceptionType.equals(env.typeRemoteException) ||
969 exceptionType.equals(env.typeIOException) ||
970 exceptionType.equals(env.typeException) ||
971 exceptionType.equals(env.typeThrowable)) {
972
973 return true;
974 }
975 return false;
976 }
977
978 /*
979 * Check if method is conforming.
980 */
981 protected boolean isConformingRemoteMethod (Method method, boolean quiet)
982 throws ClassNotFound {
983
984 // Do we have one exception that is RemoteException or
985 // a superclass of RemoteException?
986
987 boolean haveRemote = false;
988 ClassType[] exceptions = method.getExceptions();
989
990 for (int i = 0; i < exceptions.length; i++) {
991
992 // Is it a conforming exception?
993
994 if (isRemoteException(exceptions[i],env)) {
995
996 // Got it.
997
998 haveRemote = true;
999 break;
1000 }
1001 }
1002
1003 // Do we have our exception?
1004
1005 if (!haveRemote) {
1006
1007 // No, so report failure...
1008
1009 failedConstraint(5,quiet,stack,method.getEnclosing(), method.toString());
1010 }
1011
1012 // Are any of the arguments exceptions which implement IDLEntity?
1013 // If so, report failure...
1014
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;
1022 }
1023 }
1024 }
1025
1026 return (haveRemote && noIDLEntity);
1027 }
1028
1029 protected boolean isIDLEntityException(Type type, CompoundType.Method method,boolean quiet)
1030 throws ClassNotFound {
1031 if (type.isArray()) {
1032 type = type.getElementType();
1033 }
1034 if (type.isCompound()){
1035 if (((CompoundType)type).isIDLEntityException()) {
1036 failedConstraint(18,quiet,stack,method.getEnclosing(), method.toString());
1037 return true;
1038 }
1039 }
1040 return false;
1041 }
1042
1043 /**
1044 * Convert all invalid types to valid ones.
1045 */
1046 protected void swapInvalidTypes () {
1047
1048 // Walk all interfaces and check them...
1049
1050 for (int i = 0; i < interfaces.length; i++) {
1051 if (interfaces[i].getStatus() != STATUS_VALID) {
1052 interfaces[i] = (InterfaceType)getValidType(interfaces[i]);
1053 }
1054 }
1055
1056 // Update methods...
1057
1058 for (int i = 0; i < methods.length; i++) {
1059 methods[i].swapInvalidTypes();
1060 }
1061
1062 // Update members...
1063
1064 for (int i = 0; i < members.length; i++) {
1065 members[i].swapInvalidTypes();
1066 }
1067 }
1068
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) {
1076
1077 // Check self.
1078
1079 boolean result = super.addTypes(typeCodeFilter,checked,matching);
1080
1081 // Have we been checked before?
1082
1083 if (result) {
1084
1085 // Nope, so walk parent(s) and check them...
1086
1087 ClassType parent = getSuperclass();
1088
1089 if (parent != null) {
1090 parent.addTypes(typeCodeFilter,checked,matching);
1091 }
1092
1093 // Walk all interfaces and check them...
1094
1095 //if (interfaces == null) System.out.println("NULL for " +getQualifiedName() + " interfaces");
1096 for (int i = 0; i < interfaces.length; i++) {
1097
1098 // Now recurse and add it and any referenced types...
1099
1100 //if (interfaces[i] == null) System.out.println("NULL for " +getQualifiedName() + " interfaces[" + i + "]");
1101 interfaces[i].addTypes(typeCodeFilter,checked,matching);
1102 }
1103
1104 // Walk all methods and check arguments...
1105
1106 //if (methods == null) System.out.println("NULL for " +getQualifiedName() + " methods");
1107 for (int i = 0; i < methods.length; i++) {
1108
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);
1113
1114 // Add args...
1115
1116 Type[] args = methods[i].getArguments();
1117 //if (args == null) System.out.println("NULL for " + getQualifiedName() + " args");
1118
1119 for (int j = 0; j < args.length; j++) {
1120
1121 Type arg = args[j];
1122 //if (arg == null) System.out.println("NULL for " + getQualifiedName() + " arg[" +j+"]");
1123
1124 // Add argument...
1125
1126 arg.addTypes(typeCodeFilter,checked,matching);
1127 }
1128
1129 // Add exceptions...
1130
1131 ClassType[] exceptions = methods[i].getExceptions();
1132 //if (exceptions == null) System.out.println("NULL for " + getQualifiedName() + " exceptions");
1133
1134 for (int j = 0; j < exceptions.length; j++) {
1135
1136 ClassType ex = exceptions[j];
1137
1138 // Add argument...
1139
1140 ex.addTypes(typeCodeFilter,checked,matching);
1141 }
1142 }
1143
1144 // Walk all members and add em...
1145
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");
1151
1152 // Add it...
1153
1154 cType.addTypes(typeCodeFilter,checked,matching);
1155 }
1156 }
1157
1158 return result;
1159 }
1160
1161 /*
1162 * Return true if theType is a conforming constant type.
1163 */
1164 private boolean isConformingConstantType (MemberDefinition member) {
1165 return isConformingConstantType(member.getType(),member);
1166 }
1167
1168 /*
1169 * Return true if theType is a conforming constant type.
1170 */
1171 private boolean isConformingConstantType (sun.tools.java.Type theType,MemberDefinition member) {
1172
1173 // Constraint 3: Constants must be either primitives or String.
1174
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...
1186 {
1187 break;
1188 }
1189
1190 case TC_CLASS: // Must be java.lang.String
1191 {
1192 if (theType.getClassName() != idJavaLangString) {
1193 failedConstraint(3,false,stack,member.getClassDefinition(),member.getName());
1194 result = false;
1195 }
1196 break;
1197 }
1198
1199 case TC_ARRAY: // Array constants are not allowed.
1200 {
1201 failedConstraint(3,false,stack,member.getClassDefinition(),member.getName());
1202 result = false;
1203 break;
1204 }
1205
1206 default:
1207 throw new Error("unexpected type code: " + typeCode);
1208 }
1209
1210 return result;
1211 }
1212
1213
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 {
1230
1231 ClassDeclaration parentDecl = current.getSuperClass(env);
1232
1233 while (parentDecl != null) {
1234
1235 ClassDefinition parentDef = parentDecl.getClassDefinition(env);
1236 Identifier currentID = parentDecl.getName();
1237
1238 if ( currentID == idJavaLangObject ) break;
1239
1240 // Walk all members of this class and update any that
1241 // already exist in currentMethods...
1242
1243 for (MemberDefinition member = parentDef.getFirstMember();
1244 member != null;
1245 member = member.getNextMember()) {
1246
1247 if (member.isMethod() &&
1248 !member.isInitializer() &&
1249 !member.isConstructor() &&
1250 !member.isPrivate()) {
1251
1252 // It's a method. Is it valid?
1253
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;
1260 }
1261
1262 // Have we already seen it?
1263
1264 int index = currentMethods.indexOf(method);
1265 if (index >= 0) {
1266
1267 // Yes, so update it...
1268
1269 Method currentMethod = (Method)currentMethods.elementAt(index);
1270 currentMethod.setDeclaredBy(currentID);
1271 }
1272 else currentMethods.addElement(method);
1273 }
1274 }
1275
1276 // Update parent and keep walking up the chain...
1277
1278 parentDecl = parentDef.getSuperClass(env);
1279 }
1280
1281 return currentMethods;
1282 }
1283
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 {
1301
1302 // Constraint 6: Multiple inherited interfaces may not
1303 // declare the same method.
1304
1305 ClassDeclaration[] interfaces = current.getInterfaces();
1306
1307 // We want to add members starting at the _least_ derived
1308 // interfaces. To do so, recurse until we have no more
1309 // interfaces...
1310
1311 for (int i = 0; i < interfaces.length; i++) {
1312
1313 Vector result = addAllMethods(interfaces[i].getClassDefinition(env),
1314 directMethods,
1315 noMultiInheritedMethods,quiet,stack);
1316 if (result == null) {
1317 return null;
1318 }
1319 }
1320
1321 // Walk all members of this interface, adding any unique methods
1322 // other than initializers and private methods...
1323
1324 for (MemberDefinition member = current.getFirstMember();
1325 member != null;
1326 member = member.getNextMember())
1327 {
1328 if (member.isMethod() &&
1329 !member.isInitializer() &&
1330 !member.isPrivate()) {
1331
1332 // It's a method. Is it valid?
1333
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;
1340 }
1341
1342 // Have we already seen it?
1343
1344 if (!directMethods.contains(method)) {
1345
1346 // Nope, so add it...
1347
1348 directMethods.addElement(method);
1349
1350 } else {
1351
1352 // Yes. This is an error unless we are looking at the
1353 // target interface (or this is a ValueType). Are we?
1354
1355 if (noMultiInheritedMethods && current != classDef &&
1356 !stack.isParentAValue() && !stack.getContext().isValue()) {
1357
1358 // Nope. Say so and signal error by returning null..
1359
1360 Method existingMethod = (Method) directMethods.elementAt(directMethods.indexOf(method));
1361 ClassDefinition existingMemberClassDef = existingMethod.getMemberDefinition().getClassDefinition();
1362
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))
1369 {
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;
1376 }
1377 }
1378
1379 // Bug fix 5014329
1380
1381 // find a matching method.
1382 int index = directMethods.indexOf(method);
1383 Method other = (Method) directMethods.get(index);
1384
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);
1389
1390 // replace the old method with the new.
1391 directMethods.set(index, newMethod);
1392 }
1393 }
1394 }
1395
1396 return directMethods;
1397 }
1398
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;
1404
1405 ClassDefinition superDef;
1406 if (def.getSuperClass() != null) {
1407 superDef = def.getSuperClass().getClassDefinition();
1408 if (inheritsFrom(superDef, otherDef))
1409 return true;
1410 }
1411
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;
1417 }
1418 return false;
1419 }
1420
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 {
1428
1429 // Add all the interfaces of current...
1430
1431 ClassDefinition theInterface = getClassDefinition();
1432 ClassDeclaration[] interfaces = theInterface.getInterfaces();
1433
1434 stack.setNewContextCode(ContextStack.IMPLEMENTS);
1435
1436 for (int i = 0; i < interfaces.length; i++) {
1437
1438 ClassDefinition def = interfaces[i].getClassDefinition(env);
1439
1440 // Is it a SpecialInterfaceType...
1441
1442 InterfaceType it = SpecialInterfaceType.forSpecial(def,stack);;
1443
1444 if (it == null) {
1445
1446 // No, is it Remote?
1447
1448 if (env.defRemote.implementedBy(env, interfaces[i])) {
1449
1450 // Yes, so it must be a RemoteType.
1451
1452 it = RemoteType.forRemote(def,stack,false);
1453
1454 } else {
1455
1456 // Then try Abstract...
1457
1458 it = AbstractType.forAbstract(def,stack,true);
1459
1460 if (it == null && allowNonConforming) {
1461
1462 // Must be non-conforming...
1463
1464 it = NCInterfaceType.forNCInterface(def,stack);
1465 }
1466 }
1467 }
1468
1469 if (it != null) {
1470 list.addElement(it);
1471 } else {
1472 return null;
1473 }
1474 }
1475
1476 return list;
1477 }
1478
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 {
1485
1486 // Add all the interfaces of current...
1487
1488 ClassDefinition theInterface = getClassDefinition();
1489 ClassDeclaration[] interfaces = theInterface.getInterfaces();
1490
1491 stack.setNewContextCode(ContextStack.IMPLEMENTS);
1492
1493 for (int i = 0; i < interfaces.length; i++) {
1494
1495 ClassDefinition def = interfaces[i].getClassDefinition(env);
1496
1497 // First try SpecialInterfaceType...
1498
1499 InterfaceType it = SpecialInterfaceType.forSpecial(def,stack);
1500
1501 if (it == null) {
1502
1503 // Then try AbstractType...
1504
1505 it = AbstractType.forAbstract(def,stack,true);
1506
1507 if (it == null) {
1508
1509 // Then try NCInterfaceType...
1510
1511 it = NCInterfaceType.forNCInterface(def,stack);
1512 }
1513 }
1514
1515 if (it != null) {
1516 list.addElement(it);
1517 } else {
1518 return null;
1519 }
1520 }
1521
1522 return list;
1523 }
1524
1525
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) {
1534
1535 boolean result = true;
1536
1537 // Walk all members of this interface...
1538
1539 for (MemberDefinition member = getClassDefinition().getFirstMember();
1540 member != null && result;
1541 member = member.getNextMember())
1542 {
1543 if (!member.isMethod()) {
1544
1545 try {
1546 String value = null;
1547
1548 // Prod it to setValue if it is a constant...
1549
1550 member.getValue(env);
1551
1552 // Get the value, if any...
1553
1554 Node node = member.getValue();
1555
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();
1565 }
1566 }
1567
1568 // Are we supposed to allow only conforming constants?
1569
1570 if (onlyConformingConstants && member.getInnerClass() == null) {
1571
1572 // Yep, so check it...
1573
1574 if (value == null || !isConformingConstantType(member)) {
1575 failedConstraint(3,quiet,stack,member.getClassDefinition(),member.getName());
1576 result = false;
1577 break;
1578 }
1579 }
1580
1581 // Make member and add to list...
1582
1583 try {
1584 Member newMember = new Member(member,value,stack,this);
1585 allMembers.addElement(newMember);
1586 } catch (CompilerError e) {
1587 result = false;
1588 }
1589
1590 } catch (ClassNotFound e) {
1591 classNotFound(stack,e);
1592 result = false;
1593 }
1594 }
1595 }
1596
1597 return result;
1598 }
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) {
1606
1607 boolean result = true;
1608
1609 // Walk all members of this interface...
1610
1611 for (MemberDefinition member = getClassDefinition().getFirstMember();
1612 member != null && result;
1613 member = member.getNextMember())
1614 {
1615 if (!member.isMethod()) {
1616
1617 try {
1618 String value = null;
1619
1620 // Prod it to setValue if it is a constant...
1621
1622 member.getValue(env);
1623
1624 // Get the value, if any...
1625
1626 Node node = member.getValue();
1627
1628 if (node != null) {
1629 value = node.toString();
1630 }
1631
1632
1633 // Is it a constant?
1634
1635 if (value != null) {
1636
1637 // Yes, is it conforming?
1638
1639 if (!isConformingConstantType(member)) {
1640 failedConstraint(3,quiet,stack,member.getClassDefinition(),member.getName());
1641 result = false;
1642 break;
1643 }
1644
1645 // Yes, so make a member and add to list...
1646
1647 try {
1648 Member newMember = new Member(member,value,stack,this);
1649 allMembers.addElement(newMember);
1650 } catch (CompilerError e) {
1651 result = false;
1652 }
1653 }
1654 } catch (ClassNotFound e) {
1655 classNotFound(stack,e);
1656 result = false;
1657 }
1658 }
1659 }
1660
1661 return result;
1662 }
1663
1664 protected ValueType[] getMethodExceptions (MemberDefinition member,
1665 boolean quiet,
1666 ContextStack stack) throws Exception {
1667
1668 boolean result = true;
1669 stack.setNewContextCode(ContextStack.METHOD_EXCEPTION);
1670 ClassDeclaration[] except = member.getExceptions(env);
1671 ValueType[] exceptions = new ValueType[except.length];
1672
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;
1682 }
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");
1689 }
1690 }
1691 } catch (ClassNotFound e) {
1692 classNotFound(quiet,stack,e);
1693 result = false;
1694 }
1695
1696 if (!result) {
1697 throw new Exception();
1698 }
1699
1700 // Remove any duplicates (javac seems to allow them, but rmic will
1701 // generate bad ties)...
1702
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++;
1709 }
1710 }
1711 }
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];
1718 }
1719 }
1720 exceptions = temp;
1721 }
1722
1723 return exceptions;
1724 }
1725
1726
1727 protected static String getVisibilityString (MemberDefinition member) {
1728 String vis = "";
1729 String prefix = "";
1730
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 = " ";
1740 }
1741
1742 if (member.isStatic()) {
1743 vis += prefix;
1744 vis += "static";
1745 prefix = " ";
1746 }
1747
1748 if (member.isFinal()) {
1749 vis += prefix;
1750 vis += "final";
1751 prefix = " ";
1752 }
1753
1754 return vis;
1755 }
1756
1757 protected boolean assertNotImpl(Type type,
1758 boolean quiet,
1759 ContextStack stack,
1760 CompoundType enclosing,
1761 boolean dataMember) {
1762
1763 if (type.isType(TYPE_IMPLEMENTATION)) {
1764 int constraint = dataMember ? 28 : 21;
1765 failedConstraint(constraint,quiet,stack,type,enclosing.getName());
1766 return false;
1767 }
1768 return true;
1769 }
1770
1771 //_____________________________________________________________________
1772 // Inner Class "Method"
1773 //_____________________________________________________________________
1774
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 {
1781
1782 /**
1783 * Is this method inherited?
1784 */
1785 public boolean isInherited () {
1786 return declaredBy != enclosing.getIdentifier();
1787 }
1788
1789 /**
1790 * Is this method an attribute?
1791 * Return true if getAttributeKind != ATTRIBUTE_NONE.
1792 */
1793 public boolean isAttribute () {
1794 return attributeKind != ATTRIBUTE_NONE;
1795 }
1796
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;
1803 }
1804
1805 /**
1806 * Return the attribute kind.
1807 */
1808 public int getAttributeKind() {
1809 return attributeKind;
1810 }
1811
1812 /**
1813 * Return the attribute name. Will be null if
1814 * attribute kind == ATTRIBUTE_NONE.
1815 */
1816 public String getAttributeName() {
1817 return attributeName;
1818 }
1819
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;
1827 }
1828
1829 /**
1830 * Return context element name.
1831 */
1832 public String getElementName() {
1833 return memberDef.toString();
1834 }
1835
1836 /**
1837 * Equality check based on method signature.
1838 */
1839 public boolean equals(Object obj) {
1840 Method other = (Method) obj;
1841
1842 if (getName().equals(other.getName()) &&
1843 arguments.length == other.arguments.length) {
1844
1845 for (int i = 0; i < arguments.length; i++) {
1846 if (! arguments[i].equals(other.arguments[i])) {
1847 return false;
1848 }
1849 }
1850 return true;
1851 }
1852 return false;
1853 }
1854
1855 public int hashCode() {
1856 return getName().hashCode() ^ Arrays.hashCode(arguments);
1857 }
1858
1859 /**
1860 * Return a new Method object that is a legal combination of
1861 * this method object and another one.
1862 *
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());
1871 }
1872
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;
1883 }
1884
1885 Method merged = (Method) clone();
1886 merged.exceptions = new ValueType[legalExceptions.size()];
1887 legalExceptions.copyInto(merged.exceptions);
1888 merged.implExceptions = merged.exceptions;
1889
1890 return merged;
1891 }
1892
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 {
1900
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;
1910 }
1911 }
1912 }
1913 }
1914 }
1915
1916 /**
1917 * Return the compound type which contains this method.
1918 */
1919 public CompoundType getEnclosing() {
1920 return enclosing;
1921 }
1922
1923 /**
1924 * Return the identifier for the class or interface which
1925 * declares this method.
1926 */
1927 public Identifier getDeclaredBy() {
1928 return declaredBy;
1929 }
1930
1931 /**
1932 * Return the visibility (e.g. "public final") of this member.
1933 */
1934 public String getVisibility() {
1935 return vis;
1936 }
1937
1938 /**
1939 * Methods to check various attributes.
1940 */
1941 public boolean isPublic() {
1942 return memberDef.isPublic();
1943 }
1944
1945 public boolean isProtected() {
1946 return memberDef.isPrivate();
1947 }
1948
1949 public boolean isPrivate() {
1950 return memberDef.isPrivate();
1951 }
1952
1953 public boolean isStatic() {
1954 return memberDef.isStatic();
1955 }
1956
1957 /**
1958 * Return the name of this method.
1959 */
1960 public String getName() {
1961 return name;
1962 }
1963
1964 /**
1965 * IDL_Naming
1966 * Return the IDL name of this method.
1967 */
1968 public String getIDLName() {
1969 return idlName;
1970 }
1971
1972 /**
1973 * Return the type of this method.
1974 */
1975 public sun.tools.java.Type getType() {
1976 return memberDef.getType();
1977 }
1978
1979 /**
1980 * Return true if this is a constructor.
1981 */
1982 public boolean isConstructor () {
1983 return memberDef.isConstructor();
1984 }
1985
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;
1992 }
1993
1994 /**
1995 * Get the return type of this method. May be null.
1996 */
1997 public Type getReturnType() {
1998 return returnType;
1999 }
2000
2001 /**
2002 * Return the argument types of this method.
2003 */
2004 public Type[] getArguments() {
2005 return (Type[]) arguments.clone();
2006 }
2007
2008 /**
2009 * Return the names of the argument types of this method.
2010 */
2011 public String[] getArgumentNames() {
2012 return argumentNames;
2013 }
2014
2015 /**
2016 * Return the MemberDefinition from which this method was created.
2017 */
2018 public MemberDefinition getMemberDefinition() {
2019 return memberDef;
2020 }
2021
2022 /**
2023 * Return an array of the exception classes declared to be
2024 * thrown by this remote method.
2025 *
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();
2033 }
2034
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();
2041 }
2042
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;
2054
2055 try {
2056
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--;
2065 }
2066 }
2067
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--;
2077 }
2078 }
2079 }
2080 }
2081
2082 } catch (ClassNotFound e) {
2083 classNotFound(stack,e); // Report error but do not stop.
2084 }
2085
2086 // Create new list if we removed anything...
2087
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];
2094 }
2095 }
2096 list = temp;
2097 }
2098
2099 if (list.length == 0) {
2100 return null;
2101 } else {
2102 return list;
2103 }
2104 }
2105
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;
2117
2118 try {
2119
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--;
2128 }
2129 }
2130
2131 } catch (ClassNotFound e) {
2132 classNotFound(stack,e); // Report error but do not stop.
2133 }
2134
2135 // Create new list if we removed anything...
2136
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];
2143 }
2144 }
2145 list = temp;
2146 }
2147
2148 return list;
2149 }
2150
2151 /**
2152 * Return the string representation of this method.
2153 */
2154 public String toString() {
2155
2156 if (stringRep == null) {
2157
2158 StringBuffer result = new StringBuffer(returnType.toString());
2159
2160 // Add name...
2161
2162 result.append(" ");
2163 result.append(getName());
2164 result.append(" (");
2165
2166 // Add arguments...
2167
2168 for (int i = 0; i < arguments.length; i++) {
2169 if (i > 0) {
2170 result.append(", ");
2171 }
2172 result.append(arguments[i]);
2173 result.append(" ");
2174 result.append(argumentNames[i]);
2175 }
2176
2177 result.append(")");
2178
2179 // Add exceptions...
2180
2181 for (int i = 0; i < exceptions.length; i++) {
2182 if (i == 0) {
2183 result.append(" throws ");
2184 } else {
2185 result.append(", ");
2186 }
2187 result.append(exceptions[i]);
2188 }
2189
2190 result.append(";");
2191
2192 stringRep = result.toString();
2193 }
2194
2195 return stringRep;
2196 }
2197
2198
2199 /**
2200 * Set attribute kind. May only be called during initialization.
2201 */
2202 public void setAttributeKind(int kind) {
2203 attributeKind = kind;
2204 }
2205
2206 /**
2207 * Set pair index. May only be called during initialization.
2208 */
2209 public void setAttributePairIndex(int index) {
2210 attributePairIndex = index;
2211 }
2212
2213 /**
2214 * Set attribute name. May only be called during initialization.
2215 */
2216 public void setAttributeName(String name) {
2217 attributeName = name;
2218 }
2219
2220 /**
2221 * Set the idl name. May only be called during initialization.
2222 */
2223 public void setIDLName (String idlName) {
2224 this.idlName=idlName;
2225 }
2226
2227 /**
2228 * Set the implExceptions array. May only be called during initialization.
2229 */
2230 public void setImplExceptions (ValueType[] exceptions) {
2231 implExceptions = exceptions;
2232 }
2233
2234 /**
2235 * Set the declaredBy Identifier. May only be called during initialization.
2236 */
2237 public void setDeclaredBy (Identifier by) {
2238 declaredBy = by;
2239 }
2240
2241 /**
2242 * Convert all invalid types to valid ones.
2243 */
2244 protected void swapInvalidTypes () {
2245
2246 // Check return type...
2247
2248 if (returnType.getStatus() != STATUS_VALID) {
2249 returnType = getValidType(returnType);
2250 }
2251
2252 // Check args...
2253
2254 for (int i = 0; i < arguments.length; i++) {
2255 if (arguments[i].getStatus() != STATUS_VALID) {
2256 arguments[i] = getValidType(arguments[i]);
2257 }
2258 }
2259
2260 // Check exceptions...
2261
2262 for (int i = 0; i < exceptions.length; i++) {
2263 if (exceptions[i].getStatus() != STATUS_VALID) {
2264 exceptions[i] = (ValueType)getValidType(exceptions[i]);
2265 }
2266 }
2267
2268 // Check implExceptions...
2269
2270 for (int i = 0; i < implExceptions.length; i++) {
2271 if (implExceptions[i].getStatus() != STATUS_VALID) {
2272 implExceptions[i] = (ValueType)getValidType(implExceptions[i]);
2273 }
2274 }
2275 }
2276
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;
2288 }
2289 exceptions = null;
2290 }
2291
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;
2296 }
2297 implExceptions = null;
2298 }
2299
2300 if (returnType != null) returnType.destroy();
2301 returnType = null;
2302
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;
2307 }
2308 arguments = null;
2309 }
2310
2311 if (argumentNames != null) {
2312 for (int i = 0; i < argumentNames.length; i++) {
2313 argumentNames[i] = null;
2314 }
2315 argumentNames = null;
2316 }
2317
2318 vis = null;
2319 name = null;
2320 idlName = null;
2321 stringRep = null;
2322 attributeName = null;
2323 declaredBy = null;
2324 }
2325 }
2326
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;
2342
2343 /**
2344 * Make up an argument name for the given type.
2345 */
2346 private String makeArgName (int argNum, Type type) {
2347 return "arg" + argNum;
2348 }
2349
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 {
2358
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();
2365
2366 // Set name...
2367
2368 name = memberDef.getName().toString();
2369
2370 // Update the context...
2371
2372 stack.setNewContextCode(ContextStack.METHOD);
2373 stack.push(this);
2374
2375 // Set return type...
2376
2377 stack.setNewContextCode(ContextStack.METHOD_RETURN);
2378 sun.tools.java.Type methodType = memberDef.getType();
2379 sun.tools.java.Type rtnType = methodType.getReturnType();
2380
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());
2389 }
2390 }
2391
2392 // Set arguments and argument names...
2393
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();
2399
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) {
2405 }
2406
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);
2417 }
2418 }
2419 } else {
2420 valid = false;
2421 failedConstraint(25,false,stack,enclosing.getQualifiedName(),name);
2422 }
2423 }
2424
2425 if (!valid) {
2426 stack.pop(false);
2427 throw new Exception();
2428 }
2429
2430 // Set exceptions...
2431
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();
2439 }
2440 }
2441
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");
2450 }
2451 }
2452 }
2453
2454 //_____________________________________________________________________
2455 // Inner Class "Member"
2456 //_____________________________________________________________________
2457
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 {
2463
2464 /**
2465 * Return context element name.
2466 */
2467 public String getElementName() {
2468 return "\"" + getName() + "\"";
2469 }
2470
2471 /**
2472 * Return the type of this member.
2473 */
2474 public Type getType() {
2475 return type;
2476 }
2477
2478 /**
2479 * Return the name of this member.
2480 */
2481 public String getName() {
2482 return name;
2483 }
2484
2485 /**
2486 * IDL_Naming
2487 * Return the IDL name of this member.
2488 */
2489 public String getIDLName() {
2490 return idlName;
2491 }
2492
2493 /**
2494 * Return the visibility (e.g. "public final") of this member.
2495 */
2496 public String getVisibility() {
2497 return vis;
2498 }
2499
2500 /**
2501 * Methods to check various attributes.
2502 */
2503 public boolean isPublic() {
2504 return member.isPublic();
2505 }
2506
2507 public boolean isPrivate() {
2508 return member.isPrivate();
2509 }
2510
2511 public boolean isStatic() {
2512 return member.isStatic();
2513 }
2514
2515 public boolean isFinal() {
2516 return member.isFinal();
2517 }
2518
2519 public boolean isTransient() {
2520 if (forceTransient) return true;
2521 return member.isTransient();
2522 }
2523
2524 /**
2525 * Return the value of this member. May be null.
2526 */
2527 public String getValue() {
2528 return value;
2529 }
2530
2531 /**
2532 * Return true if this member represents an inner class declaration,
2533 * false otherwise.
2534 */
2535 public boolean isInnerClassDeclaration() {
2536 return innerClassDecl;
2537 }
2538
2539 /**
2540 * Return true if this member represents a constant.
2541 */
2542 public boolean isConstant () {
2543 return constant;
2544 }
2545
2546 /**
2547 * Return the string representation of this constant.
2548 */
2549 public String toString() {
2550
2551 String result = type.toString();
2552
2553 if (value != null) {
2554 result += (" = " + value);
2555 }
2556
2557 return result;
2558 }
2559
2560 /**
2561 * Convert all invalid types to valid ones.
2562 */
2563 protected void swapInvalidTypes () {
2564 if (type.getStatus() != STATUS_VALID) {
2565 type = getValidType(type);
2566 }
2567 }
2568
2569 protected void setTransient() {
2570 if (! isTransient()) {
2571 forceTransient = true;
2572 if (vis.length() > 0) {
2573 vis = vis + " transient";
2574 } else {
2575 vis = "transient";
2576 }
2577 }
2578 }
2579
2580 protected MemberDefinition getMemberDefinition() {
2581 return member;
2582 }
2583
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;
2596 }
2597 }
2598
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;
2608
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;
2620
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...
2624
2625 if (!innerClassDecl) {
2626 init (stack,enclosing);
2627 }
2628 }
2629
2630 public void init (ContextStack stack, CompoundType enclosing) {
2631
2632 constant = false;
2633 name = member.getName().toString();
2634 vis = getVisibilityString(member);
2635 idlName = null;
2636
2637 // Add self to stack...
2638
2639 int contextCode = ContextStack.MEMBER;
2640 stack.setNewContextCode(contextCode);
2641
2642 // Check for special contextCodes...
2643
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;
2652 }
2653 }
2654
2655 stack.setNewContextCode(contextCode);
2656 stack.push(this);
2657
2658 type = makeType(member.getType(),null,stack);
2659
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("");
2667 }
2668
2669 // Clean up primitive constant values...
2670
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);
2677 }
2678 } else if (type.isType(TYPE_BOOLEAN)) {
2679 value = value.toUpperCase();
2680 }
2681 }
2682 if (constant && type.isType(TYPE_STRING)) {
2683 value = "L" + value;
2684 }
2685 stack.pop(true);
2686 }
2687
2688 public void setIDLName (String name) {
2689 this.idlName = name;
2690 }
2691
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");
2700 }
2701 }
2702 }
2703 }

mercurial