1 /* 2 * Copyright (c) 1999, 2004, 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 * COMPONENT_NAME: idl.toJava 27 * 28 * ORIGINS: 27 29 * 30 * Licensed Materials - Property of IBM 31 * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999 32 * RMI-IIOP v1.0 33 * 34 */ 35 36 package com.sun.tools.corba.se.idl.toJavaPortable; 37 38 // Notes: 39 // -F46838.4<klr> Ported -td option from toJava. 40 // -10/17/98 KLR Ported fix for d48911 from toJava 41 // -10/18/98 KLR Ported fix from toJava for "unsigned long" constants 42 // -F46082.51<daz> Removed code to collect makefile list generation inforamtion 43 // from getStream(); see f46830. 44 // -F46082.51<daz> Removed -stateful feature: methods javaStatefulName(String) 45 // and javaStatefulName(SymtabEntry) are obsolete, supplanted by javaName(). 46 // -D54640<daz> Represent unsigned long long expressions with their computed 47 // value rather than their actual representation (see notes in method 48 // parseTerminal(), parseBinary(), and parseUnary().) 49 // -D58319<daz> Add getVersion() method. 50 // -D48034<daz> Import Helper classes for typedef struct members when generating 51 // helper. See method addImportLines(). 52 // -D59851<daz> Modify to enable QuickTest build. (pending) 53 // -D42256<daz> Determine import lines for template types, which may specify any 54 // positive int., constant expression for a boundary. Such expression containing 55 // non-literal contansts previously caused problems when appearing in constructs 56 // structs, unions, exceptions, typedefs, operation types and parameters, 57 // attributes; and of course, sequences, strings. 58 // -D59063<daz> Add helper for global exception to stub import list. 59 // -D58951<daz> Publicise members for QuickTest. 60 // -D59421<klr> Change ValueBaseHolder to SerializableHolder 61 // -D59596<klr> Prevent accesses to elements of empty Vectors. 62 // -D59771<daz> Add import stmt for Helper of global type in stubs. 63 // -D59355<daz> Remove target dir. from filename when writing to prolog. 64 // -D59437<daz> Fill typename information for value boxes. 65 // -D62023<klr> Don't import ValueBase* 66 // -D62023<klr> Add corbaLevel 67 68 import java.io.File; 69 import java.io.PrintWriter; 70 import java.math.BigInteger; 71 import java.text.DateFormat; 72 import java.util.Date; 73 import java.util.Enumeration; 74 import java.util.Hashtable; 75 import java.util.Locale; 76 import java.util.Vector; 77 78 import com.sun.tools.corba.se.idl.ConstEntry; 79 import com.sun.tools.corba.se.idl.EnumEntry; 80 import com.sun.tools.corba.se.idl.ExceptionEntry; 81 import com.sun.tools.corba.se.idl.GenFileStream; 82 import com.sun.tools.corba.se.idl.InterfaceEntry; 83 import com.sun.tools.corba.se.idl.MethodEntry; 84 import com.sun.tools.corba.se.idl.NativeEntry; 85 import com.sun.tools.corba.se.idl.ParameterEntry; 86 import com.sun.tools.corba.se.idl.PrimitiveEntry; 87 import com.sun.tools.corba.se.idl.SequenceEntry; 88 import com.sun.tools.corba.se.idl.StringEntry; 89 import com.sun.tools.corba.se.idl.StructEntry; 90 import com.sun.tools.corba.se.idl.SymtabEntry; 91 import com.sun.tools.corba.se.idl.TypedefEntry; 92 import com.sun.tools.corba.se.idl.UnionBranch; 93 import com.sun.tools.corba.se.idl.UnionEntry; 94 import com.sun.tools.corba.se.idl.ValueEntry; 95 import com.sun.tools.corba.se.idl.ValueBoxEntry; 96 import com.sun.tools.corba.se.idl.InterfaceState; 97 98 import com.sun.tools.corba.se.idl.constExpr.*; 99 100 /** 101 * Class Util is a repository of static members available for general 102 * use by the IDL parser framework and any generator extensions. 103 **/ 104 public class Util extends com.sun.tools.corba.se.idl.Util 105 { 106 // <d58319> 107 /** 108 * Fetch the version number of this build of the IDL-to-Java (portable) 109 * compiler from the appropriate properties file. 110 * @return the version number of this compiler build. 111 **/ 112 public static String getVersion () 113 { 114 return com.sun.tools.corba.se.idl.Util.getVersion ("com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable.prp"); 115 } // getVersion 116 117 /** 118 * This method is called by Setup.preEmit, so 119 * symbolTable is available for all Util methods. 120 **/ 121 static void setSymbolTable (Hashtable symtab) 122 { 123 symbolTable = symtab; 124 } // setSymbolTable 125 126 public static void setPackageTranslation( Hashtable pkgtrans ) 127 { 128 packageTranslation = pkgtrans ; 129 } 130 131 public static boolean isInterface (String name) 132 { 133 return isInterface (name, symbolTable); 134 } // isInterface 135 136 static String arrayInfo (Vector arrayInfo) 137 { 138 int arrays = arrayInfo.size (); 139 String info = ""; 140 Enumeration e = arrayInfo.elements (); 141 while (e.hasMoreElements ()) 142 info = info + '[' + parseExpression ((Expression)e.nextElement ()) + ']'; 143 return info; 144 } // arrayInfo 145 146 // <d58951> static String sansArrayInfo (Vector arrayInfo) 147 public static String sansArrayInfo (Vector arrayInfo) 148 { 149 int arrays = arrayInfo.size (); 150 String brackets = ""; 151 for (int i = 0; i < arrays; ++i) 152 brackets = brackets + "[]"; 153 return brackets; 154 } // sansArrayInfo 155 156 // <d58951> static String sansArrayInfo (String name) 157 static public String sansArrayInfo (String name) 158 { 159 int index = name.indexOf ('['); 160 if (index >= 0) 161 { 162 String array = name.substring (index); 163 name = name.substring (0, index); 164 while (!array.equals ("")) 165 { 166 name = name + "[]"; 167 array = array.substring (array.indexOf (']') + 1); 168 } 169 } 170 return name; 171 } // sansArrayInfo 172 173 /** 174 * Given a symbol table entry, return the name of 175 * the file which should be created. 176 **/ 177 public static String fileName (SymtabEntry entry, String extension ) 178 { 179 NameModifier nm = new NameModifierImpl() ; 180 return fileName( entry, nm, extension ) ; 181 } // fileName 182 183 public static String fileName (SymtabEntry entry, NameModifier modifier, String extension ) 184 { 185 // This may not be the most appropriate place for 186 // the mkdir calls, but it's common to everything: 187 String pkg = containerFullName (entry.container ()); 188 if (pkg != null && !pkg.equals ("")) 189 mkdir (pkg); 190 191 String name = entry.name (); 192 name = modifier.makeName( name ) + extension ; 193 if (pkg != null && !pkg.equals ("")) 194 name = pkg + '/' + name; 195 196 return name.replace ('/', File.separatorChar); 197 } // fileName 198 199 public static GenFileStream stream (SymtabEntry entry, String extension) 200 { 201 NameModifier nm = new NameModifierImpl() ; 202 return stream(entry, nm, extension); 203 } // stream 204 205 public static GenFileStream stream (SymtabEntry entry, NameModifier modifier, String extension ) 206 { 207 return getStream ( fileName (entry,modifier,extension), entry ) ; 208 } 209 210 public static GenFileStream getStream (String name, SymtabEntry entry) 211 { 212 // <f46838.4> 213 String absPathName = ((Arguments)Compile.compiler.arguments).targetDir + name; 214 if (Compile.compiler.arguments.keepOldFiles && new File (absPathName).exists ()) 215 return null; 216 else 217 // Write the data to the file stream 218 return new GenFileStream (absPathName); 219 } // getStream 220 221 public static String containerFullName( SymtabEntry container) 222 { 223 String name = doContainerFullName( container ) ; 224 if (packageTranslation.size() > 0) 225 name = translate( name ) ; 226 return name ; 227 } 228 229 public static String translate( String name ) 230 { 231 String head = name ; 232 String tail = "" ; 233 int index ; 234 String trname ; 235 236 // Check for package name translations, starting with the 237 // most specific match. 238 do { 239 trname = (String)(packageTranslation.get( head )) ; 240 if (trname != null) 241 return trname + tail ; 242 243 index = head.lastIndexOf( '/' ) ; 244 if (index >= 0) { 245 tail = head.substring( index ) + tail ; 246 head = head.substring( 0, index ) ; 247 } 248 } while (index >= 0) ; 249 250 return name ; 251 } 252 253 private static String doContainerFullName (SymtabEntry container) 254 { 255 String name = ""; 256 257 if (container == null) 258 name = ""; 259 else 260 { 261 if (container instanceof InterfaceEntry || 262 container instanceof StructEntry || 263 container instanceof UnionEntry) 264 name = container.name () + "Package"; 265 else 266 name = container.name (); 267 268 if (container.container () != null && 269 !container.container ().name ().equals ("")) 270 name = doContainerFullName (container.container ()) + '/' + name; 271 } 272 273 return name; 274 } // doContainerFullName 275 276 /** 277 * Given a SymtabEntry, return the string which should be used 278 * for this entry. Enums are converted to ints, typedefs and 279 * sequences are converted to their info types. javaQualifiedName 280 * does not do any of these conversions. 281 **/ 282 public static String javaName (SymtabEntry entry) 283 { 284 // First get the real name of this type 285 String name = ""; 286 if (entry instanceof TypedefEntry || entry instanceof SequenceEntry) 287 try 288 { 289 name = sansArrayInfo ((String)entry.dynamicVariable (Compile.typedefInfo)); 290 } 291 catch (NoSuchFieldException e) 292 { 293 name = entry.name (); 294 } 295 else if (entry instanceof PrimitiveEntry) 296 name = javaPrimName (entry.name ()); 297 else if (entry instanceof StringEntry) 298 name = "String"; 299 else if (entry instanceof NativeEntry) 300 name = javaNativeName (entry.name()); 301 else if (entry instanceof ValueEntry && entry.name ().equals ("ValueBase")) 302 name = "java.io.Serializable"; 303 else if (entry instanceof ValueBoxEntry) 304 { 305 ValueBoxEntry v = (ValueBoxEntry) entry; 306 TypedefEntry member = ((InterfaceState) v.state ().elementAt (0)).entry; 307 SymtabEntry mType = member.type (); 308 if (mType instanceof PrimitiveEntry) 309 { 310 name = containerFullName (entry.container ()); 311 if (!name.equals ("")) 312 name = name + '.'; 313 name = name + entry.name (); 314 } 315 else 316 name = javaName (mType); 317 } 318 else 319 { 320 name = containerFullName (entry.container ()); 321 if (name.equals ("")) 322 name = entry.name (); 323 else 324 name = name + '.' + entry.name (); 325 } 326 327 // Make it a fully package-qualified name 328 return name.replace ('/', '.'); 329 } // javaName 330 331 public static String javaPrimName (String name) 332 { 333 if (name.equals ("long") || name.equals ("unsigned long")) 334 name = "int"; 335 else if (name.equals ("octet")) 336 name = "byte"; 337 // "unisigned long long" exceeds Java long. 338 else if (name.equals ("long long") || name.equals ("unsigned long long")) 339 name = "long"; 340 else if (name.equals ("wchar")) 341 name = "char"; 342 else if (name.equals ("unsigned short")) 343 name = "short"; 344 else if (name.equals ("any")) 345 name = "org.omg.CORBA.Any"; 346 else if (name.equals ("TypeCode")) 347 name = "org.omg.CORBA.TypeCode"; 348 else if (name.equals ("Principal")) // <d61961> 349 name = "org.omg.CORBA.Principal"; 350 return name; 351 } // javaPrimName 352 353 public static String javaNativeName (String name) 354 { 355 356 // translations for Native declarations according to CORBA 2.3 spec 357 358 if (name.equals ("AbstractBase") || name.equals ("Cookie")) 359 name = "java.lang.Object"; 360 else if (name.equals ("Servant")) 361 name = "org.omg.PortableServer.Servant"; 362 else if (name.equals ("ValueFactory")) 363 name = "org.omg.CORBA.portable.ValueFactory"; 364 return name; 365 } 366 367 368 /** 369 * Given a symtabEntry, return the name of this entry. This 370 * method does not do any conversions like javaName does. 371 **/ 372 public static String javaQualifiedName (SymtabEntry entry) 373 { 374 String name = ""; 375 if (entry instanceof PrimitiveEntry) 376 name = javaPrimName (entry.name ()); 377 else if (entry instanceof StringEntry) 378 name = "String"; 379 else if (entry instanceof ValueEntry && entry.name ().equals ("ValueBase")) 380 name = "java.io.Serializable"; 381 else 382 { 383 SymtabEntry container = entry.container (); 384 if (container != null) 385 name = container.name (); 386 if (name.equals ("")) 387 name = entry.name (); 388 else 389 name = containerFullName (entry.container ()) + '.' + entry.name (); 390 } 391 return name.replace ('/', '.'); 392 } // javaQualifiedName 393 394 // <f46082.03> Publicize for extensions. 395 //static String collapseName (String name) 396 397 /** 398 * Collapse primitive type names. 399 **/ 400 public static String collapseName (String name) 401 { 402 if (name.equals ("unsigned short")) 403 name = "ushort"; 404 else if (name.equals ("unsigned long")) 405 name = "ulong"; 406 else if (name.equals ("unsigned long long")) 407 name = "ulonglong"; 408 else if (name.equals ("long long")) 409 name = "longlong"; 410 return name; 411 } // collapseName 412 413 /** 414 * 415 **/ 416 public static SymtabEntry typeOf (SymtabEntry entry) 417 { 418 while (entry instanceof TypedefEntry && ((TypedefEntry)entry).arrayInfo ().isEmpty () && !(entry.type () instanceof SequenceEntry)) 419 entry = entry.type (); 420 return entry; 421 } // typeOf 422 423 /** 424 * Fill the info field with the full name (with array info) of the type. 425 **/ 426 static void fillInfo (SymtabEntry infoEntry) 427 { 428 String arrayInfo = ""; 429 SymtabEntry entry = infoEntry; 430 boolean alreadyHave = false; 431 432 do 433 { 434 try 435 { 436 alreadyHave = entry.dynamicVariable (Compile.typedefInfo) != null; 437 } 438 catch (NoSuchFieldException e) 439 {} 440 // If this entry's info has already been processed 441 // don't bother processing it again, just take it. 442 if (!alreadyHave) 443 { 444 if (entry instanceof TypedefEntry) 445 arrayInfo = arrayInfo + arrayInfo (((TypedefEntry)entry).arrayInfo ()); 446 else if (entry instanceof SequenceEntry) 447 { 448 Expression maxSize = ((SequenceEntry)entry).maxSize (); 449 if (maxSize == null) 450 arrayInfo = arrayInfo + "[]"; 451 else 452 arrayInfo = arrayInfo + '[' + parseExpression (maxSize) + ']'; 453 } 454 if (entry.type () == null) 455 { 456 // <d59437> Suppress this message. It tells the developer nothing, and 457 // this path does not cause the algorithm to fail. Value boxes may 458 // contain anonymous types, like a struct or enum. 459 //System.err.println (getMessage ("PreEmit.indeterminateTypeInfo", entry.typeName ())); 460 } 461 else 462 entry = entry.type (); 463 } 464 } while (!alreadyHave && entry != null && 465 (entry instanceof TypedefEntry || entry instanceof SequenceEntry)); 466 // <d59437> Value boxes may contain types lacking typename info., which 467 // causes the 2nd case, below, to fail with exception when retrieving the 468 // javaName(). 469 if (entry instanceof ValueBoxEntry) 470 fillValueBoxInfo ((ValueBoxEntry)entry); 471 try 472 { 473 if (alreadyHave) 474 infoEntry.dynamicVariable (Compile.typedefInfo, (String)entry.dynamicVariable (Compile.typedefInfo) + arrayInfo); 475 else 476 infoEntry.dynamicVariable (Compile.typedefInfo, javaName (entry) + arrayInfo); 477 } 478 catch (NoSuchFieldException e) 479 {} 480 } // fillInfo 481 482 // <d59437> 483 /** 484 * 485 **/ 486 static void fillValueBoxInfo (ValueBoxEntry vb) 487 { 488 SymtabEntry stateMember = (((InterfaceState) vb.state ().elementAt (0)).entry); 489 if (stateMember.type() != null) 490 Util.fillInfo (stateMember.type ()); 491 Util.fillInfo (stateMember); 492 } // fillValueBoxInfo 493 494 /** 495 * 496 **/ 497 public static String holderName (SymtabEntry entry) 498 { 499 String name; 500 if (entry instanceof PrimitiveEntry) 501 if (entry.name ().equals ("any")) 502 name = "org.omg.CORBA.AnyHolder"; 503 else if (entry.name ().equals ("TypeCode")) 504 name = "org.omg.CORBA.TypeCodeHolder"; 505 else if (entry.name ().equals ("Principal")) // <d61961> 506 name = "org.omg.CORBA.PrincipalHolder"; 507 else 508 name = "org.omg.CORBA." + capitalize (javaQualifiedName (entry)) + "Holder"; 509 else if (entry instanceof TypedefEntry) 510 { 511 TypedefEntry td = (TypedefEntry)entry; 512 if (!td.arrayInfo ().isEmpty () || td.type () instanceof SequenceEntry) 513 name = javaQualifiedName (entry) + "Holder"; 514 else 515 name = holderName (entry.type ()); 516 } 517 else if (entry instanceof StringEntry) 518 name = "org.omg.CORBA.StringHolder"; 519 else if (entry instanceof ValueEntry) 520 { 521 if (entry.name ().equals ("ValueBase")) 522 name = "org.omg.CORBA.ValueBaseHolder"; // <d59421>, <d60929> 523 else 524 name = javaName (entry) + "Holder"; 525 } else if (entry instanceof NativeEntry) { 526 // do not attach holder to the translation for Native Entries, e.g. 527 // for Cookie it should be CookieHolder instead of java.lang.ObjectHolder 528 // returns the complete name for the package, etc. 529 name = javaQualifiedName(entry) + "Holder"; 530 } 531 else 532 name = javaName (entry) + "Holder"; 533 return name; 534 } // holderName 535 536 /** 537 * d61056 538 **/ 539 public static String helperName (SymtabEntry entry, boolean qualifiedName) 540 { 541 if (entry instanceof ValueEntry) 542 if (entry.name ().equals ("ValueBase")) 543 return "org.omg.CORBA.ValueBaseHelper"; 544 545 if (qualifiedName) 546 return javaQualifiedName (entry) + "Helper"; 547 else 548 return javaName (entry) + "Helper"; 549 } // helperName 550 551 public static final short 552 TypeFile = 0, 553 StubFile = 1, 554 HelperFile = 2, 555 HolderFile = 3, 556 StateFile = 4; 557 558 /** 559 * 560 **/ 561 public static void writePackage (PrintWriter stream, SymtabEntry entry) 562 { 563 writePackage (stream, entry, TypeFile); 564 } // writePackage 565 566 /** 567 * 568 **/ 569 public static void writePackage (PrintWriter stream, SymtabEntry entry, String name, short type) 570 { 571 if (name != null && !name.equals ("")) 572 { 573 stream.println ("package " + name.replace ('/', '.') + ';'); 574 575 // This type is in a module. Just in case it refers to types 576 // in the unnamed module, add an import statement for each of 577 // those types. 578 if (!Compile.compiler.importTypes.isEmpty ()) 579 { 580 stream.println (); 581 Vector v = addImportLines (entry, Compile.compiler.importTypes, type); 582 printImports (v, stream); 583 } 584 } 585 } // writePackage 586 587 /** 588 * 589 **/ 590 public static void writePackage (PrintWriter stream, SymtabEntry entry, short type) 591 { 592 String fullName = containerFullName (entry.container ()); 593 if (fullName != null && !fullName.equals ("")) 594 { 595 stream.println ("package " + fullName.replace ('/', '.') + ';'); 596 // This type is in a module. Just in case it refers to types 597 // in the unnamed module, add an import statement for each of 598 // those types. 599 if ((type != HolderFile || entry instanceof TypedefEntry) && !Compile.compiler.importTypes.isEmpty ()) 600 { 601 stream.println (); 602 Vector v = addImportLines (entry, Compile.compiler.importTypes, type); 603 printImports (v, stream); 604 } 605 /* 606 Enumeration e = Compile.compiler.importTypes.elements (); 607 while (e.hasMoreElements ()) 608 { 609 SymtabEntry i = (SymtabEntry)e.nextElement (); 610 // Write import for type 611 if (!(i instanceof TypedefEntry)) 612 stream.println ("import " + i.name () + ';'); 613 614 // Write import for Helper 615 if (!(i instanceof ConstEntry)) 616 stream.println ("import " + i.name () + "Helper;"); 617 618 // Write import for Holder 619 if (!(i instanceof ConstEntry)) 620 if (!(i instanceof TypedefEntry) || (i.type () instanceof SequenceEntry || !((TypedefEntry)i).arrayInfo ().isEmpty ())) 621 stream.println ("import " + i.name () + "Holder;"); 622 } 623 */ 624 } 625 } // writePackage 626 627 /** 628 * 629 **/ 630 static private void printImports (Vector importList, PrintWriter stream) 631 { 632 Enumeration e = importList.elements (); 633 while (e.hasMoreElements ()) 634 stream.println ("import " + (String)e.nextElement () + ';'); 635 } // printImport 636 637 /** 638 * 639 **/ 640 static private void addTo (Vector importList, String name) 641 { 642 // REVISIT - <d62023-klr> was also importing ValueBaseHolder and Helper 643 if (name.startsWith ("ValueBase")) // don't import ValueBase* 644 if ((name.compareTo ("ValueBase") == 0) || 645 (name.compareTo ("ValueBaseHolder") == 0) || 646 (name.compareTo ("ValueBaseHelper") == 0)) 647 return; 648 if (!importList.contains (name)) 649 importList.addElement (name); 650 } // addTo 651 652 /** 653 * 654 **/ 655 static private Vector addImportLines (SymtabEntry entry, Vector importTypes, short type) 656 { 657 Vector importList = new Vector (); 658 if (entry instanceof ConstEntry) 659 { 660 ConstEntry c = (ConstEntry)entry; 661 Object cvalue = c.value ().value (); 662 if (cvalue instanceof ConstEntry && importTypes.contains (cvalue)) 663 addTo (importList, ((ConstEntry)cvalue).name ()); 664 } 665 else if (entry instanceof ValueEntry && type == HelperFile) // <d59512> 666 { 667 // This code inspired by ValueGen.getConcreteBaseTypeCode(). Helper method 668 // type() could be invoked against a global valuetype. 669 if (((ValueEntry)entry).derivedFrom ().size () > 0) // <59596> KLR HACK 670 { 671 ValueEntry base = (ValueEntry)((ValueEntry)entry).derivedFrom ().elementAt (0); 672 String baseName = base.name (); 673 if (!"ValueBase".equals (baseName)) 674 if (importTypes.contains (base)) 675 addTo (importList, baseName + "Helper"); 676 } 677 } 678 else if (entry instanceof InterfaceEntry && (type == TypeFile || type == StubFile)) 679 { 680 InterfaceEntry i = (InterfaceEntry)entry; 681 682 if (i instanceof ValueEntry) // <d59512> 683 { 684 // Examine interface parents in supports vector. 685 Enumeration e = ((ValueEntry)i).supports ().elements (); 686 while (e.hasMoreElements ()) 687 { 688 SymtabEntry parent = (SymtabEntry)e.nextElement (); 689 if (importTypes.contains (parent)) 690 { 691 addTo (importList, parent.name () + "Operations"); 692 } 693 // If this is a stub, then recurse to the parents 694 if (type == StubFile) 695 { 696 if (importTypes.contains (parent)) 697 addTo (importList, parent.name ()); 698 Vector subImportList = addImportLines (parent, importTypes, StubFile); 699 Enumeration en = subImportList.elements (); 700 while (en.hasMoreElements ()) 701 { 702 addTo (importList, (String)en.nextElement ()); 703 } 704 } 705 } 706 } 707 // Interface or valuetype -- Examine interface and valuetype parents, 708 // Look through derivedFrom vector 709 Enumeration e = i.derivedFrom ().elements (); 710 while (e.hasMoreElements ()) 711 { 712 SymtabEntry parent = (SymtabEntry)e.nextElement (); 713 if (importTypes.contains (parent)) 714 { 715 addTo (importList, parent.name ()); 716 // <d59512> Always add both imports, even though superfluous. Cannot 717 // tell when writing Operations or Signature interface! 718 if (!(parent instanceof ValueEntry)) // && parent.name ().equals ("ValueBase"))) 719 addTo (importList, parent.name () + "Operations"); 720 } 721 // If this is a stub, then recurse to the parents 722 if (type == StubFile) 723 { 724 Vector subImportList = addImportLines (parent, importTypes, StubFile); 725 Enumeration en = subImportList.elements (); 726 while (en.hasMoreElements ()) 727 { 728 addTo (importList, (String)en.nextElement ()); 729 } 730 } 731 } 732 // Look through methods vector 733 e = i.methods ().elements (); 734 while (e.hasMoreElements ()) 735 { 736 MethodEntry m = (MethodEntry)e.nextElement (); 737 738 // Look at method type 739 SymtabEntry mtype = typeOf (m.type ()); 740 if (mtype != null && importTypes.contains (mtype)) 741 if (type == TypeFile || type == StubFile) 742 { 743 addTo (importList, mtype.name ()); 744 addTo (importList, mtype.name () + "Holder"); 745 if (type == StubFile) 746 addTo (importList, mtype.name () + "Helper"); 747 } 748 checkForArrays (mtype, importTypes, importList); 749 // <d42256> Print import lines for globals constants and constants 750 // within global interfaces. 751 if (type == StubFile) 752 checkForBounds (mtype, importTypes, importList); 753 754 // Look through exceptions 755 Enumeration exEnum = m.exceptions ().elements (); 756 while (exEnum.hasMoreElements ()) 757 { 758 ExceptionEntry ex = (ExceptionEntry)exEnum.nextElement (); 759 if (importTypes.contains (ex)) 760 { 761 addTo (importList, ex.name ()); 762 addTo (importList, ex.name () + "Helper"); // <d59063> 763 } 764 } 765 766 // Look through parameters 767 Enumeration parms = m.parameters ().elements (); 768 while (parms.hasMoreElements ()) 769 { 770 ParameterEntry parm = (ParameterEntry)parms.nextElement (); 771 SymtabEntry parmType = typeOf (parm.type ()); 772 if (importTypes.contains (parmType)) 773 { 774 // <d59771> Helper needed in stubs. 775 if (type == StubFile) 776 addTo (importList, parmType.name () + "Helper"); 777 if (parm.passType () == ParameterEntry.In) 778 addTo (importList, parmType.name ()); 779 else 780 addTo (importList, parmType.name () + "Holder"); 781 } 782 checkForArrays (parmType, importTypes, importList); 783 // <d42256> 784 if (type == StubFile) 785 checkForBounds (parmType, importTypes, importList); 786 } 787 } 788 } 789 else if (entry instanceof StructEntry) 790 { 791 StructEntry s = (StructEntry)entry; 792 793 // Look through the members 794 Enumeration members = s.members ().elements (); 795 while (members.hasMoreElements ()) 796 { 797 SymtabEntry member = (TypedefEntry)members.nextElement (); 798 // <d48034> Need to add helper name for typedef members. This name 799 // is referenced at typecode generation in Helper class. 800 SymtabEntry memberType = member.type (); 801 member = typeOf (member); 802 if (importTypes.contains (member)) 803 { 804 // If this IS a typedef, then there are only Helper/Holder classes. 805 //if (!(member instanceof TypedefEntry)) 806 // <d59437> Valueboxes 807 if (!(member instanceof TypedefEntry) && !(member instanceof ValueBoxEntry)) 808 addTo (importList, member.name ()); 809 // <d48034> Add helper name of alias, too, if member is a typedef. 810 //if (type == HelperFile) 811 // addTo (importList, member.name () + "Helper"); 812 if (type == HelperFile) 813 { 814 addTo (importList, member.name () + "Helper"); 815 if (memberType instanceof TypedefEntry) 816 addTo (importList, memberType.name () + "Helper"); 817 } 818 } 819 checkForArrays (member, importTypes, importList); 820 checkForBounds (member, importTypes, importList); 821 } 822 } 823 else if (entry instanceof TypedefEntry) 824 { 825 TypedefEntry t = (TypedefEntry)entry; 826 String arrays = checkForArrayBase (t, importTypes, importList); 827 if (type == HelperFile) 828 { 829 checkForArrayDimensions (arrays, importTypes, importList); 830 try 831 { 832 String name = (String)t.dynamicVariable (Compile.typedefInfo); 833 int index = name.indexOf ('['); 834 if (index >= 0) 835 name = name.substring (0, index); 836 // See if the base type should be added to the list. 837 SymtabEntry typeEntry = (SymtabEntry)symbolTable.get (name); 838 if (typeEntry != null && importTypes.contains (typeEntry)) 839 addTo (importList, typeEntry.name () + "Helper"); 840 } 841 catch (NoSuchFieldException e) 842 {} 843 844 // <d42256> Typedefs for global bounded strings need import 845 // statement when bound expression contains non-literal constants. 846 checkForBounds (typeOf (t), importTypes, importList); 847 } 848 Vector subImportList = addImportLines (t.type (), importTypes, type); 849 Enumeration e = subImportList.elements (); 850 while (e.hasMoreElements ()) 851 addTo (importList, (String)e.nextElement ()); 852 } 853 else if (entry instanceof UnionEntry) 854 { 855 UnionEntry u = (UnionEntry)entry; 856 857 // Look at the discriminant type 858 SymtabEntry utype = typeOf (u.type ()); 859 if (utype instanceof EnumEntry && importTypes.contains (utype)) 860 addTo (importList, utype.name ()); 861 862 // Look through the branches 863 Enumeration branches = u.branches ().elements (); 864 while (branches.hasMoreElements ()) 865 { 866 UnionBranch branch = (UnionBranch)branches.nextElement (); 867 SymtabEntry branchEntry = typeOf (branch.typedef); 868 if (importTypes.contains (branchEntry)) 869 { 870 addTo (importList, branchEntry.name ()); 871 if (type == HelperFile) 872 addTo (importList, branchEntry.name () + "Helper"); 873 } 874 checkForArrays (branchEntry, importTypes, importList); 875 // <d42256> 876 checkForBounds (branchEntry, importTypes, importList); 877 } 878 } 879 880 // If a typedef is not a sequence or an array, only holders and 881 // helpers are generated for it. Remove references to such 882 // class names. 883 Enumeration en = importList.elements (); 884 while (en.hasMoreElements ()) 885 { 886 String name = (String)en.nextElement (); 887 SymtabEntry e = (SymtabEntry)symbolTable.get (name); 888 if (e != null && e instanceof TypedefEntry) 889 { 890 TypedefEntry t = (TypedefEntry)e; 891 if (t.arrayInfo ().size () == 0 || !(t.type () instanceof SequenceEntry)) 892 importList.removeElement (name); 893 } 894 } 895 return importList; 896 } // addImportLines 897 898 /** 899 * 900 **/ 901 static private void checkForArrays (SymtabEntry entry, Vector importTypes, Vector importList) 902 { 903 if (entry instanceof TypedefEntry) 904 { 905 TypedefEntry t = (TypedefEntry)entry; 906 String arrays = checkForArrayBase (t, importTypes, importList); 907 checkForArrayDimensions (arrays, importTypes, importList); 908 } 909 } // checkForArrays 910 911 /** 912 * 913 **/ 914 static private String checkForArrayBase (TypedefEntry t, Vector importTypes, Vector importList) 915 { 916 String arrays = ""; 917 try 918 { 919 String name = (String)t.dynamicVariable (Compile.typedefInfo); 920 int index = name.indexOf ('['); 921 if (index >= 0) 922 { 923 arrays = name.substring (index); 924 name = name.substring (0, index); 925 } 926 927 // See if the base type should be added to the list. 928 SymtabEntry typeEntry = (SymtabEntry)symbolTable.get (name); 929 if (typeEntry != null && importTypes.contains (typeEntry)) 930 addTo (importList, typeEntry.name ()); 931 } 932 catch (NoSuchFieldException e) 933 {} 934 return arrays; 935 } // checkForArrayBase 936 937 /** 938 * 939 **/ 940 static private void checkForArrayDimensions (String arrays, Vector importTypes, Vector importList) 941 { 942 // See if any of the arrays contain a constentry. 943 // If so, see if it should be added to the list. 944 while (!arrays.equals ("")) 945 { 946 int index = arrays.indexOf (']'); 947 String dim = arrays.substring (1, index); 948 arrays = arrays.substring (index + 1); 949 SymtabEntry constant = (SymtabEntry)symbolTable.get (dim); 950 if (constant == null) 951 { 952 // A constant expr could be of the form <const> OR 953 // <interface>.<const>. This if branch checks for that case. 954 int i = dim.lastIndexOf ('.'); 955 if (i >= 0) 956 constant = (SymtabEntry)symbolTable.get (dim.substring (0, i)); 957 } 958 if (constant != null && importTypes.contains (constant)) 959 addTo (importList, constant.name ()); 960 } 961 } // checkForArrayDimensions 962 963 // <d42256> Call the following method when its necessary to determine the 964 // the import types for IDL constructs containing arbitrary positive int. 965 // expressions, which may specify non-literal constants. 966 967 /** 968 * Determine the import lines for template types. 969 **/ 970 static private void checkForBounds (SymtabEntry entry, Vector importTypes, Vector importList) 971 { 972 // Obtain actual type, just to be complete. 973 SymtabEntry entryType = entry; 974 while (entryType instanceof TypedefEntry) 975 entryType = entryType.type (); 976 977 if (entryType instanceof StringEntry && ((StringEntry)entryType).maxSize () != null) 978 checkForGlobalConstants (((StringEntry)entryType).maxSize ().rep (), importTypes, importList); 979 else 980 if (entryType instanceof SequenceEntry && ((SequenceEntry)entryType).maxSize () != null) 981 checkForGlobalConstants (((SequenceEntry)entryType).maxSize ().rep (), importTypes, importList); 982 } // checkForBounds 983 984 /** 985 * Extract the global constants from the supplied integer expression 986 * representation (string) and add them to the supplied import list. 987 **/ 988 static private void checkForGlobalConstants (String exprRep, Vector importTypes, Vector importList) 989 { 990 // NOTE: Do not use '/' as a delimiter. Symbol table names use '/' as a 991 // delimiter and would not be otherwise properly collected. Blanks and 992 // arithmetic symbols do not appear in tokens, except for '/'. 993 java.util.StringTokenizer st = new java.util.StringTokenizer (exprRep, " +-*()~&|^%<>"); 994 while (st.hasMoreTokens ()) 995 { 996 String token = st.nextToken (); 997 // When token contains '/', it represents the division symbol or 998 // a nested type (e.g., I/x). Ignore the division symbol, and don't 999 // forget constants declared within global interfaces! 1000 if (!token.equals ("/")) 1001 { 1002 SymtabEntry typeEntry = (SymtabEntry)symbolTable.get (token); 1003 if (typeEntry instanceof ConstEntry) 1004 { 1005 int slashIdx = token.indexOf ('/'); 1006 if (slashIdx < 0) // Possible global constant 1007 { 1008 if (importTypes.contains (typeEntry)) 1009 addTo (importList, typeEntry.name ()); 1010 } 1011 else // Possible constant in global interface 1012 { 1013 SymtabEntry constContainer = (SymtabEntry)symbolTable.get (token.substring (0, slashIdx)); 1014 if (constContainer instanceof InterfaceEntry && importTypes.contains (constContainer)) 1015 addTo (importList, constContainer.name ()); 1016 } 1017 } 1018 } 1019 } 1020 } // checkForGlobalConstants 1021 1022 /** 1023 * 1024 **/ 1025 public static void writeInitializer (String indent, String name, String arrayDcl, SymtabEntry entry, PrintWriter stream) 1026 { 1027 if (entry instanceof TypedefEntry) 1028 { 1029 TypedefEntry td = (TypedefEntry)entry; 1030 writeInitializer (indent, name, arrayDcl + sansArrayInfo (td.arrayInfo ()), td.type (), stream); 1031 } 1032 else if (entry instanceof SequenceEntry) 1033 writeInitializer (indent, name, arrayDcl + "[]", entry.type (), stream); 1034 else if (entry instanceof EnumEntry) 1035 if (arrayDcl.length () > 0) 1036 stream.println (indent + javaName (entry) + ' ' + name + arrayDcl + " = null;"); 1037 else 1038 stream.println (indent + javaName (entry) + ' ' + name + " = null;"); 1039 else if (entry instanceof PrimitiveEntry) 1040 { 1041 boolean array = arrayDcl.length () > 0; 1042 String tname = javaPrimName (entry.name ()); 1043 if (tname.equals ("boolean")) 1044 stream.println (indent + "boolean " + name + arrayDcl + " = " + (array ? "null;" : "false;")); 1045 else if (tname.equals ("org.omg.CORBA.TypeCode")) 1046 stream.println (indent + "org.omg.CORBA.TypeCode " + name + arrayDcl + " = null;"); 1047 else if (tname.equals ("org.omg.CORBA.Any")) 1048 stream.println (indent + "org.omg.CORBA.Any " + name + arrayDcl + " = null;"); 1049 else if (tname.equals ("org.omg.CORBA.Principal")) // <d61961> 1050 stream.println (indent + "org.omg.CORBA.Principal " + name + arrayDcl + " = null;"); 1051 else 1052 stream.println (indent + tname + ' ' + name + arrayDcl + " = " + (array ? "null;" : '(' + tname + ")0;")); 1053 } 1054 // <f46082.51> Remove -stateful feature. This case is identical to next one 1055 // because javaName() supplants javaStatefulName(). 1056 //else if (entry instanceof InterfaceEntry && ((InterfaceEntry)entry).state () != null) 1057 // stream.println (indent + javaStatefulName ((InterfaceEntry)entry) + ' ' + name + arrayDcl + " = null;"); 1058 else 1059 stream.println (indent + javaName (entry) + ' ' + name + arrayDcl + " = null;"); 1060 } // writeInitializer 1061 1062 /** 1063 * 1064 **/ 1065 public static void writeInitializer (String indent, String name, String arrayDcl, SymtabEntry entry, String initializer, PrintWriter stream) 1066 { 1067 if (entry instanceof TypedefEntry) 1068 { 1069 TypedefEntry td = (TypedefEntry)entry; 1070 writeInitializer (indent, name, arrayDcl + sansArrayInfo (td.arrayInfo ()), td.type (), initializer, stream); 1071 } 1072 else if (entry instanceof SequenceEntry) 1073 writeInitializer (indent, name, arrayDcl + "[]", entry.type (), initializer, stream); 1074 else if (entry instanceof EnumEntry) 1075 if (arrayDcl.length () > 0) 1076 stream.println (indent + javaName (entry) + ' ' + name + arrayDcl + " = " + initializer + ';'); 1077 else 1078 stream.println (indent + javaName (entry) + ' ' + name + " = " + initializer + ';'); 1079 else if (entry instanceof PrimitiveEntry) 1080 { 1081 boolean array = arrayDcl.length () > 0; 1082 String tname = javaPrimName (entry.name ()); 1083 if (tname.equals ("boolean")) 1084 stream.println (indent + "boolean " + name + arrayDcl + " = " + initializer + ';'); 1085 else if (tname.equals ("org.omg.CORBA.TypeCode")) 1086 stream.println (indent + "org.omg.CORBA.TypeCode " + name + arrayDcl + " = " + initializer + ';'); 1087 else if (tname.equals ("org.omg.CORBA.Any")) 1088 stream.println (indent + "org.omg.CORBA.Any " + name + arrayDcl + " = " + initializer + ';'); 1089 else if (tname.equals ("org.omg.CORBA.Principal")) // <d61961> 1090 stream.println (indent + "org.omg.CORBA.Principal " + name + arrayDcl + " = " + initializer + ';'); 1091 else 1092 stream.println (indent + tname + ' ' + name + arrayDcl + " = " + initializer + ';'); 1093 } 1094 // <f46082.51> Remove -stateful feature. This case is identical to next one 1095 // because javaName() supplants javaStatefulName(). 1096 //else if (entry instanceof InterfaceEntry && ((InterfaceEntry)entry).state () != null) 1097 // stream.println (indent + javaStatefulName ((InterfaceEntry)entry) + ' ' + name + arrayDcl + " = " + initializer + ';'); 1098 else 1099 stream.println (indent + javaName (entry) + ' ' + name + arrayDcl + " = " + initializer + ';'); 1100 } // writeInitializer 1101 1102 /** 1103 * 1104 **/ 1105 public static void mkdir (String name) 1106 { 1107 String targetDir = ((Arguments)Compile.compiler.arguments).targetDir; // F46838.4 1108 name = (targetDir + name).replace ('/', File.separatorChar); // F46838.4 1109 File pkg = new File (name); 1110 if (!pkg.exists ()) 1111 if (!pkg.mkdirs ()) 1112 System.err.println (getMessage ("Util.cantCreatePkg", name)); 1113 } // mkdir 1114 1115 /** 1116 * 1117 **/ 1118 public static void writeProlog (PrintWriter stream, String filename) 1119 { 1120 // <d59355> Remove target directory 1121 String targetDir = ((Arguments)Compile.compiler.arguments).targetDir; 1122 if (targetDir != null) 1123 filename = filename.substring (targetDir.length ()); 1124 stream.println (); 1125 stream.println ("/**"); 1126 stream.println ("* " + filename.replace (File.separatorChar, '/') + 1127 " ."); 1128 stream.println ("* " + Util.getMessage ("toJavaProlog1", 1129 Util.getMessage ("Version.product", Util.getMessage ("Version.number")))); 1130 // <d48911> Do not introduce invalid escape characters into comment! <daz> 1131 //stream.println ("* " + Util.getMessage ("toJavaProlog2", Compile.compiler.arguments.file)); 1132 stream.println ("* " + Util.getMessage ("toJavaProlog2", Compile.compiler.arguments.file.replace (File.separatorChar, '/'))); 1133 1134 /////////////// 1135 // This SHOULD work, but there's a bug in the JDK. 1136 // stream.println ("* " + DateFormat.getDateTimeInstance (DateFormat.FULL, DateFormat.FULL, Locale.getDefault ()).format (new Date ())); 1137 // This gets around the bug: 1138 1139 DateFormat formatter = DateFormat.getDateTimeInstance (DateFormat.FULL, DateFormat.FULL, Locale.getDefault ()); 1140 1141 // Japanese-specific workaround. JDK bug 4069784 being repaired by JavaSoft. 1142 // Keep this transient solution until bug fix is reported.cd . 1143 1144 if (Locale.getDefault () == Locale.JAPAN) 1145 formatter.setTimeZone (java.util.TimeZone.getTimeZone ("JST")); 1146 else 1147 formatter.setTimeZone (java.util.TimeZone.getDefault ()); 1148 1149 stream.println ("* " + formatter.format (new Date ())); 1150 1151 // <daz> 1152 /////////////// 1153 1154 stream.println ("*/"); 1155 stream.println (); 1156 } // writeProlog 1157 1158 // keywords ending in Holder or Helper or Package have '_' prepended. 1159 // These prepended underscores must not be part of anything sent 1160 // across the wire, so these two methods are provided to strip them 1161 // off. 1162 1163 /** 1164 * 1165 **/ 1166 public static String stripLeadingUnderscores (String string) 1167 { 1168 while (string.startsWith ("_")) 1169 string = string.substring (1); 1170 return string; 1171 } // stripLeadingUnderscores 1172 1173 /** 1174 * 1175 **/ 1176 public static String stripLeadingUnderscoresFromID (String string) 1177 { 1178 String stringPrefix = ""; 1179 int slashIndex = string.indexOf (':'); 1180 if (slashIndex >= 0) 1181 do 1182 { 1183 stringPrefix = stringPrefix + string.substring (0, slashIndex + 1); 1184 string = string.substring (slashIndex + 1); 1185 while (string.startsWith ("_")) 1186 string = string.substring (1); 1187 slashIndex = string.indexOf ('/'); 1188 } while (slashIndex >= 0); 1189 return stringPrefix + string; 1190 } // stripLeadingUnderscoresFromID 1191 1192 /** 1193 * 1194 **/ 1195 public static String parseExpression (Expression e) 1196 { 1197 if (e instanceof Terminal) 1198 return parseTerminal ((Terminal)e); 1199 else if (e instanceof BinaryExpr) 1200 return parseBinary ((BinaryExpr)e); 1201 else if (e instanceof UnaryExpr) 1202 return parseUnary ((UnaryExpr)e); 1203 else 1204 return "(UNKNOWN_VALUE)"; // This shouldn't happen unless someone slips 1205 // in another type of expression. 1206 } // parseExpression 1207 1208 /** 1209 * 1210 **/ 1211 static String parseTerminal (Terminal e) 1212 { 1213 if (e.value () instanceof ConstEntry) 1214 { 1215 ConstEntry c = (ConstEntry)e.value (); 1216 if (c.container () instanceof InterfaceEntry) 1217 return javaQualifiedName (c.container ()) + '.' + c.name (); 1218 else 1219 return javaQualifiedName (c) + ".value"; 1220 } 1221 else if (e.value () instanceof Expression) 1222 return '(' + parseExpression ((Expression)e.value ()) + ')'; 1223 else if (e.value () instanceof Character) 1224 { 1225 if (((Character)e.value ()).charValue () == '\013') 1226 // e.rep is \v. \v for vertical tab is meaningless in Java. 1227 return "'\\013'"; 1228 else if (((Character)e.value ()).charValue () == '\007') 1229 // e.rep is \a. \a for alert is meaningless in Java. 1230 return "'\\007'"; 1231 else if (e.rep ().startsWith ("'\\x")) 1232 return hexToOctal (e.rep ()); 1233 else if (e.rep ().equals ("'\\?'")) 1234 return "'?'"; 1235 else 1236 return e.rep (); 1237 } 1238 else if (e.value () instanceof Boolean) 1239 return e.value ().toString (); 1240 1241 // <d54640> If value is type "unsigned long long" (ull) and its magnitude 1242 // is greater than the maximal Java long (i.e., IDL long long) value, then 1243 // return its signed representation rather than its actual representation. 1244 /* 1245 // Support long long 1246 //else if (e.value () instanceof Long) 1247 else if (e.value () instanceof BigInteger && 1248 (e.type ().indexOf ("long long") >= 0 || e.type ().equals ("unsigned long"))) // <klr> 1249 { 1250 String rep = e.rep (); 1251 int index = rep.indexOf (')'); 1252 if (index < 0) 1253 return rep + 'L'; 1254 else 1255 return rep.substring (0, index) + 'L' + rep.substring (index); 1256 } 1257 */ 1258 else if (e.value () instanceof BigInteger) 1259 { 1260 // Get the correct primitive type. Since integer types (octet, short, 1261 // long, long long, unsigned short, unsigned long, unsigned long long) 1262 // could be aliased (typedef'ed) to any arbitrary levels, the code 1263 // below walks up the alias chain to get to the primitive type. 1264 1265 // Get the symbol table entry corresponding to the 'type'. 1266 SymtabEntry typeEntry = (SymtabEntry) symbolTable.get(e.type()); 1267 1268 // Get to the primitive type. 1269 while (typeEntry.type() != null) { 1270 typeEntry = typeEntry.type(); 1271 } 1272 String type = typeEntry.name(); 1273 1274 if (type.equals("unsigned long long") && 1275 ((BigInteger)e.value ()).compareTo (Expression.llMax) > 0) // value > long long Max? 1276 { 1277 // Convert to signed value, which will always be negative. 1278 BigInteger v = (BigInteger)e.value (); 1279 v = v.subtract (Expression.twoPow64); 1280 int index = e.rep ().indexOf (')'); 1281 if (index < 0) 1282 return v.toString () + 'L'; 1283 else 1284 return '(' + v.toString () + 'L' + ')'; 1285 } 1286 else if ( type.indexOf("long long") >= 0 || type.equals("unsigned long") ) 1287 { 1288 String rep = e.rep (); 1289 int index = rep.indexOf (')'); 1290 if (index < 0) 1291 return rep + 'L'; 1292 else 1293 return rep.substring (0, index) + 'L' + rep.substring (index); 1294 } 1295 else 1296 return e.rep (); 1297 } // end <d54640> 1298 else 1299 return e.rep (); 1300 } // parseTerminal 1301 1302 /** 1303 * 1304 **/ 1305 static String hexToOctal (String hex) 1306 { 1307 // The format of hex is '/xXX' where XX is one or two hex digits. 1308 // This statement pulls off XX. 1309 hex = hex.substring (3, hex.length () - 1); 1310 return "'\\" + Integer.toString (Integer.parseInt (hex, 16), 8) + "'"; 1311 } // hexToOctal 1312 1313 /** 1314 * 1315 **/ 1316 static String parseBinary (BinaryExpr e) 1317 { 1318 String castString = ""; 1319 if (e.value () instanceof Float || e.value () instanceof Double) 1320 { 1321 castString = "(double)"; 1322 if (!(e instanceof Plus || e instanceof Minus || 1323 e instanceof Times || e instanceof Divide)) 1324 System.err.println ("Operator " + e.op () + " is invalid on floating point numbers"); 1325 } 1326 else if (e.value () instanceof Number) 1327 { 1328 if (e.type (). indexOf ("long long") >= 0) 1329 castString = "(long)"; 1330 else 1331 castString = "(int)"; 1332 } 1333 else 1334 { 1335 castString = ""; 1336 System.err.println ("Unknown type in constant expression"); 1337 } 1338 1339 // <d54640> Must emit value rather than representation when type "unsigned 1340 // long long" (ull) because emitted binary arithmetic expressions containing 1341 // ull's converted to long (i.e., IDL long long) do not always compute to 1342 // the correct result. 1343 1344 //return castString + '(' + parseExpression (e.left ()) + ' ' + e.op () + ' ' + parseExpression (e.right ()) + ')'; 1345 if (e.type ().equals ("unsigned long long")) 1346 { 1347 BigInteger value = (BigInteger)e.value (); 1348 if (value.compareTo (Expression.llMax) > 0) // value > long long max? 1349 value = value.subtract (Expression.twoPow64); // Convert to Java long (signed) 1350 return castString + '(' + value.toString () + 'L' + ')'; 1351 } 1352 else 1353 return castString + '(' + parseExpression (e.left ()) + ' ' + e.op () + ' ' + parseExpression (e.right ()) + ')'; 1354 // <d54640> end 1355 } // parseBinary 1356 1357 /** 1358 * 1359 **/ 1360 static String parseUnary (UnaryExpr e) 1361 { 1362 if (!(e.value () instanceof Number)) 1363 return "(UNKNOWN_VALUE)"; // This shouldn't happen if the parser checked the expression types correctly. 1364 else if ((e.value () instanceof Float || e.value () instanceof Double) && e instanceof Not) 1365 return "(UNKNOWN_VALUE)"; // This shouldn't happen if the parser checked the expression types correctly. 1366 else 1367 { 1368 String castString = ""; 1369 if (e.operand ().value () instanceof Float || 1370 e.operand ().value () instanceof Double) 1371 castString = "(double)"; 1372 // Support long long. 1373 //else 1374 // castString = "(long)"; 1375 else if (e.type (). indexOf ("long long") >= 0) 1376 castString = "(long)"; 1377 else 1378 castString = "(int)"; 1379 1380 // <d54640> Must emit value rather than representation when type is 1381 // "unsigned long long" (ull) because emitted unary arithmetic expressions 1382 // containing a ull converted to long (i.e., IDL long long) do not always 1383 // compute to the correct result. 1384 1385 //return castString + e.op () + parseExpression (e.operand ()); 1386 if (e.type ().equals ("unsigned long long")) 1387 { 1388 BigInteger value = (BigInteger)e.value (); 1389 if (value.compareTo (Expression.llMax) > 0) // value > long long max? 1390 value = value.subtract (Expression.twoPow64); // Convert to Java long (signed) 1391 return castString + '(' + value.toString () + 'L' + ')'; 1392 } 1393 else 1394 return castString + e.op () + parseExpression (e.operand ()); 1395 // end <d54640> 1396 } 1397 } // parseUnary 1398 1399 /** 1400 * 1401 **/ 1402 public static boolean IDLEntity (SymtabEntry entry) 1403 { 1404 boolean rc = true; 1405 if (entry instanceof PrimitiveEntry || entry instanceof StringEntry) 1406 rc = false; 1407 else if (entry instanceof TypedefEntry) 1408 rc = IDLEntity (entry.type ()); 1409 return rc; 1410 } // IDLEntity 1411 1412 // <d62023> 1413 /** 1414 * @return true if the current setting of corbaLevel is within delta of 1415 * the range {@code min <= corbaLevel <= max} 1416 **/ 1417 public static boolean corbaLevel (float min, float max) 1418 { 1419 float level = Compile.compiler.arguments.corbaLevel; 1420 float delta = 0.001f; 1421 if ((level - min + delta >= 0.0f) && (max - level + delta >= 0.0f)) 1422 return true; 1423 else 1424 return false; 1425 } // corbaLevel 1426 1427 static Hashtable symbolTable = new Hashtable (); 1428 static Hashtable packageTranslation = new Hashtable() ; 1429 } // class Util