TypedefGen.java revision 608:7e06bf1dcb09
1/*
2 * Copyright (c) 1999, 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// -11aug1997<daz> No modification: comments for type_defs will appear in
40//  helper, holder classes as a result of modifications to routines
41//  makeHelper(), makeHolder() in class com.sun.tools.corba.se.idl.toJava.Util.
42// -F46082.51<daz> Remove -stateful feature; javaStatefulName() obsolete.
43// -D61056   <klr> Use Util.helperName
44
45import java.io.PrintWriter;
46
47import java.util.Enumeration;
48import java.util.Hashtable;
49
50import com.sun.tools.corba.se.idl.InterfaceEntry;
51import com.sun.tools.corba.se.idl.InterfaceState;
52import com.sun.tools.corba.se.idl.PrimitiveEntry;
53import com.sun.tools.corba.se.idl.SequenceEntry;
54import com.sun.tools.corba.se.idl.StringEntry;
55import com.sun.tools.corba.se.idl.StructEntry;
56import com.sun.tools.corba.se.idl.SymtabEntry;
57import com.sun.tools.corba.se.idl.TypedefEntry;
58import com.sun.tools.corba.se.idl.UnionEntry;
59
60import com.sun.tools.corba.se.idl.constExpr.Expression;
61
62// Notes:
63
64/**
65 *
66 **/
67public class TypedefGen implements com.sun.tools.corba.se.idl.TypedefGen, JavaGenerator
68{
69  /**
70   * Public zero-argument constructor.
71   **/
72  public TypedefGen ()
73  {
74  } // ctor
75
76  /**
77   *
78   **/
79  public void generate (Hashtable symbolTable, TypedefEntry t, PrintWriter stream)
80  {
81    this.symbolTable = symbolTable;
82    this.t           = t;
83
84    if (t.arrayInfo ().size () > 0 || t.type () instanceof SequenceEntry)
85      generateHolder ();
86    generateHelper ();
87  } // generator
88
89  /**
90   *
91   **/
92  protected void generateHolder ()
93  {
94    ((Factories)Compile.compiler.factories ()).holder ().generate (symbolTable, t);
95  }
96
97  /**
98   *
99   **/
100  protected void generateHelper ()
101  {
102    ((Factories)Compile.compiler.factories ()).helper ().generate (symbolTable, t);
103  }
104
105  ///////////////
106  // From JavaGenerator
107
108  private boolean inStruct (TypedefEntry entry)
109  {
110    boolean inStruct = false;
111    if (entry.container () instanceof StructEntry || entry.container () instanceof UnionEntry)
112      inStruct = true;
113    else if (entry.container () instanceof InterfaceEntry)
114    {
115      InterfaceEntry i = (InterfaceEntry)entry.container ();
116      if (i.state () != null)
117      {
118        Enumeration e = i.state ().elements ();
119        while (e.hasMoreElements ())
120          if (((InterfaceState)e.nextElement ()).entry == entry)
121          {
122            inStruct = true;
123            break;
124          }
125      }
126    }
127    return inStruct;
128  } // inStruct
129
130  public int helperType (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
131  {
132    TypedefEntry td = (TypedefEntry)entry;
133    boolean inStruct = inStruct (td);
134    if (inStruct)
135      tcoffsets.setMember (entry);
136    else
137      tcoffsets.set (entry);
138
139    // Print the base types typecode
140    index = ((JavaGenerator)td.type ().generator ()).type (index, indent, tcoffsets, name, td.type (), stream);
141
142    if (inStruct && td.arrayInfo ().size () != 0)
143      tcoffsets.bumpCurrentOffset (4); // for array length field
144
145    // Print the array typecodes (if there are any)
146    int dimensions = td.arrayInfo ().size ();
147    for (int i = 0; i < dimensions; ++i)
148    {
149      String size = Util.parseExpression ((Expression)td.arrayInfo ().elementAt (i));
150      stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_array_tc (" + size + ", " + name + " );");
151    }
152
153    // If this typedef describes a struct/union member, don't put it
154    // in an alias typedef; otherwise that's where it belongs.
155    if (!inStruct)
156      // <54697>
157      //stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_alias_tc (id (), \"" + Util.stripLeadingUnderscores (td.name ()) + "\", " + name + ");");
158      stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_alias_tc (" + Util.helperName (td, true) + ".id (), \"" + Util.stripLeadingUnderscores (td.name ()) + "\", " + name + ");"); // <d61056>
159
160    return index;
161  } // helperType
162
163  public int type (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
164  {
165    // The type() method is invoked from other emitters instead of when an IDL
166    // typedef statement is being processed.  Code generated is identical minus the
167    // generation of a create_alias_tc() which is required for IDL typedef's but not
168    // needed when typedef is being processed as a member of struct/union/valuetype.
169
170    return helperType( index, indent, tcoffsets, name, entry, stream);
171  } // type
172
173  public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream)
174  {
175    Util.writeInitializer ("    ", "value", "", entry, stream);
176    read (0, "    ", "value", entry, stream);
177    stream.println ("    return value;");
178  } // helperRead
179
180  public void helperWrite (SymtabEntry entry, PrintWriter stream)
181  {
182    write (0, "    ", "value", entry, stream);
183  } // helperWrite
184
185  public int read (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
186  {
187    TypedefEntry td = (TypedefEntry)entry;
188    String modifier = Util.arrayInfo (td.arrayInfo ());
189    if (!modifier.equals (""))
190    {
191      // arrayInfo is a vector of Expressions which indicate the
192      // number of array dimensions for this typedef.  But what if
193      // this is a typedef of a sequence?
194      // The `new' statement being generated must know the full
195      // number of brackets.  That can be found in td.info.
196      // For instance:
197      // typedef sequence<short> A[10][10];
198      // void proc (out A a);
199      // typeModifier = "[10][10]"
200      // td.info    = "short[][][]";
201      // The first new statement generated is:
202      // a.value = new short[10][][];
203      // Note that the 3 sets of brackets come from td.info, not
204      // arrayInfo;
205      // The second new statement generated is:
206      // a.value[_i1] = new short[10][];
207      // ------------     ---- ------
208      //    \           \    \
209      //    name      baseName   arrayDcl
210      int closingBrackets = 0;
211      String loopIndex = "";
212      String baseName;
213      try
214      {
215        baseName = (String)td.dynamicVariable (Compile.typedefInfo);
216      }
217      catch (NoSuchFieldException e)
218      {
219        baseName = td.name ();
220      }
221      int startArray = baseName.indexOf ('[');
222      String arrayDcl = Util.sansArrayInfo (baseName.substring (startArray)) + "[]"; // Add an extra set because the first gets stripped off in the loop.
223      baseName = baseName.substring (0, startArray);
224
225      // For interfaces having state, e.g., valuetypes.
226      SymtabEntry baseEntry = (SymtabEntry)Util.symbolTable.get (baseName.replace ('.', '/'));
227      if (baseEntry instanceof InterfaceEntry && ((InterfaceEntry)baseEntry).state () != null)
228        // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete.
229        //baseName = Util.javaStatefulName ((InterfaceEntry)baseEntry);
230        baseName = Util.javaName ((InterfaceEntry)baseEntry);
231
232      int end1stArray;
233      while (!modifier.equals (""))
234      {
235        int rbracket = modifier.indexOf (']');
236        String size = modifier.substring (1, rbracket);
237        end1stArray = arrayDcl.indexOf (']');
238        arrayDcl = '[' + size + arrayDcl.substring (end1stArray + 2);
239        stream.println (indent + name + " = new " + baseName + arrayDcl + ';');
240        loopIndex = "_o" + index++;
241        stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < (" + size + "); ++" + loopIndex + ')');
242        stream.println (indent + '{');
243        ++closingBrackets;
244        modifier = modifier.substring (rbracket + 1);
245        indent = indent + "  ";
246        name = name + '[' + loopIndex + ']';
247      }
248      end1stArray = arrayDcl.indexOf (']');
249      if (td.type () instanceof SequenceEntry || td.type () instanceof PrimitiveEntry || td.type () instanceof StringEntry)
250        index = ((JavaGenerator)td.type ().generator ()).read (index, indent, name, td.type (), stream);
251      else if (td.type () instanceof InterfaceEntry && td.type ().fullName ().equals ("org/omg/CORBA/Object"))
252        stream.println (indent + name + " = istream.read_Object ();");
253      else
254        stream.println (indent + name + " = " + Util.helperName (td.type (), true) + ".read (istream);"); // <d61056>
255      for (int i = 0; i < closingBrackets; ++i)
256      {
257        indent = indent.substring (2);
258        stream.println (indent + '}');
259      }
260    }
261    else
262    {
263      SymtabEntry tdtype = Util.typeOf (td.type ());
264      if (tdtype instanceof SequenceEntry || tdtype instanceof PrimitiveEntry || tdtype instanceof StringEntry)
265        index = ((JavaGenerator)tdtype.generator ()).read (index, indent, name, tdtype, stream);
266      else if (tdtype instanceof InterfaceEntry && tdtype.fullName ().equals ("org/omg/CORBA/Object"))
267        stream.println (indent + name + " = istream.read_Object ();");
268      else
269        stream.println (indent + name + " = " + Util.helperName (tdtype, true) + ".read (istream);"); // <d61056>
270    }
271    return index;
272  } // read
273
274  public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
275  {
276    TypedefEntry td = (TypedefEntry)entry;
277    String modifier = Util.arrayInfo (td.arrayInfo ());
278    if (!modifier.equals (""))
279    {
280      int closingBrackets = 0;
281      String loopIndex = "";
282      while (!modifier.equals (""))
283      {
284        int rbracket = modifier.indexOf (']');
285        String size = modifier.substring (1, rbracket);
286        stream.println (indent + "if (" + name + ".length != (" + size + "))");
287        stream.println (indent + "  throw new org.omg.CORBA.MARSHAL (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);");
288        loopIndex = "_i" + index++;
289        stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < (" + size + "); ++" + loopIndex + ')');
290        stream.println (indent + '{');
291        ++closingBrackets;
292        modifier = modifier.substring (rbracket + 1);
293        indent = indent + "  ";
294        name = name + '[' + loopIndex + ']';
295      }
296      if (td.type () instanceof SequenceEntry || td.type () instanceof PrimitiveEntry || td.type () instanceof StringEntry)
297        index = ((JavaGenerator)td.type ().generator ()).write (index, indent, name, td.type (), stream);
298      else if (td.type () instanceof InterfaceEntry && td.type ().fullName ().equals ("org/omg/CORBA/Object"))
299        stream.println (indent + "ostream.write_Object (" + name + ");");
300      else
301        stream.println (indent + Util.helperName (td.type (), true) + ".write (ostream, " + name + ");"); // <d61056>
302      for (int i = 0; i < closingBrackets; ++i)
303      {
304        indent = indent.substring (2);
305        stream.println (indent + '}');
306      }
307    }
308    else
309    {
310      SymtabEntry tdtype = Util.typeOf (td.type ());
311      if (tdtype instanceof SequenceEntry || tdtype instanceof PrimitiveEntry || tdtype instanceof StringEntry)
312        index = ((JavaGenerator)tdtype.generator ()).write (index, indent, name, tdtype, stream);
313      else if (tdtype instanceof InterfaceEntry && tdtype.fullName ().equals ("org/omg/CORBA/Object"))
314        stream.println (indent + "ostream.write_Object (" + name + ");");
315      else
316        stream.println (indent + Util.helperName (tdtype, true) + ".write (ostream, " + name + ");"); // <d61056>
317    }
318    return index;
319  } // write
320
321  // From JavaGenerator
322  ////////////////
323
324  protected Hashtable     symbolTable = null;
325  protected TypedefEntry  t           = null;
326} // class TypedefGen
327