Compile.java revision 608:7e06bf1dcb09
1/*
2 * Copyright (c) 1999, 2001, 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
36package com.sun.tools.corba.se.idl.toJavaPortable;
37
38// NOTES:
39// -09/23/98 KLR Ported -m updates (F46838.1-3)
40// -f46082.51<daz> Transferred makefile list generation (for ODE delta-builds,
41//  see f46838) to toJava; cleaned-out dead code.
42// -D58319<daz> Display version info. for -version option.
43// -D58951<daz> Modify to allow QuickTest to build.
44// -D49526<daz> Remove "TypeCode" symbol from preParse().
45// -D58591<daz> Publicise _factories and compile for QuickTest.  Need to revert
46//  t0 private and add accessor methods.
47// -D59437<daz> Fill typename information for value boxes.
48
49import java.io.File;
50import java.io.IOException;
51import java.io.BufferedWriter;
52import java.io.FileWriter;
53import java.io.PrintWriter;
54
55import java.util.Enumeration;
56import java.util.Hashtable;
57import java.util.Vector;
58
59import com.sun.tools.corba.se.idl.GenFileStream;
60import com.sun.tools.corba.se.idl.SymtabFactory;
61import com.sun.tools.corba.se.idl.IncludeEntry;
62import com.sun.tools.corba.se.idl.InterfaceEntry;
63import com.sun.tools.corba.se.idl.InterfaceState;
64import com.sun.tools.corba.se.idl.ModuleEntry;
65import com.sun.tools.corba.se.idl.PrimitiveEntry;
66import com.sun.tools.corba.se.idl.SequenceEntry;
67import com.sun.tools.corba.se.idl.StructEntry;
68import com.sun.tools.corba.se.idl.SymtabEntry;
69import com.sun.tools.corba.se.idl.TypedefEntry;
70import com.sun.tools.corba.se.idl.UnionBranch;
71import com.sun.tools.corba.se.idl.UnionEntry;
72import com.sun.tools.corba.se.idl.ValueEntry;
73import com.sun.tools.corba.se.idl.ValueBoxEntry;
74import com.sun.tools.corba.se.idl.InvalidArgument;
75
76/**
77 * Compiler usage:
78 * <br><br>
79 *
80 * java com.sun.tools.corba.se.idl.toJavaPortable.Compile [options] &lt;idl file&gt;
81 * <br><br>
82 *
83 * where &lt;idl file&gt; is the name of a file containing IDL definitions,
84 * and [options] is any combination of the options listed below.  The options
85 * may appear in any order.
86 * <br><br>
87 *
88 * Options:
89 * <dl>
90 *   <dt>-i &lt;include path&gt;
91 *   <dd>By default, the current directory is scanned for included files.
92 *   This option adds another directory.  See also the note below.
93 *
94 *   <dt>-d &lt;symbol&gt;
95 *   <dd>This is equivalent to the following line in an IDL file:
96 *   #define &lt;symbol&gt;
97 *
98 *   <dt>-f<side>
99 *   <dd>Defines what bindings to emit.  <side> is one of client, server, all,
100 *   serverTIE, allTIE.  serverTIE and allTIE cause delegate model skeletons
101 *   to be emitted. If this flag is not used, -fclient is assumed.
102 *   allPOA has the same effect as all, except for generation POA type skeletons.
103 *
104 *   <dt>-keep
105 *   <dd>If a file to be generated already exists, do not overwrite it. By
106 *   default it is overwritten.
107 *
108 *   <dt>-sep <string>
109 *   <dd>Only valid with -m.  Replace the file separator character with
110 *     <string> in the file names listed in the .u file.
111 *
112 *   <dt>-emitAll
113 *   <dd>Emit all types, including those found in #included files.
114 *
115 *   <dt>-v
116 *   <dd>Verbose mode.
117 *
118 *   <dt>-pkgPrefix <type> <package>
119 *   <dd>Whereever <type> is encountered, make sure it resides within
120 *   &lt;package&gt; in all generated files.  &lt;type&gt; is a fully
121 *   qualified, java-style name.
122 * </dl>
123 *
124 * <B>Note:</B> If you have an include path or paths that you will always
125 * be using, it can get tedious putting these on the command with the -i
126 * option all the time.  Instead, these can be placed into a config file
127 * called idl.config.  This file must be in the CLASSPATH.  The format of
128 * the includes line is:
129 *
130 * <pre>
131 * includes=<path1>;<path2>;...;<pathN>
132 * </pre>
133 *
134 * Note that the path separator character, here shown as a semicolon,
135 * is machine dependent.  For instance, on Windows 95 this character
136 * is a semicolon, on UNIX it is a colon.
137 **/
138public class Compile extends com.sun.tools.corba.se.idl.Compile
139{
140 /**
141  *
142  **/
143  public static void main (String[] args)
144  {
145    compiler = new Compile ();
146    compiler.start (args);
147  } // main
148
149 /**
150  *
151  **/
152  public void start (String[] args)
153  {
154    try
155    {
156      // <f46082.51> Use generator-specific messages file.
157      //Util.registerMessageFile ("com/sun/corba/se/idl/toJavaPortable/toJava.prp");
158      Util.registerMessageFile ("com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable.prp");
159      init (args);
160      if (arguments.versionRequest)
161        displayVersion ();
162      else
163      {
164        preParse ();
165        Enumeration e = parse ();
166        if (e != null)
167        {
168          preEmit (e);
169          generate ();
170          // <f46082.03> Move ODE delta-build support to toJava
171          //if (((Arguments)arguments).genMakefileLists)
172          //  generateMakefileLists ();
173        }
174      }
175    }
176    catch (InvalidArgument e)
177    {
178      System.err.println (e);
179    }
180    catch (IOException e)
181    {
182      System.err.println (e);
183    }
184  } // start
185
186  /**
187   *
188   **/
189  protected Compile ()
190  {
191    factory = factories ().symtabFactory ();
192  } // ctor
193
194  // <d58591> _factories was made public for QuickTest to operate correctly,
195  // but the code needs to be changed to this:
196  //private Factories _factories = null;
197  //protected com.sun.tools.corba.se.idl.Factories factories ()
198  //{
199  //  if (_factories == null)
200  //    _factories = new Factories ();
201  //  return _factories;
202  //} // factories
203
204  public Factories _factories = new Factories ();  // 58974 - changed for quicktest
205  protected com.sun.tools.corba.se.idl.Factories factories ()
206  {
207    return _factories;
208  } // factories
209
210
211  ModuleEntry org;
212  ModuleEntry omg;
213  ModuleEntry corba;
214  InterfaceEntry object;
215
216  /**
217   *
218   **/
219  protected void preParse ()
220  {
221    Util.setSymbolTable (symbolTable);
222    Util.setPackageTranslation( ((Arguments)arguments).packageTranslation ) ;
223
224    // Need modules for the predefined objects
225    org = factory.moduleEntry ();
226    // <d61919> Suppress generation of this module.  If the parser reopens it
227    // while parsing the main IDL source, any definitions appearing in the module
228    // -- and not appearing in a global-scope include file -- will be added to
229    // the emit list with emit=true for eventual generation.
230    org.emit (false);
231    org.name ("org");
232    org.container (null);
233    omg = factory.moduleEntry ();
234    omg.emit (false); // <d61919>
235    omg.name ("omg");
236    omg.module ("org");
237    omg.container (org);
238    org.addContained (omg);
239    corba = factory.moduleEntry ();
240    corba.emit (false); // <d61919>
241    corba.name ("CORBA");
242    corba.module ("org/omg");
243    corba.container (omg);
244    omg.addContained (corba);
245    symbolTable.put ("org", org);
246    symbolTable.put ("org/omg", omg);
247    symbolTable.put ("org/omg/CORBA", corba);
248
249    // Add CORBA::Object to symbol table.
250    object = (InterfaceEntry)symbolTable.get ("Object");
251    object.module ("org/omg/CORBA");
252    object.container (corba);
253    symbolTable.put ("org/omg/CORBA/Object", object);
254
255    // <d61961> Add PIDL type (primitive) CORBA::TypeCode to symbol table.
256    PrimitiveEntry pEntry = factory.primitiveEntry ();
257    pEntry.name ("TypeCode");
258    pEntry.module ("org/omg/CORBA");
259    pEntry.container (corba);
260    symbolTable.put ("org/omg/CORBA/TypeCode", pEntry);
261    symbolTable.put ("CORBA/TypeCode", pEntry);                      // <d55699>
262    overrideNames.put ("CORBA/TypeCode", "org/omg/CORBA/TypeCode");  // <d55699>
263    overrideNames.put ("org/omg/CORBA/TypeCode", "CORBA/TypeCode");  // <d55699>
264    // <d49526> Allow user to specify types named "TypeCode"
265    //symbolTable.put ("TypeCode", pEntry);
266    //overrideNames.put ("TypeCode", "org/omg/CORBA/TypeCode");
267
268    // CORBA::Principal is deprecated!
269    // <d61961> Add PIDL type (primitive) CORBA::Principal to symbol table.
270    pEntry = factory.primitiveEntry ();
271    pEntry.name ("Principal");
272    pEntry.module ("org/omg/CORBA");
273    pEntry.container (corba);
274    symbolTable.put ("org/omg/CORBA/Principle", pEntry);
275    symbolTable.put ("CORBA/Principal", pEntry);
276    overrideNames.put ("CORBA/Principal", "org/omg/CORBA/Principal");
277    overrideNames.put ("org/omg/CORBA/Principal", "CORBA/Principal");
278
279    // <d61961> Add PIDL type (interface) CORBA::Current to symbol table.
280    //InterfaceEntry iEntry = factory.interfaceEntry ();
281    //iEntry.name ("Current");
282    //iEntry.module ("org/omg/CORBA");
283    //iEntry.container (corba);
284    //symbolTable.put ("org/omg/CORBA/Current", iEntry);
285    //symbolTable.put ("CORBA/Current", iEntry);
286    //overrideNames.put ("CORBA/Current", "org/omg/CORBA/Current");
287    //overrideNames.put ("org/omg/CORBA/Current", "CORBA/Current");
288
289    overrideNames.put ("TRUE", "true");
290    overrideNames.put ("FALSE", "false");
291    //overrideNames.put ("any", "org/omg/CORBA/Any");
292
293    // Add CORBA module to symbol table
294    symbolTable.put ("CORBA", corba);  // 55699
295    overrideNames.put ("CORBA", "org/omg/CORBA");  // <d55699>
296    overrideNames.put ("org/omg/CORBA", "CORBA");  // <d55699>
297  } // preParse
298
299
300  protected void preEmit (Enumeration emitList)
301  {
302    typedefInfo = SymtabEntry.getVariableKey ();
303    Hashtable tempST = (Hashtable)symbolTable.clone ();
304
305    for (Enumeration e = tempST.elements (); e.hasMoreElements ();)
306    {
307      SymtabEntry element = (SymtabEntry)e.nextElement ();
308
309      // Any other symbolTable processing?
310      preEmitSTElement (element);
311    }
312
313    // Do this processing AFTER any other processing to get the
314    // correct names.
315    Enumeration elements = symbolTable.elements ();
316    while (elements.hasMoreElements ())
317    {
318      // Find all TypedefEntry's and fill in the SymtabEntry.info
319      // field with it's real type , including [][]... with const
320      // exprs.
321      SymtabEntry element = (SymtabEntry)elements.nextElement ();
322      if (element instanceof TypedefEntry || element instanceof SequenceEntry)
323        Util.fillInfo (element);
324
325      // <d59437> Members of constructed types may now be value boxes, and value
326      // boxes may contain types that are directly defined rather than typedef-ed
327      // (e.g., "valuetype vb sequence <long, 5>;").  If member resolves to a value
328      // box, then check and fillInfo() for value box and its content type BEFORE
329      // doing fillInfo() on member; otherwise, could get an exception.  There's
330      // code in fillInfo() that performs this check, so it does not appear here.
331
332      else if (element instanceof StructEntry)
333      {
334        Enumeration members = ((StructEntry)element).members ().elements ();
335        while (members.hasMoreElements ())
336          Util.fillInfo ((SymtabEntry)members.nextElement ());
337      }
338      else if (element instanceof InterfaceEntry && ((InterfaceEntry)element).state () != null)
339      {
340        Enumeration members = ((InterfaceEntry)element).state ().elements ();
341        while (members.hasMoreElements ())
342          Util.fillInfo (((InterfaceState)members.nextElement ()).entry);
343      }
344      else if (element instanceof UnionEntry)
345      {
346        Enumeration branches = ((UnionEntry)element).branches ().elements ();
347        while (branches.hasMoreElements ())
348          Util.fillInfo (((UnionBranch)branches.nextElement ()).typedef);
349      }
350
351      // For each type that is at the top level that is NOT a module
352      // or IncludeEntry, add it to the imports list.  If there are
353      // types within modules which refer to these, their types must
354      // be explicitly stated in an import statement.
355      if (element.module ().equals ("") && !(element instanceof ModuleEntry || element instanceof IncludeEntry || element instanceof PrimitiveEntry))
356        importTypes.addElement (element);
357    }
358
359    while (emitList.hasMoreElements ())
360    {
361      SymtabEntry entry = (SymtabEntry)emitList.nextElement ();
362
363      // Any other emitList processing:
364      preEmitELElement (entry);
365    }
366  } // preEmit
367
368  /**
369   * This method is called by preEmit once for each symbol table entry.
370   * It can be called by extenders.
371   **/
372  protected void preEmitSTElement (SymtabEntry entry)
373  {
374    // If the -package argument was used, search the packages list
375    // for the given type name and prepend the package to it.
376    Hashtable packages = ((Arguments)arguments).packages;
377    if (packages.size () > 0)
378    {
379      String substr = (String)packages.get (entry.fullName ());
380      if (substr != null)
381      {
382        String pkg = null;
383        ModuleEntry mod = null;
384        ModuleEntry prev = null;
385        while (substr != null)
386        {
387          int dot = substr.indexOf ('.');
388          if (dot < 0)
389          {
390            pkg = substr;
391            substr = null;
392          }
393          else
394          {
395            pkg = substr.substring (0, dot);
396            substr = substr.substring (dot + 1);
397          }
398
399          String fullName = prev == null ? pkg : prev.fullName () + '/' + pkg;
400          mod = (ModuleEntry)symbolTable.get (fullName);
401          if (mod == null)
402          {
403            mod = factory.moduleEntry ();
404            mod.name (pkg);
405            mod.container (prev);
406            if (prev != null) mod.module (prev.fullName ());
407            symbolTable.put (pkg, mod);
408          }
409          prev = mod;
410        }
411        entry.module (mod.fullName ());
412        entry.container (mod);
413      }
414    }
415  } // preEmitSTElement
416
417  /**
418   * This method is called by preEmit once for each emitList entry.
419   * It can be called by extenders.
420   **/
421  protected void preEmitELElement (SymtabEntry entry)
422  {
423  } // preEmitELElement
424
425  public        Vector        importTypes  = new Vector ();
426  public        SymtabFactory factory;
427  public static int           typedefInfo;
428  public        Hashtable     list         = new Hashtable ();
429  public static Compile       compiler     = null;  // <d58591>
430} // class Compile
431