duke@1: /* mbankal@371: * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as ohair@158: * published by the Free Software Foundation. Oracle designates this duke@1: * particular file as subject to the "Classpath" exception as provided ohair@158: * by Oracle in the LICENSE file that accompanied this code. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * ohair@158: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@158: * or visit www.oracle.com if you need additional information or have any ohair@158: * questions. duke@1: */ duke@1: duke@1: /* duke@1: * Licensed Materials - Property of IBM duke@1: * RMI-IIOP v1.0 duke@1: * Copyright IBM Corp. 1998 1999 All Rights Reserved duke@1: * duke@1: */ duke@1: duke@1: package sun.rmi.rmic.iiop; duke@1: duke@1: import java.util.Hashtable; duke@1: import java.util.Locale; duke@1: import sun.tools.java.Identifier; duke@1: import sun.tools.java.CompilerError; duke@1: import sun.tools.java.ClassDefinition; duke@1: import sun.tools.java.ClassNotFound; duke@1: import com.sun.corba.se.impl.util.RepositoryId; duke@1: duke@1: /** duke@1: * IDLNames provides static utility methods to perform the IDL duke@1: * name mappings specified in Chapter 5 of the Java Language duke@1: * to IDL specification. duke@1: * duke@1: * @author Bryan Atsatt duke@1: */ duke@1: public class IDLNames implements sun.rmi.rmic.iiop.Constants { duke@1: duke@1: /** duke@1: * Used to convert ascii to hex. duke@1: */ duke@1: public static final byte ASCII_HEX[] = { duke@1: (byte)'0', duke@1: (byte)'1', duke@1: (byte)'2', duke@1: (byte)'3', duke@1: (byte)'4', duke@1: (byte)'5', duke@1: (byte)'6', duke@1: (byte)'7', duke@1: (byte)'8', duke@1: (byte)'9', duke@1: (byte)'A', duke@1: (byte)'B', duke@1: (byte)'C', duke@1: (byte)'D', duke@1: (byte)'E', duke@1: (byte)'F', duke@1: }; duke@1: mbankal@371: // Legal IDL Identifier characters (1 = legal). Note mbankal@371: // that '.' (2E) is marked as legal even though it is mbankal@371: // not legal in IDL. This allows us to treat a fully mbankal@371: // qualified Java name with '.' package separators mbankal@371: // uniformly, and is safe because that is the only mbankal@371: // legal use of '.' in a Java name. mbankal@371: mbankal@371: private static final byte[] IDL_IDENTIFIER_CHARS = { mbankal@371: mbankal@371: // 0 1 2 3 4 5 6 7 8 9 a b c d e f mbankal@371: 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 00-0f mbankal@371: 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 10-1f mbankal@371: 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0, // 20-2f mbankal@371: 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, // 30-3f mbankal@371: 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 40-4f mbankal@371: 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, // 50-5f mbankal@371: 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 60-6f mbankal@371: 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, // 70-7f mbankal@371: 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 80-8f mbankal@371: 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 90-9f mbankal@371: 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // a0-af mbankal@371: 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // b0-bf mbankal@371: 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // c0-cf mbankal@371: 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // d0-df mbankal@371: 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // e0-ef mbankal@371: 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // f0-ff mbankal@371: }; mbankal@371: duke@1: //_____________________________________________________________________ duke@1: // Public Interfaces duke@1: //_____________________________________________________________________ duke@1: duke@1: /** duke@1: * Convert a name. The nameContext argument MUST be pre-filled with duke@1: * all names from the appropriate context (e.g. all the method names duke@1: * in a given class). The names must not have had any IDL conversions duke@1: * applied. duke@1: *
duke@1: * Section 28.3.2.2 duke@1: * Section 28.3.2.3 duke@1: * Section 28.3.2.4 duke@1: * Section 28.3.2.7 (member and method names only) duke@1: */ duke@1: public static String getMemberOrMethodName (NameContext nameContext, duke@1: String name, duke@1: BatchEnvironment env) { duke@1: duke@1: // Check namesCache... duke@1: duke@1: String result = (String) env.namesCache.get(name); duke@1: duke@1: if (result == null) { duke@1: duke@1: // 28.3.2.7 Case sensitive member names. duke@1: duke@1: // Note: This must be done before any of duke@1: // the other conversions! duke@1: duke@1: result = nameContext.get(name); duke@1: duke@1: // 28.3.2.3 Leading underscores... duke@1: duke@1: result = convertLeadingUnderscores(result); duke@1: duke@1: // 28.3.2.2 IDL keywords (NOTE: must be done duke@1: // after leading underscore conversion because duke@1: // the mangling for IDL keywords creates a duke@1: // leading underscore!)... duke@1: duke@1: result = convertIDLKeywords(result); duke@1: duke@1: // 28.3.2.4 Illegal IDL identifier characters... duke@1: duke@1: result = convertToISOLatin1(result); duke@1: duke@1: // Add to namesCache... duke@1: duke@1: env.namesCache.put(name,result); duke@1: } duke@1: duke@1: return result; duke@1: } duke@1: duke@1: /** duke@1: * Convert names with illegal IDL identifier characters. duke@1: *
duke@1: * Section 28.3.2.4 duke@1: */ duke@1: public static String convertToISOLatin1 (String name) { duke@1: duke@1: // First, replace any escape sequences... duke@1: duke@1: String result = replace(name,"x\\u","U"); duke@1: result = replace(result,"x\\U","U"); duke@1: duke@1: // Now see if we have any remaining illegal characters (see mbankal@371: // IDL_IDENTIFIER_CHARS array)... duke@1: duke@1: int length = result.length(); duke@1: StringBuffer buffer = null; duke@1: duke@1: for (int i = 0; i < length; i++) { duke@1: duke@1: char c = result.charAt(i); duke@1: mbankal@371: if (c > 255 || IDL_IDENTIFIER_CHARS[c] == 0) { duke@1: duke@1: // We gotta convert. Have we already started? duke@1: duke@1: if (buffer == null) { duke@1: duke@1: // No, so get set up... duke@1: duke@1: buffer = new StringBuffer(result.substring(0,i)); duke@1: } duke@1: duke@1: // Convert the character into the IDL escape syntax... duke@1: duke@1: buffer.append("U"); duke@1: buffer.append((char)ASCII_HEX[(c & 0xF000) >>> 12]); duke@1: buffer.append((char)ASCII_HEX[(c & 0x0F00) >>> 8]); duke@1: buffer.append((char)ASCII_HEX[(c & 0x00F0) >>> 4]); duke@1: buffer.append((char)ASCII_HEX[(c & 0x000F)]); duke@1: duke@1: } else { duke@1: if (buffer != null) { duke@1: buffer.append(c); duke@1: } duke@1: } duke@1: } duke@1: duke@1: if (buffer != null) { duke@1: result = buffer.toString(); duke@1: } duke@1: duke@1: return result; duke@1: } duke@1: duke@1: /** duke@1: * Convert names which collide with IDL keywords. duke@1: *
duke@1: * Section 28.3.2.5 duke@1: */ duke@1: public static String convertIDLKeywords (String name) { duke@1: duke@1: for (int i = 0; i < IDL_KEYWORDS.length; i++) { duke@1: if (name.equalsIgnoreCase(IDL_KEYWORDS[i])) { duke@1: return "_" + name; duke@1: } duke@1: } duke@1: duke@1: return name; duke@1: } duke@1: duke@1: /** duke@1: * Convert names which have leading underscores duke@1: *
duke@1: * Section 28.3.2.3 duke@1: */ duke@1: public static String convertLeadingUnderscores (String name) { duke@1: duke@1: if (name.startsWith("_")) { duke@1: return "J" + name; duke@1: } duke@1: duke@1: return name; duke@1: } duke@1: duke@1: /** duke@1: * Convert a type name. duke@1: *
duke@1: * Section 28.3.2.5 duke@1: * Section 28.3.2.7 (class or interface names only) duke@1: * Throws exception if fails 28.3.2.7. duke@1: */ duke@1: public static String getClassOrInterfaceName (Identifier id, duke@1: BatchEnvironment env) throws Exception { duke@1: duke@1: // Get the type and package name... duke@1: duke@1: String typeName = id.getName().toString(); duke@1: String packageName = null; duke@1: duke@1: if (id.isQualified()) { duke@1: packageName = id.getQualifier().toString(); duke@1: } duke@1: duke@1: // Check namesCache... duke@1: duke@1: String result = (String) env.namesCache.get(typeName); duke@1: duke@1: if (result == null) { duke@1: duke@1: // 28.3.2.5 Inner classes... duke@1: duke@1: result = replace(typeName,". ","__"); duke@1: duke@1: // 28.3.2.4 Illegal identifier characters... duke@1: duke@1: result = convertToISOLatin1(result); duke@1: duke@1: // 28.3.2.7 Case sensitive class or interface names... duke@1: duke@1: NameContext context = NameContext.forName(packageName,false,env); duke@1: context.assertPut(result); duke@1: duke@1: // Run it through the name checks... duke@1: duke@1: result = getTypeOrModuleName(result); duke@1: duke@1: // Add it to the namesCache... duke@1: duke@1: env.namesCache.put(typeName,result); duke@1: } duke@1: duke@1: return result; duke@1: } duke@1: duke@1: /** duke@1: * Convert an Exception name. duke@1: *
duke@1: * Section 28.3.7.2 (see ValueType) duke@1: */ duke@1: public static String getExceptionName (String idlName) { duke@1: duke@1: String result = idlName; duke@1: // d.11315 Incorrectly mangled exception names duke@1: if (idlName.endsWith(EXCEPTION_SUFFIX)) { duke@1: duke@1: // Remove "Exception" and append "Ex". Strip leading underscore duke@1: // in case the idlName is exactly "_Exception"... duke@1: duke@1: result = stripLeadingUnderscore(idlName.substring(0,idlName.lastIndexOf(EXCEPTION_SUFFIX)) + EX_SUFFIX); duke@1: } else { duke@1: result = idlName + EX_SUFFIX; duke@1: } duke@1: duke@1: return result; duke@1: } duke@1: duke@1: /** duke@1: * Convert a qualified Identifier into an array of IDL names. duke@1: *
duke@1: * Section 28.3.2.1 (see CompoundType) duke@1: * Throws exception if fails 28.3.2.7. duke@1: */ duke@1: public static String[] getModuleNames (Identifier theID, duke@1: boolean boxIt, duke@1: BatchEnvironment env) throws Exception { duke@1: duke@1: String[] result = null; duke@1: duke@1: if (theID.isQualified()) { duke@1: duke@1: // Extract the qualifier... duke@1: duke@1: Identifier id = theID.getQualifier(); duke@1: duke@1: // 28.3.2.7 Case sensitive module names. duke@1: duke@1: env.modulesContext.assertPut(id.toString()); duke@1: duke@1: // Count them... duke@1: duke@1: int count = 1; duke@1: Identifier current = id; duke@1: while (current.isQualified()) { duke@1: current = current.getQualifier(); duke@1: count++; duke@1: } duke@1: duke@1: result = new String[count]; duke@1: int index = count-1; duke@1: current = id; duke@1: duke@1: // Now walk them and fill our array (backwards)... duke@1: duke@1: for (int i = 0; i < count; i++) { duke@1: duke@1: String item = current.getName().toString(); duke@1: duke@1: // Check namesCache... duke@1: duke@1: String cachedItem = (String) env.namesCache.get(item); duke@1: duke@1: if (cachedItem == null) { duke@1: duke@1: // 28.3.2.4 Illegal identifier characters... duke@1: duke@1: cachedItem = convertToISOLatin1(item); duke@1: duke@1: // Run it through the name checks... duke@1: duke@1: cachedItem = getTypeOrModuleName(cachedItem); duke@1: duke@1: // Add it to the namesCache... duke@1: duke@1: env.namesCache.put(item,cachedItem); duke@1: } duke@1: duke@1: result[index--] = cachedItem; duke@1: current = current.getQualifier(); duke@1: } duke@1: } duke@1: duke@1: duke@1: // If it is supposed to be "boxed", prepend duke@1: // IDL_BOXEDIDL_MODULE... duke@1: duke@1: if (boxIt) { duke@1: if (result == null) { duke@1: result = IDL_BOXEDIDL_MODULE; duke@1: } else { duke@1: String[] boxed = new String[result.length+IDL_BOXEDIDL_MODULE.length]; duke@1: System.arraycopy(IDL_BOXEDIDL_MODULE,0,boxed,0,IDL_BOXEDIDL_MODULE.length); duke@1: System.arraycopy(result,0,boxed,IDL_BOXEDIDL_MODULE.length,result.length); duke@1: result = boxed; duke@1: } duke@1: } duke@1: duke@1: return result; duke@1: } duke@1: duke@1: /** duke@1: * Get an array name with the specified dimensions. duke@1: *
duke@1: * Section 28.3.6 (see ArrayType)
duke@1: */
duke@1: public static String getArrayName (Type theType, int arrayDimension) {
duke@1:
duke@1: StringBuffer idlName = new StringBuffer(64);
duke@1:
duke@1: // Prefix with seq
duke@1: * Section 28.3.2.7 (see CompoundType)
duke@1: * Section 28.3.2.7
duke@1: * Section 28.3.4.3 (RemoteType/AbstractType only).
duke@1: */
duke@1: public static void setMethodNames (CompoundType container,
duke@1: CompoundType.Method[] allMethods,
duke@1: BatchEnvironment env)
duke@1: throws Exception {
duke@1:
duke@1: // This method implements the following name mangling sequence:
duke@1: //
duke@1: // 1. If methods belong to a Remote interface, identify
duke@1: // those which qualify as an attribute under 28.3.4.3.
duke@1: // Those that do are referred to as 'attributes' below;
duke@1: // those that do not are referred to as 'methods'.
duke@1: //
duke@1: // 2. Apply the 28.3.4.3 manglings, except "__", to all
duke@1: // attribute names.
duke@1: //
duke@1: // 3. Apply all 28.3 manglings, except 28.3.2.7, to all names.
duke@1: //
duke@1: // 4. Apply 28.3.2.7 manglings to all method names.
duke@1: //
duke@1: // 5. Compare each attribute name to each method name. For
duke@1: // any which compare equal, append "__" to the attribute
duke@1: // name.
duke@1: //
duke@1: // 6. Compare each name (attribute and method) to all others.
duke@1: // If any compare equal, throw an Exception with the
duke@1: // conflicting name as the message.
duke@1:
duke@1: int count = allMethods.length;
duke@1:
duke@1: if (count == 0) return;
duke@1:
duke@1: // Make an array of all the method names...
duke@1:
duke@1: String[] names = new String[count];
duke@1: for (int i = 0; i < count; i++) {
duke@1: names[i] = allMethods[i].getName();
duke@1: }
duke@1:
duke@1: // Are we dealing with a RemoteType, AbstractType, or ValueType?
duke@1:
duke@1: CompoundType enclosing = allMethods[0].getEnclosing();
duke@1: if (enclosing.isType(TYPE_REMOTE) ||
duke@1: enclosing.isType(TYPE_ABSTRACT) ||
duke@1: enclosing.isType(TYPE_VALUE)) {
duke@1:
duke@1: // Yes, so we must do the 28.3.4.3 attribute mapping. First, get
duke@1: // the initial attribute kind of each method...
duke@1:
duke@1: int[] kinds = new int[count];
duke@1:
duke@1: for (int i = 0; i < count; i++) {
duke@1: kinds[i] = getInitialAttributeKind(allMethods[i],env);
duke@1: }
duke@1:
duke@1: // Now set the attribute kind for each method and do the
duke@1: // 28.3.4.3 name mangling...
duke@1:
duke@1: setAttributeKinds(allMethods,kinds,names);
duke@1: }
duke@1:
duke@1: // Make and populate a new context from our names array...
duke@1:
duke@1: NameContext context = new NameContext(true);
duke@1:
duke@1: for (int i = 0; i < count; i++) {
duke@1: context.put(names[i]);
duke@1: }
duke@1:
duke@1: // Apply the appropriate 28.3 manglings to all the names...
duke@1:
duke@1: boolean haveConstructor = false;
duke@1: for (int i = 0; i < count; i++) {
duke@1: if (!allMethods[i].isConstructor()) {
duke@1: names[i] = getMemberOrMethodName(context,names[i],env);
duke@1: } else {
duke@1: names[i] = IDL_CONSTRUCTOR;
duke@1: haveConstructor = true;
duke@1: }
duke@1: }
duke@1:
duke@1: // Now do the 28.3.2.7 mangling for method name collisions...
duke@1: // Do this in two passes so that we don't change one during
duke@1: // the detection of collisions and then miss a real one...
duke@1:
duke@1: boolean overloaded[] = new boolean[count];
duke@1: for (int i = 0; i < count; i++) {
duke@1: overloaded[i] = (!allMethods[i].isAttribute() &&
duke@1: !allMethods[i].isConstructor() &&
duke@1: doesMethodCollide(names[i],allMethods[i],allMethods,names,true));
duke@1: }
duke@1: convertOverloadedMethods(allMethods,names,overloaded);
duke@1:
duke@1: // Now do the same mangling for constructor name collisions...
duke@1:
duke@1: for (int i = 0; i < count; i++) {
duke@1: overloaded[i] = (!allMethods[i].isAttribute() &&
duke@1: allMethods[i].isConstructor() &&
duke@1: doesConstructorCollide(names[i],allMethods[i],allMethods,names,true));
duke@1: }
duke@1: convertOverloadedMethods(allMethods,names,overloaded);
duke@1:
duke@1: // Now do the 28.3.4.3 mangling for attribute name collisions...
duke@1:
duke@1: for (int i = 0; i < count; i++) {
duke@1:
duke@1: CompoundType.Method method = allMethods[i];
duke@1:
duke@1: // If this is an attribute name, does it collide with a method?
duke@1:
duke@1: if (method.isAttribute() &&
duke@1: doesMethodCollide(names[i],method,allMethods,names,true)) {
duke@1:
duke@1: // Yes, so add double underscore...
duke@1:
duke@1: names[i] += "__";
duke@1: }
duke@1: }
duke@1:
duke@1: // Do the same mangling for any constructors which collide with
duke@1: // methods...
duke@1:
duke@1: if (haveConstructor) {
duke@1: for (int i = 0; i < count; i++) {
duke@1: CompoundType.Method method = allMethods[i];
duke@1:
duke@1: // Is this a constructor which collides with a method?
duke@1:
duke@1: if (method.isConstructor() &&
duke@1: doesConstructorCollide(names[i],method,allMethods,names,false)) {
duke@1:
duke@1: // Yes, so add double underscore...
duke@1:
duke@1: names[i] += "__";
duke@1: }
duke@1: }
duke@1: }
duke@1:
duke@1: // Now see if we have a collision with the container name (28.3.2.9).
duke@1:
duke@1: String containerName = container.getIDLName();
duke@1: for (int i = 0; i < count; i++) {
duke@1: if (names[i].equalsIgnoreCase(containerName)) {
duke@1: // Do not add underscore to attributes.
duke@1: // Otherwise getFoo will turn into _get_foo_.
duke@1: if (! allMethods[i].isAttribute()) {
duke@1: names[i] += "_";
duke@1: }
duke@1: }
duke@1: }
duke@1:
duke@1: // Now see if we have any collisions (28.3.2.9). If we do,
duke@1: // it's an error. Note: a get/set pair does not collide.
duke@1:
duke@1: for (int i = 0; i < count; i++) {
duke@1:
duke@1: // Does it collide with any other name?
duke@1:
duke@1: if (doesMethodCollide(names[i],allMethods[i],allMethods,names,false)) {
duke@1:
duke@1: // Yes, so bail...
duke@1:
duke@1: throw new Exception(allMethods[i].toString());
duke@1: }
duke@1: }
duke@1:
duke@1: // Ok. We have unique names. Create the appropriate 'wire' name
duke@1: // for each and set as the 'idl' name. If it is an attribute, also
duke@1: // set the attribute name...
duke@1:
duke@1: for (int i = 0; i < count; i++) {
duke@1:
duke@1: CompoundType.Method method = allMethods[i];
duke@1: String wireName = names[i];
duke@1:
duke@1: if (method.isAttribute()) {
duke@1: wireName = ATTRIBUTE_WIRE_PREFIX[method.getAttributeKind()] +
duke@1: stripLeadingUnderscore(wireName);
duke@1: String attributeName = names[i];
duke@1: method.setAttributeName(attributeName);
duke@1: }
duke@1: method.setIDLName(wireName);
duke@1: }
duke@1: }
duke@1:
duke@1: private static String stripLeadingUnderscore (String name) {
duke@1: if (name != null && name.length() > 1
duke@1: && name.charAt(0) == '_')
duke@1: {
duke@1: return name.substring(1);
duke@1: }
duke@1: return name;
duke@1: }
duke@1:
duke@1:
duke@1: private static String stripTrailingUnderscore (String name) {
duke@1: if (name != null && name.length() > 1 &&
duke@1: name.charAt(name.length() - 1) == '_')
duke@1: {
duke@1: return name.substring(0, name.length() - 1);
duke@1: }
duke@1: return name;
duke@1: }
duke@1:
duke@1:
duke@1: private static void convertOverloadedMethods(CompoundType.Method[] allMethods,
duke@1: String[] names,
duke@1: boolean[] overloaded) {
duke@1:
duke@1: for (int i = 0; i < names.length; i++) {
duke@1:
duke@1: // Do we need to mangle it?
duke@1:
duke@1: if (overloaded[i]) {
duke@1:
duke@1: // Yes, so add arguments...
duke@1:
duke@1: CompoundType.Method method = allMethods[i];
duke@1: Type[] args = method.getArguments();
duke@1:
duke@1: for (int k = 0; k < args.length; k++) {
duke@1:
duke@1: // Add the separator...
duke@1:
duke@1: names[i] += "__";
duke@1:
duke@1: // Get the fully qualified IDL name, without the "::"
duke@1: // prefix...
duke@1:
duke@1: String argIDLName = args[k].getQualifiedIDLName(false);
duke@1:
duke@1: // Replace any occurances of "::_" with "_" to
duke@1: // undo any IDL keyword mangling and do next step
duke@1: // at the same time...
duke@1:
duke@1: argIDLName = replace(argIDLName,"::_","_");
duke@1:
duke@1: // Replace any occurances of "::" with "_"...
duke@1:
duke@1: argIDLName = replace(argIDLName,"::","_");
duke@1:
duke@1: // Replace any occurances of " " with "_"...
duke@1:
duke@1: argIDLName = replace(argIDLName," ","_");
duke@1:
duke@1: // Add the argument type name...
duke@1:
duke@1: names[i] += argIDLName;
duke@1: }
duke@1:
duke@1: if (args.length == 0) {
duke@1: names[i] += "__";
duke@1: }
duke@1:
duke@1: // Remove any IDL keyword mangling...
duke@1:
duke@1: names[i] = stripLeadingUnderscore(names[i]);
duke@1: }
duke@1: }
duke@1: }
duke@1:
duke@1: private static boolean doesMethodCollide (String name,
duke@1: CompoundType.Method method,
duke@1: CompoundType.Method[] allMethods,
duke@1: String[] allNames,
duke@1: boolean ignoreAttributes) {
duke@1:
duke@1: // Scan all methods looking for a match...
duke@1:
duke@1: for (int i = 0; i < allMethods.length; i++) {
duke@1:
duke@1: CompoundType.Method target = allMethods[i];
duke@1:
duke@1: if (method != target && // Not same instance
duke@1: !target.isConstructor() && // Not a constructor
duke@1: (!ignoreAttributes || !target.isAttribute()) && // Correct kind
duke@1: name.equals(allNames[i])) { // Same names
duke@1:
duke@1: // Are we looking at a get/set pair?
duke@1:
duke@1: int kind1 = method.getAttributeKind();
duke@1: int kind2 = target.getAttributeKind();
duke@1:
duke@1: if ((kind1 != ATTRIBUTE_NONE && kind2 != ATTRIBUTE_NONE) &&
duke@1: ((kind1 == ATTRIBUTE_SET && kind2 != ATTRIBUTE_SET) ||
duke@1: (kind1 != ATTRIBUTE_SET && kind2 == ATTRIBUTE_SET) ||
duke@1: // one is a is-getter/setter pair and the other is just a getter
duke@1: (kind1 == ATTRIBUTE_IS_RW && kind2 == ATTRIBUTE_GET) ||
duke@1: (kind1 == ATTRIBUTE_GET && kind2 == ATTRIBUTE_IS_RW))) {
duke@1:
duke@1: // Yes, so ignore it...
duke@1:
duke@1: } else {
duke@1:
duke@1: // No, so we have a collision...
duke@1:
duke@1: return true;
duke@1: }
duke@1: }
duke@1: }
duke@1:
duke@1: return false;
duke@1: }
duke@1:
duke@1: private static boolean doesConstructorCollide (String name,
duke@1: CompoundType.Method method,
duke@1: CompoundType.Method[] allMethods,
duke@1: String[] allNames,
duke@1: boolean compareConstructors) {
duke@1:
duke@1: // Scan all methods looking for a match...
duke@1:
duke@1: for (int i = 0; i < allMethods.length; i++) {
duke@1:
duke@1: CompoundType.Method target = allMethods[i];
duke@1:
duke@1: if (method != target && // Not same instance
duke@1: (target.isConstructor() == compareConstructors) && // Correct kind
duke@1: name.equals(allNames[i])) { // Same names
duke@1:
duke@1: // We have a collision...
duke@1:
duke@1: return true;
duke@1: }
duke@1: }
duke@1:
duke@1: return false;
duke@1: }
duke@1:
duke@1:
duke@1: /**
duke@1: * Set all the member names in a given class.
duke@1: *
duke@1: * Section 28.3.2.7 (see CompoundType)
duke@1: * Section 28.3.2.7
duke@1: */
duke@1: public static void setMemberNames (CompoundType container,
duke@1: CompoundType.Member[] allMembers,
duke@1: CompoundType.Method[] allMethods,
duke@1: BatchEnvironment env)
duke@1: throws Exception {
duke@1:
duke@1: // Make and populate a new context...
duke@1:
duke@1: NameContext context = new NameContext(true);
duke@1:
duke@1: for (int i = 0; i < allMembers.length; i++) {
duke@1: context.put(allMembers[i].getName());
duke@1: }
duke@1:
duke@1: // Now set all the idl names...
duke@1:
duke@1: for (int i = 0; i < allMembers.length; i++) {
duke@1:
duke@1: CompoundType.Member member = allMembers[i];
duke@1: String idlName = getMemberOrMethodName(context,member.getName(),env);
duke@1: member.setIDLName(idlName);
duke@1: }
duke@1:
duke@1: // First see if we have a collision with the container name (28.3.2.9).
duke@1:
duke@1: String containerName = container.getIDLName();
duke@1: for (int i = 0; i < allMembers.length; i++) {
duke@1: String name = allMembers[i].getIDLName();
duke@1: if (name.equalsIgnoreCase(containerName)) {
duke@1: // REVISIT - How is this different than line 788
duke@1: allMembers[i].setIDLName(name+"_");
duke@1: }
duke@1: }
duke@1:
duke@1: // Check for collisions between member names...
duke@1:
duke@1: for (int i = 0; i < allMembers.length; i++) {
duke@1: String name = allMembers[i].getIDLName();
duke@1: for (int j = 0; j < allMembers.length; j++) {
duke@1: if (i != j && allMembers[j].getIDLName().equals(name)) {
duke@1:
duke@1: // Collision...
duke@1:
duke@1: throw new Exception(name);
duke@1: }
duke@1: }
duke@1: }
duke@1:
duke@1: // Now check for collisions between member names and
duke@1: // method names...
duke@1:
duke@1: boolean changed;
duke@1: do {
duke@1: changed = false;
duke@1: for (int i = 0; i < allMembers.length; i++) {
duke@1: String name = allMembers[i].getIDLName();
duke@1: for (int j = 0; j < allMethods.length; j++) {
duke@1: if (allMethods[j].getIDLName().equals(name)) {
duke@1:
duke@1: // Collision, so append "_" to member name...
duke@1:
duke@1: allMembers[i].setIDLName(name+"_");
duke@1: changed = true;
duke@1: break;
duke@1: }
duke@1: }
duke@1: }
duke@1: } while (changed);
duke@1: }
duke@1:
duke@1: /**
duke@1: * Get the name for the specified type code.
duke@1: *
duke@1: * Section 28.3..3 (see PrimitiveType)
duke@1: * Section 28.3.5.10 (see SpecialClassType)
duke@1: * Section 28.3.4.1 (see SpecialInterfaceType)
duke@1: * Section 28.3.10.1 (see SpecialInterfaceType)
duke@1: * Section 28.3.10.2 (see SpecialClassType)
duke@1: */
duke@1: public static String getTypeName(int typeCode, boolean isConstant) {
duke@1:
duke@1: String idlName = null;
duke@1:
duke@1: switch (typeCode) {
duke@1: case TYPE_VOID: idlName = IDL_VOID; break;
duke@1: case TYPE_BOOLEAN: idlName = IDL_BOOLEAN; break;
duke@1: case TYPE_BYTE: idlName = IDL_BYTE; break;
duke@1: case TYPE_CHAR: idlName = IDL_CHAR; break;
duke@1: case TYPE_SHORT: idlName = IDL_SHORT; break;
duke@1: case TYPE_INT: idlName = IDL_INT; break;
duke@1: case TYPE_LONG: idlName = IDL_LONG; break;
duke@1: case TYPE_FLOAT: idlName = IDL_FLOAT; break;
duke@1: case TYPE_DOUBLE: idlName = IDL_DOUBLE; break;
duke@1: case TYPE_ANY: idlName = IDL_ANY; break;
duke@1: case TYPE_CORBA_OBJECT: idlName = IDL_CORBA_OBJECT; break;
duke@1: case TYPE_STRING:
duke@1: {
duke@1: if (isConstant) {
duke@1: idlName = IDL_CONSTANT_STRING;
duke@1: } else {
duke@1: idlName = IDL_STRING;
duke@1: }
duke@1:
duke@1: break;
duke@1: }
duke@1: }
duke@1:
duke@1: return idlName;
duke@1: }
duke@1:
duke@1: /**
duke@1: * Create a qualified name.
duke@1: */
duke@1: public static String getQualifiedName (String[] idlModuleNames, String idlName) {
duke@1: String result = null;
duke@1: if (idlModuleNames != null && idlModuleNames.length > 0) {
duke@1: for (int i = 0; i < idlModuleNames.length;i++) {
duke@1: if (i == 0) {
duke@1: result = idlModuleNames[0];
duke@1: } else {
duke@1: result += IDL_NAME_SEPARATOR;
duke@1: result += idlModuleNames[i];
duke@1: }
duke@1: }
duke@1: result += IDL_NAME_SEPARATOR;
duke@1: result += idlName;
duke@1: } else {
duke@1: result = idlName;
duke@1: }
duke@1: return result;
duke@1: }
duke@1:
duke@1: /**
duke@1: * Replace substrings
duke@1: * @param source The source string.
duke@1: * @param match The string to search for within the source string.
duke@1: * @param replace The replacement for any matching components.
duke@1: * @return
duke@1: */
duke@1: public static String replace (String source, String match, String replace) {
duke@1:
duke@1: int index = source.indexOf(match,0);
duke@1:
duke@1: if (index >=0) {
duke@1:
duke@1: // We have at least one match, so gotta do the
duke@1: // work...
duke@1:
duke@1: StringBuffer result = new StringBuffer(source.length() + 16);
duke@1: int matchLength = match.length();
duke@1: int startIndex = 0;
duke@1:
duke@1: while (index >= 0) {
duke@1: result.append(source.substring(startIndex,index));
duke@1: result.append(replace);
duke@1: startIndex = index + matchLength;
duke@1: index = source.indexOf(match,startIndex);
duke@1: }
duke@1:
duke@1: // Grab the last piece, if any...
duke@1:
duke@1: if (startIndex < source.length()) {
duke@1: result.append(source.substring(startIndex));
duke@1: }
duke@1:
duke@1: return result.toString();
duke@1:
duke@1: } else {
duke@1:
duke@1: // No matches, just return the source...
duke@1:
duke@1: return source;
duke@1: }
duke@1: }
duke@1:
duke@1: /**
duke@1: * Get an IDL style repository id for
duke@1: */
duke@1: public static String getIDLRepositoryID (String idlName) {
duke@1: return IDL_REPOSITORY_ID_PREFIX +
duke@1: replace(idlName,"::", "/") +
duke@1: IDL_REPOSITORY_ID_VERSION;
duke@1: }
duke@1:
duke@1: //_____________________________________________________________________
duke@1: // Internal Interfaces
duke@1: //_____________________________________________________________________
duke@1:
duke@1:
duke@1: /**
duke@1: * Convert a type or module name.
duke@1: *
duke@1: * Section 28.3.2.2
duke@1: * Section 28.3.2.3
duke@1: */
duke@1: private static String getTypeOrModuleName (String name) {
duke@1:
duke@1: // 28.3.2.3 Leading underscores...
duke@1:
duke@1: String result = convertLeadingUnderscores(name);
duke@1:
duke@1: // 28.3.2.2 IDL keywords (NOTE: must be done
duke@1: // after leading underscore conversion because
duke@1: // the mangling for IDL keywords creates a
duke@1: // leading underscore!)...
duke@1:
duke@1: return convertIDLKeywords(result);
duke@1: }
duke@1: }