src/share/classes/sun/rmi/rmic/iiop/IDLNames.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.Hashtable;
36 import java.util.Locale;
37 import sun.tools.java.Identifier;
38 import sun.tools.java.CompilerError;
39 import sun.tools.java.ClassDefinition;
40 import sun.tools.java.ClassNotFound;
41 import com.sun.corba.se.impl.util.RepositoryId;
42
43 /**
44 * IDLNames provides static utility methods to perform the IDL
45 * name mappings specified in Chapter 5 of the Java Language
46 * to IDL specification.
47 *
48 * @author Bryan Atsatt
49 */
50 public class IDLNames implements sun.rmi.rmic.iiop.Constants {
51
52 /**
53 * Used to convert ascii to hex.
54 */
55 public static final byte ASCII_HEX[] = {
56 (byte)'0',
57 (byte)'1',
58 (byte)'2',
59 (byte)'3',
60 (byte)'4',
61 (byte)'5',
62 (byte)'6',
63 (byte)'7',
64 (byte)'8',
65 (byte)'9',
66 (byte)'A',
67 (byte)'B',
68 (byte)'C',
69 (byte)'D',
70 (byte)'E',
71 (byte)'F',
72 };
73
74 //_____________________________________________________________________
75 // Public Interfaces
76 //_____________________________________________________________________
77
78 /**
79 * Convert a name. The nameContext argument MUST be pre-filled with
80 * all names from the appropriate context (e.g. all the method names
81 * in a given class). The names must not have had any IDL conversions
82 * applied.
83 * <p>
84 * Section 28.3.2.2
85 * Section 28.3.2.3
86 * Section 28.3.2.4
87 * Section 28.3.2.7 (member and method names only)
88 */
89 public static String getMemberOrMethodName (NameContext nameContext,
90 String name,
91 BatchEnvironment env) {
92
93 // Check namesCache...
94
95 String result = (String) env.namesCache.get(name);
96
97 if (result == null) {
98
99 // 28.3.2.7 Case sensitive member names.
100
101 // Note: This must be done before any of
102 // the other conversions!
103
104 result = nameContext.get(name);
105
106 // 28.3.2.3 Leading underscores...
107
108 result = convertLeadingUnderscores(result);
109
110 // 28.3.2.2 IDL keywords (NOTE: must be done
111 // after leading underscore conversion because
112 // the mangling for IDL keywords creates a
113 // leading underscore!)...
114
115 result = convertIDLKeywords(result);
116
117 // 28.3.2.4 Illegal IDL identifier characters...
118
119 result = convertToISOLatin1(result);
120
121 // Add to namesCache...
122
123 env.namesCache.put(name,result);
124 }
125
126 return result;
127 }
128
129 /**
130 * Convert names with illegal IDL identifier characters.
131 * <p>
132 * Section 28.3.2.4
133 */
134 public static String convertToISOLatin1 (String name) {
135
136 // First, replace any escape sequences...
137
138 String result = replace(name,"x\\u","U");
139 result = replace(result,"x\\U","U");
140
141 // Now see if we have any remaining illegal characters (see
142 // RepositoryId.IDL_IDENTIFIER_CHARS array)...
143
144 int length = result.length();
145 StringBuffer buffer = null;
146
147 for (int i = 0; i < length; i++) {
148
149 char c = result.charAt(i);
150
151 if (c > 255 || RepositoryId.IDL_IDENTIFIER_CHARS[c] == 0) {
152
153 // We gotta convert. Have we already started?
154
155 if (buffer == null) {
156
157 // No, so get set up...
158
159 buffer = new StringBuffer(result.substring(0,i));
160 }
161
162 // Convert the character into the IDL escape syntax...
163
164 buffer.append("U");
165 buffer.append((char)ASCII_HEX[(c & 0xF000) >>> 12]);
166 buffer.append((char)ASCII_HEX[(c & 0x0F00) >>> 8]);
167 buffer.append((char)ASCII_HEX[(c & 0x00F0) >>> 4]);
168 buffer.append((char)ASCII_HEX[(c & 0x000F)]);
169
170 } else {
171 if (buffer != null) {
172 buffer.append(c);
173 }
174 }
175 }
176
177 if (buffer != null) {
178 result = buffer.toString();
179 }
180
181 return result;
182 }
183
184 /**
185 * Convert names which collide with IDL keywords.
186 * <p>
187 * Section 28.3.2.5
188 */
189 public static String convertIDLKeywords (String name) {
190
191 for (int i = 0; i < IDL_KEYWORDS.length; i++) {
192 if (name.equalsIgnoreCase(IDL_KEYWORDS[i])) {
193 return "_" + name;
194 }
195 }
196
197 return name;
198 }
199
200 /**
201 * Convert names which have leading underscores
202 * <p>
203 * Section 28.3.2.3
204 */
205 public static String convertLeadingUnderscores (String name) {
206
207 if (name.startsWith("_")) {
208 return "J" + name;
209 }
210
211 return name;
212 }
213
214 /**
215 * Convert a type name.
216 * <p>
217 * Section 28.3.2.5
218 * Section 28.3.2.7 (class or interface names only)
219 * Throws exception if fails 28.3.2.7.
220 */
221 public static String getClassOrInterfaceName (Identifier id,
222 BatchEnvironment env) throws Exception {
223
224 // Get the type and package name...
225
226 String typeName = id.getName().toString();
227 String packageName = null;
228
229 if (id.isQualified()) {
230 packageName = id.getQualifier().toString();
231 }
232
233 // Check namesCache...
234
235 String result = (String) env.namesCache.get(typeName);
236
237 if (result == null) {
238
239 // 28.3.2.5 Inner classes...
240
241 result = replace(typeName,". ","__");
242
243 // 28.3.2.4 Illegal identifier characters...
244
245 result = convertToISOLatin1(result);
246
247 // 28.3.2.7 Case sensitive class or interface names...
248
249 NameContext context = NameContext.forName(packageName,false,env);
250 context.assertPut(result);
251
252 // Run it through the name checks...
253
254 result = getTypeOrModuleName(result);
255
256 // Add it to the namesCache...
257
258 env.namesCache.put(typeName,result);
259 }
260
261 return result;
262 }
263
264 /**
265 * Convert an Exception name.
266 * <p>
267 * Section 28.3.7.2 (see ValueType)
268 */
269 public static String getExceptionName (String idlName) {
270
271 String result = idlName;
272 // d.11315 Incorrectly mangled exception names
273 if (idlName.endsWith(EXCEPTION_SUFFIX)) {
274
275 // Remove "Exception" and append "Ex". Strip leading underscore
276 // in case the idlName is exactly "_Exception"...
277
278 result = stripLeadingUnderscore(idlName.substring(0,idlName.lastIndexOf(EXCEPTION_SUFFIX)) + EX_SUFFIX);
279 } else {
280 result = idlName + EX_SUFFIX;
281 }
282
283 return result;
284 }
285
286 /**
287 * Convert a qualified Identifier into an array of IDL names.
288 * <p>
289 * Section 28.3.2.1 (see CompoundType)
290 * Throws exception if fails 28.3.2.7.
291 */
292 public static String[] getModuleNames (Identifier theID,
293 boolean boxIt,
294 BatchEnvironment env) throws Exception {
295
296 String[] result = null;
297
298 if (theID.isQualified()) {
299
300 // Extract the qualifier...
301
302 Identifier id = theID.getQualifier();
303
304 // 28.3.2.7 Case sensitive module names.
305
306 env.modulesContext.assertPut(id.toString());
307
308 // Count them...
309
310 int count = 1;
311 Identifier current = id;
312 while (current.isQualified()) {
313 current = current.getQualifier();
314 count++;
315 }
316
317 result = new String[count];
318 int index = count-1;
319 current = id;
320
321 // Now walk them and fill our array (backwards)...
322
323 for (int i = 0; i < count; i++) {
324
325 String item = current.getName().toString();
326
327 // Check namesCache...
328
329 String cachedItem = (String) env.namesCache.get(item);
330
331 if (cachedItem == null) {
332
333 // 28.3.2.4 Illegal identifier characters...
334
335 cachedItem = convertToISOLatin1(item);
336
337 // Run it through the name checks...
338
339 cachedItem = getTypeOrModuleName(cachedItem);
340
341 // Add it to the namesCache...
342
343 env.namesCache.put(item,cachedItem);
344 }
345
346 result[index--] = cachedItem;
347 current = current.getQualifier();
348 }
349 }
350
351
352 // If it is supposed to be "boxed", prepend
353 // IDL_BOXEDIDL_MODULE...
354
355 if (boxIt) {
356 if (result == null) {
357 result = IDL_BOXEDIDL_MODULE;
358 } else {
359 String[] boxed = new String[result.length+IDL_BOXEDIDL_MODULE.length];
360 System.arraycopy(IDL_BOXEDIDL_MODULE,0,boxed,0,IDL_BOXEDIDL_MODULE.length);
361 System.arraycopy(result,0,boxed,IDL_BOXEDIDL_MODULE.length,result.length);
362 result = boxed;
363 }
364 }
365
366 return result;
367 }
368
369 /**
370 * Get an array name with the specified dimensions.
371 * <p>
372 * Section 28.3.6 (see ArrayType)
373 */
374 public static String getArrayName (Type theType, int arrayDimension) {
375
376 StringBuffer idlName = new StringBuffer(64);
377
378 // Prefix with seq<n>_...
379
380 idlName.append(IDL_SEQUENCE);
381 idlName.append(Integer.toString(arrayDimension));
382 idlName.append("_");
383
384 // Add the type name. We need to map any spaces in the
385 // name to "_"...
386
387 idlName.append(replace(stripLeadingUnderscore(theType.getIDLName())," ","_"));
388
389 // And we're done...
390
391 return idlName.toString();
392 }
393
394 /**
395 * Get an array module names.
396 */
397 public static String[] getArrayModuleNames (Type theType) {
398
399 String[] moduleName;
400 String[] typeModule = theType.getIDLModuleNames();
401 int typeModuleLength = typeModule.length;
402
403 // Does the type have a module?
404
405 if (typeModuleLength == 0) {
406
407 // Nope, so just use the sequence module...
408
409 moduleName = IDL_SEQUENCE_MODULE;
410 } else {
411
412 // Yes, so gotta concatenate...
413
414 moduleName = new String[typeModuleLength + IDL_SEQUENCE_MODULE.length];
415 System.arraycopy(IDL_SEQUENCE_MODULE,0,moduleName,0,IDL_SEQUENCE_MODULE.length);
416 System.arraycopy(typeModule,0,moduleName,IDL_SEQUENCE_MODULE.length,typeModuleLength);
417 }
418
419 return moduleName;
420 }
421
422 private static int getInitialAttributeKind (CompoundType.Method method,
423 BatchEnvironment env) throws ClassNotFound {
424
425 int result = ATTRIBUTE_NONE;
426
427 // First make sure it is not a constructor...
428
429 if (!method.isConstructor()) {
430
431 // Now check exceptions. It may not throw any checked
432 // exception other than RemoteException or one of its
433 // subclasses...
434
435 boolean validExceptions = true;
436 ClassType[] exceptions = method.getExceptions();
437
438 if (exceptions.length > 0) {
439 for (int i = 0; i < exceptions.length; i++) {
440 if (exceptions[i].isCheckedException() &&
441 !exceptions[i].isRemoteExceptionOrSubclass()) {
442 validExceptions = false;
443 break;
444 }
445 }
446 } else {
447
448 // If this is a ValueType, it is ok to not have any exceptions,
449 // otherwise this method does not qualify...
450
451 validExceptions = method.getEnclosing().isType(TYPE_VALUE);
452 }
453
454 if (validExceptions) {
455 String name = method.getName();
456 int nameLength = name.length();
457 int argCount = method.getArguments().length;
458 Type returnType = method.getReturnType();
459 boolean voidReturn = returnType.isType(TYPE_VOID);
460 boolean booleanReturn = returnType.isType(TYPE_BOOLEAN);
461
462 // It's a getter if name starts with "get" and it has no arguments
463 // and a return type that is not void...
464
465 if (name.startsWith("get") && nameLength > 3 && argCount == 0 && !voidReturn) {
466 result = ATTRIBUTE_GET;
467 } else {
468
469 // It's a getter if name starts with "is" and it has no arguments
470 // and a boolean return type...
471
472 if (name.startsWith("is") && nameLength > 2 && argCount == 0 && booleanReturn) {
473 result = ATTRIBUTE_IS;
474 } else {
475
476 // It's a setter if name starts with "set" and it has 1 argument
477 // and a void return type...
478
479 if (name.startsWith("set") && nameLength > 3 && argCount == 1 && voidReturn) {
480 result = ATTRIBUTE_SET;
481 }
482 }
483 }
484 }
485 }
486
487 return result;
488 }
489
490 private static void setAttributeKinds (CompoundType.Method[] methods,
491 int[] kinds,
492 String[] names) {
493
494 int count = methods.length;
495
496 // Strip the prefixes off of the attribute names...
497
498 for (int i = 0; i < count; i++) {
499 switch (kinds[i]) {
500 case ATTRIBUTE_GET: names[i] = names[i].substring(3); break;
501 case ATTRIBUTE_IS: names[i] = names[i].substring(2); break;
502 case ATTRIBUTE_SET: names[i] = names[i].substring(3); break;
503 }
504 }
505
506 // Now, we need to look at all the IS attributes to see
507 // if there is a corresponding getter or setter which has
508 // a different return type. If so, mark it as not an
509 // attribute. Do this before checking for invalid setters...
510
511 for (int i = 0; i < count; i++) {
512 if (kinds[i] == ATTRIBUTE_IS) {
513 for (int j = 0; j < count; j++) {
514 if (j != i &&
515 (kinds[j] == ATTRIBUTE_GET || kinds[j] == ATTRIBUTE_SET) &&
516 names[i].equals(names[j])) {
517
518 // We have matching getter or setter. Do the types match?
519
520 Type isType = methods[i].getReturnType();
521 Type targetType;
522
523 if (kinds[j] == ATTRIBUTE_GET) {
524 targetType = methods[j].getReturnType();
525 } else {
526 targetType = methods[j].getArguments()[0];
527 }
528
529 if (!isType.equals(targetType)) {
530
531 // No, so forget this guy as an attribute...
532
533 kinds[i] = ATTRIBUTE_NONE;
534 names[i] = methods[i].getName();
535 break;
536 }
537 }
538 }
539 }
540 }
541
542 // Now, we need to look at all the setters to see if there
543 // is a corresponding getter. If not, it is not a setter.
544 // If there is, change the getter type to _RW and set the
545 // pair index...
546
547 for (int i = 0; i < count; i++) {
548 if (kinds[i] == ATTRIBUTE_SET) {
549 int getterIndex = -1;
550 int isGetterIndex = -1;
551 // First look for is-getters, then for getters.
552 // This is preferred for boolean attributes.
553 for (int j = 0; j < count; j++) {
554 if (j != i && names[i].equals(names[j])) {
555 // Yep, is the return type of the getter the same
556 // as the argument type of the setter?
557
558 Type getterReturn = methods[j].getReturnType();
559 Type setterArg = methods[i].getArguments()[0];
560
561 if (getterReturn.equals(setterArg)) {
562 if (kinds[j] == ATTRIBUTE_IS) {
563 isGetterIndex = j;
564 // continue looking for another getter
565 } else if (kinds[j] == ATTRIBUTE_GET) {
566 getterIndex = j;
567 // continue looking for an is-getter
568 }
569 }
570 }
571 }
572
573 if (getterIndex > -1) {
574 if (isGetterIndex > -1) {
575 // We have both, a boolean is-getter and a boolean getter.
576 // Use the is-getter and drop the getter.
577
578 // We have a matching getter. Change it to a read-write type...
579 kinds[isGetterIndex] = ATTRIBUTE_IS_RW;
580
581 // Now set the pair index for both the getter and the setter...
582 methods[isGetterIndex].setAttributePairIndex(i);
583 methods[i].setAttributePairIndex(isGetterIndex);
584
585 // We found a better matching is-getter.
586 // Forget this other getter as an attribute.
587 kinds[getterIndex] = ATTRIBUTE_NONE;
588 names[getterIndex] = methods[getterIndex].getName();
589 } else {
590 // We only have one getter.
591
592 // We have a matching getter. Change it to a read-write type...
593 kinds[getterIndex] = ATTRIBUTE_GET_RW;
594
595 // Now set the pair index for both the getter and the setter...
596 methods[getterIndex].setAttributePairIndex(i);
597 methods[i].setAttributePairIndex(getterIndex);
598 }
599 } else {
600 if (isGetterIndex > -1) {
601 // We only have one is-getter.
602
603 // We have a matching getter. Change it to a read-write type...
604 kinds[isGetterIndex] = ATTRIBUTE_IS_RW;
605
606 // Now set the pair index for both the getter and the setter...
607 methods[isGetterIndex].setAttributePairIndex(i);
608 methods[i].setAttributePairIndex(isGetterIndex);
609 } else {
610 // We did not find a matching getter.
611 // Forget this setter as an attribute.
612 kinds[i] = ATTRIBUTE_NONE;
613 names[i] = methods[i].getName();
614 }
615 }
616 }
617 }
618
619 // Finally, do the case conversion and set the
620 // attribute kinds for each method...
621
622 for (int i = 0; i < count; i++) {
623
624 if (kinds[i] != ATTRIBUTE_NONE) {
625
626 String name = names[i];
627
628 // Is the first character upper case?
629
630 if (Character.isUpperCase(name.charAt(0))) {
631
632 // Yes, is the second?
633
634 if (name.length() == 1 || Character.isLowerCase(name.charAt(1))) {
635
636 // No, so convert the first character to lower case...
637
638 StringBuffer buffer = new StringBuffer(name);
639 buffer.setCharAt(0,Character.toLowerCase(name.charAt(0)));
640 names[i] = buffer.toString();
641 }
642 }
643 }
644
645 methods[i].setAttributeKind(kinds[i]);
646 }
647 }
648
649 /**
650 * Set all the method names in a given class.
651 * <p>
652 * Section 28.3.2.7 (see CompoundType)
653 * Section 28.3.2.7
654 * Section 28.3.4.3 (RemoteType/AbstractType only).
655 */
656 public static void setMethodNames (CompoundType container,
657 CompoundType.Method[] allMethods,
658 BatchEnvironment env)
659 throws Exception {
660
661 // This method implements the following name mangling sequence:
662 //
663 // 1. If methods belong to a Remote interface, identify
664 // those which qualify as an attribute under 28.3.4.3.
665 // Those that do are referred to as 'attributes' below;
666 // those that do not are referred to as 'methods'.
667 //
668 // 2. Apply the 28.3.4.3 manglings, except "__", to all
669 // attribute names.
670 //
671 // 3. Apply all 28.3 manglings, except 28.3.2.7, to all names.
672 //
673 // 4. Apply 28.3.2.7 manglings to all method names.
674 //
675 // 5. Compare each attribute name to each method name. For
676 // any which compare equal, append "__" to the attribute
677 // name.
678 //
679 // 6. Compare each name (attribute and method) to all others.
680 // If any compare equal, throw an Exception with the
681 // conflicting name as the message.
682
683 int count = allMethods.length;
684
685 if (count == 0) return;
686
687 // Make an array of all the method names...
688
689 String[] names = new String[count];
690 for (int i = 0; i < count; i++) {
691 names[i] = allMethods[i].getName();
692 }
693
694 // Are we dealing with a RemoteType, AbstractType, or ValueType?
695
696 CompoundType enclosing = allMethods[0].getEnclosing();
697 if (enclosing.isType(TYPE_REMOTE) ||
698 enclosing.isType(TYPE_ABSTRACT) ||
699 enclosing.isType(TYPE_VALUE)) {
700
701 // Yes, so we must do the 28.3.4.3 attribute mapping. First, get
702 // the initial attribute kind of each method...
703
704 int[] kinds = new int[count];
705
706 for (int i = 0; i < count; i++) {
707 kinds[i] = getInitialAttributeKind(allMethods[i],env);
708 }
709
710 // Now set the attribute kind for each method and do the
711 // 28.3.4.3 name mangling...
712
713 setAttributeKinds(allMethods,kinds,names);
714 }
715
716 // Make and populate a new context from our names array...
717
718 NameContext context = new NameContext(true);
719
720 for (int i = 0; i < count; i++) {
721 context.put(names[i]);
722 }
723
724 // Apply the appropriate 28.3 manglings to all the names...
725
726 boolean haveConstructor = false;
727 for (int i = 0; i < count; i++) {
728 if (!allMethods[i].isConstructor()) {
729 names[i] = getMemberOrMethodName(context,names[i],env);
730 } else {
731 names[i] = IDL_CONSTRUCTOR;
732 haveConstructor = true;
733 }
734 }
735
736 // Now do the 28.3.2.7 mangling for method name collisions...
737 // Do this in two passes so that we don't change one during
738 // the detection of collisions and then miss a real one...
739
740 boolean overloaded[] = new boolean[count];
741 for (int i = 0; i < count; i++) {
742 overloaded[i] = (!allMethods[i].isAttribute() &&
743 !allMethods[i].isConstructor() &&
744 doesMethodCollide(names[i],allMethods[i],allMethods,names,true));
745 }
746 convertOverloadedMethods(allMethods,names,overloaded);
747
748 // Now do the same mangling for constructor name collisions...
749
750 for (int i = 0; i < count; i++) {
751 overloaded[i] = (!allMethods[i].isAttribute() &&
752 allMethods[i].isConstructor() &&
753 doesConstructorCollide(names[i],allMethods[i],allMethods,names,true));
754 }
755 convertOverloadedMethods(allMethods,names,overloaded);
756
757 // Now do the 28.3.4.3 mangling for attribute name collisions...
758
759 for (int i = 0; i < count; i++) {
760
761 CompoundType.Method method = allMethods[i];
762
763 // If this is an attribute name, does it collide with a method?
764
765 if (method.isAttribute() &&
766 doesMethodCollide(names[i],method,allMethods,names,true)) {
767
768 // Yes, so add double underscore...
769
770 names[i] += "__";
771 }
772 }
773
774 // Do the same mangling for any constructors which collide with
775 // methods...
776
777 if (haveConstructor) {
778 for (int i = 0; i < count; i++) {
779 CompoundType.Method method = allMethods[i];
780
781 // Is this a constructor which collides with a method?
782
783 if (method.isConstructor() &&
784 doesConstructorCollide(names[i],method,allMethods,names,false)) {
785
786 // Yes, so add double underscore...
787
788 names[i] += "__";
789 }
790 }
791 }
792
793 // Now see if we have a collision with the container name (28.3.2.9).
794
795 String containerName = container.getIDLName();
796 for (int i = 0; i < count; i++) {
797 if (names[i].equalsIgnoreCase(containerName)) {
798 // Do not add underscore to attributes.
799 // Otherwise getFoo will turn into _get_foo_.
800 if (! allMethods[i].isAttribute()) {
801 names[i] += "_";
802 }
803 }
804 }
805
806 // Now see if we have any collisions (28.3.2.9). If we do,
807 // it's an error. Note: a get/set pair does not collide.
808
809 for (int i = 0; i < count; i++) {
810
811 // Does it collide with any other name?
812
813 if (doesMethodCollide(names[i],allMethods[i],allMethods,names,false)) {
814
815 // Yes, so bail...
816
817 throw new Exception(allMethods[i].toString());
818 }
819 }
820
821 // Ok. We have unique names. Create the appropriate 'wire' name
822 // for each and set as the 'idl' name. If it is an attribute, also
823 // set the attribute name...
824
825 for (int i = 0; i < count; i++) {
826
827 CompoundType.Method method = allMethods[i];
828 String wireName = names[i];
829
830 if (method.isAttribute()) {
831 wireName = ATTRIBUTE_WIRE_PREFIX[method.getAttributeKind()] +
832 stripLeadingUnderscore(wireName);
833 String attributeName = names[i];
834 method.setAttributeName(attributeName);
835 }
836 method.setIDLName(wireName);
837 }
838 }
839
840 private static String stripLeadingUnderscore (String name) {
841 if (name != null && name.length() > 1
842 && name.charAt(0) == '_')
843 {
844 return name.substring(1);
845 }
846 return name;
847 }
848
849
850 private static String stripTrailingUnderscore (String name) {
851 if (name != null && name.length() > 1 &&
852 name.charAt(name.length() - 1) == '_')
853 {
854 return name.substring(0, name.length() - 1);
855 }
856 return name;
857 }
858
859
860 private static void convertOverloadedMethods(CompoundType.Method[] allMethods,
861 String[] names,
862 boolean[] overloaded) {
863
864 for (int i = 0; i < names.length; i++) {
865
866 // Do we need to mangle it?
867
868 if (overloaded[i]) {
869
870 // Yes, so add arguments...
871
872 CompoundType.Method method = allMethods[i];
873 Type[] args = method.getArguments();
874
875 for (int k = 0; k < args.length; k++) {
876
877 // Add the separator...
878
879 names[i] += "__";
880
881 // Get the fully qualified IDL name, without the "::"
882 // prefix...
883
884 String argIDLName = args[k].getQualifiedIDLName(false);
885
886 // Replace any occurances of "::_" with "_" to
887 // undo any IDL keyword mangling and do next step
888 // at the same time...
889
890 argIDLName = replace(argIDLName,"::_","_");
891
892 // Replace any occurances of "::" with "_"...
893
894 argIDLName = replace(argIDLName,"::","_");
895
896 // Replace any occurances of " " with "_"...
897
898 argIDLName = replace(argIDLName," ","_");
899
900 // Add the argument type name...
901
902 names[i] += argIDLName;
903 }
904
905 if (args.length == 0) {
906 names[i] += "__";
907 }
908
909 // Remove any IDL keyword mangling...
910
911 names[i] = stripLeadingUnderscore(names[i]);
912 }
913 }
914 }
915
916 private static boolean doesMethodCollide (String name,
917 CompoundType.Method method,
918 CompoundType.Method[] allMethods,
919 String[] allNames,
920 boolean ignoreAttributes) {
921
922 // Scan all methods looking for a match...
923
924 for (int i = 0; i < allMethods.length; i++) {
925
926 CompoundType.Method target = allMethods[i];
927
928 if (method != target && // Not same instance
929 !target.isConstructor() && // Not a constructor
930 (!ignoreAttributes || !target.isAttribute()) && // Correct kind
931 name.equals(allNames[i])) { // Same names
932
933 // Are we looking at a get/set pair?
934
935 int kind1 = method.getAttributeKind();
936 int kind2 = target.getAttributeKind();
937
938 if ((kind1 != ATTRIBUTE_NONE && kind2 != ATTRIBUTE_NONE) &&
939 ((kind1 == ATTRIBUTE_SET && kind2 != ATTRIBUTE_SET) ||
940 (kind1 != ATTRIBUTE_SET && kind2 == ATTRIBUTE_SET) ||
941 // one is a is-getter/setter pair and the other is just a getter
942 (kind1 == ATTRIBUTE_IS_RW && kind2 == ATTRIBUTE_GET) ||
943 (kind1 == ATTRIBUTE_GET && kind2 == ATTRIBUTE_IS_RW))) {
944
945 // Yes, so ignore it...
946
947 } else {
948
949 // No, so we have a collision...
950
951 return true;
952 }
953 }
954 }
955
956 return false;
957 }
958
959 private static boolean doesConstructorCollide (String name,
960 CompoundType.Method method,
961 CompoundType.Method[] allMethods,
962 String[] allNames,
963 boolean compareConstructors) {
964
965 // Scan all methods looking for a match...
966
967 for (int i = 0; i < allMethods.length; i++) {
968
969 CompoundType.Method target = allMethods[i];
970
971 if (method != target && // Not same instance
972 (target.isConstructor() == compareConstructors) && // Correct kind
973 name.equals(allNames[i])) { // Same names
974
975 // We have a collision...
976
977 return true;
978 }
979 }
980
981 return false;
982 }
983
984
985 /**
986 * Set all the member names in a given class.
987 * <p>
988 * Section 28.3.2.7 (see CompoundType)
989 * Section 28.3.2.7
990 */
991 public static void setMemberNames (CompoundType container,
992 CompoundType.Member[] allMembers,
993 CompoundType.Method[] allMethods,
994 BatchEnvironment env)
995 throws Exception {
996
997 // Make and populate a new context...
998
999 NameContext context = new NameContext(true);
1000
1001 for (int i = 0; i < allMembers.length; i++) {
1002 context.put(allMembers[i].getName());
1003 }
1004
1005 // Now set all the idl names...
1006
1007 for (int i = 0; i < allMembers.length; i++) {
1008
1009 CompoundType.Member member = allMembers[i];
1010 String idlName = getMemberOrMethodName(context,member.getName(),env);
1011 member.setIDLName(idlName);
1012 }
1013
1014 // First see if we have a collision with the container name (28.3.2.9).
1015
1016 String containerName = container.getIDLName();
1017 for (int i = 0; i < allMembers.length; i++) {
1018 String name = allMembers[i].getIDLName();
1019 if (name.equalsIgnoreCase(containerName)) {
1020 // REVISIT - How is this different than line 788
1021 allMembers[i].setIDLName(name+"_");
1022 }
1023 }
1024
1025 // Check for collisions between member names...
1026
1027 for (int i = 0; i < allMembers.length; i++) {
1028 String name = allMembers[i].getIDLName();
1029 for (int j = 0; j < allMembers.length; j++) {
1030 if (i != j && allMembers[j].getIDLName().equals(name)) {
1031
1032 // Collision...
1033
1034 throw new Exception(name);
1035 }
1036 }
1037 }
1038
1039 // Now check for collisions between member names and
1040 // method names...
1041
1042 boolean changed;
1043 do {
1044 changed = false;
1045 for (int i = 0; i < allMembers.length; i++) {
1046 String name = allMembers[i].getIDLName();
1047 for (int j = 0; j < allMethods.length; j++) {
1048 if (allMethods[j].getIDLName().equals(name)) {
1049
1050 // Collision, so append "_" to member name...
1051
1052 allMembers[i].setIDLName(name+"_");
1053 changed = true;
1054 break;
1055 }
1056 }
1057 }
1058 } while (changed);
1059 }
1060
1061 /**
1062 * Get the name for the specified type code.
1063 * <p>
1064 * Section 28.3..3 (see PrimitiveType)
1065 * Section 28.3.5.10 (see SpecialClassType)
1066 * Section 28.3.4.1 (see SpecialInterfaceType)
1067 * Section 28.3.10.1 (see SpecialInterfaceType)
1068 * Section 28.3.10.2 (see SpecialClassType)
1069 */
1070 public static String getTypeName(int typeCode, boolean isConstant) {
1071
1072 String idlName = null;
1073
1074 switch (typeCode) {
1075 case TYPE_VOID: idlName = IDL_VOID; break;
1076 case TYPE_BOOLEAN: idlName = IDL_BOOLEAN; break;
1077 case TYPE_BYTE: idlName = IDL_BYTE; break;
1078 case TYPE_CHAR: idlName = IDL_CHAR; break;
1079 case TYPE_SHORT: idlName = IDL_SHORT; break;
1080 case TYPE_INT: idlName = IDL_INT; break;
1081 case TYPE_LONG: idlName = IDL_LONG; break;
1082 case TYPE_FLOAT: idlName = IDL_FLOAT; break;
1083 case TYPE_DOUBLE: idlName = IDL_DOUBLE; break;
1084 case TYPE_ANY: idlName = IDL_ANY; break;
1085 case TYPE_CORBA_OBJECT: idlName = IDL_CORBA_OBJECT; break;
1086 case TYPE_STRING:
1087 {
1088 if (isConstant) {
1089 idlName = IDL_CONSTANT_STRING;
1090 } else {
1091 idlName = IDL_STRING;
1092 }
1093
1094 break;
1095 }
1096 }
1097
1098 return idlName;
1099 }
1100
1101 /**
1102 * Create a qualified name.
1103 */
1104 public static String getQualifiedName (String[] idlModuleNames, String idlName) {
1105 String result = null;
1106 if (idlModuleNames != null && idlModuleNames.length > 0) {
1107 for (int i = 0; i < idlModuleNames.length;i++) {
1108 if (i == 0) {
1109 result = idlModuleNames[0];
1110 } else {
1111 result += IDL_NAME_SEPARATOR;
1112 result += idlModuleNames[i];
1113 }
1114 }
1115 result += IDL_NAME_SEPARATOR;
1116 result += idlName;
1117 } else {
1118 result = idlName;
1119 }
1120 return result;
1121 }
1122
1123 /**
1124 * Replace substrings
1125 * @param source The source string.
1126 * @param match The string to search for within the source string.
1127 * @param replace The replacement for any matching components.
1128 * @return
1129 */
1130 public static String replace (String source, String match, String replace) {
1131
1132 int index = source.indexOf(match,0);
1133
1134 if (index >=0) {
1135
1136 // We have at least one match, so gotta do the
1137 // work...
1138
1139 StringBuffer result = new StringBuffer(source.length() + 16);
1140 int matchLength = match.length();
1141 int startIndex = 0;
1142
1143 while (index >= 0) {
1144 result.append(source.substring(startIndex,index));
1145 result.append(replace);
1146 startIndex = index + matchLength;
1147 index = source.indexOf(match,startIndex);
1148 }
1149
1150 // Grab the last piece, if any...
1151
1152 if (startIndex < source.length()) {
1153 result.append(source.substring(startIndex));
1154 }
1155
1156 return result.toString();
1157
1158 } else {
1159
1160 // No matches, just return the source...
1161
1162 return source;
1163 }
1164 }
1165
1166 /**
1167 * Get an IDL style repository id for
1168 */
1169 public static String getIDLRepositoryID (String idlName) {
1170 return IDL_REPOSITORY_ID_PREFIX +
1171 replace(idlName,"::", "/") +
1172 IDL_REPOSITORY_ID_VERSION;
1173 }
1174
1175 //_____________________________________________________________________
1176 // Internal Interfaces
1177 //_____________________________________________________________________
1178
1179
1180 /**
1181 * Convert a type or module name.
1182 * <p>
1183 * Section 28.3.2.2
1184 * Section 28.3.2.3
1185 */
1186 private static String getTypeOrModuleName (String name) {
1187
1188 // 28.3.2.3 Leading underscores...
1189
1190 String result = convertLeadingUnderscores(name);
1191
1192 // 28.3.2.2 IDL keywords (NOTE: must be done
1193 // after leading underscore conversion because
1194 // the mangling for IDL keywords creates a
1195 // leading underscore!)...
1196
1197 return convertIDLKeywords(result);
1198 }
1199 }

mercurial