blob: 2d92a9bdbbd8f421cf8e49cf7b0e110086a55f70 [file] [log] [blame]
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* COMPONENT_NAME: idl.parser
*
* ORIGINS: 27
*
* Licensed Materials - Property of IBM
* 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
* RMI-IIOP v1.0
*
*/
package com.sun.tools.corba.se.idl;
// NOTES:
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import com.sun.tools.corba.se.idl.constExpr.Expression;
//<daz> import com.sun.tools.corba.se.idl.som.idlemit.TypeCode;
/**
* This is the symbol table entry for values.
**/
public class ValueEntry extends InterfaceEntry
{
protected ValueEntry ()
{
super ();
} // ctor
protected ValueEntry (ValueEntry that)
{
super (that);
_supportsNames = (Vector)that._supportsNames.clone ();
_supports = (Vector)that._supports.clone ();
_initializers = (Vector)that._initializers.clone ();
_custom = that._custom;
_isSafe = that._isSafe;
} // ctor
protected ValueEntry (SymtabEntry that, IDLID clone)
{
super (that, clone);
} // ctor
public Object clone ()
{
return new ValueEntry (this);
} // clone
/** Invoke the interface generator.
@param symbolTable The symbol table is a hash table whose key is
a fully qualified type name and whose value is a SymtabEntry or
a subclass of SymtabEntry.
@param stream The stream to which the generator should sent its output.
@see SymtabEntry */
public void generate (Hashtable symbolTable, PrintWriter stream)
{
valueGen.generate (symbolTable, this, stream);
} // generate
/** Access the value generator.
@returns an object which implements the ValueGen interface.
@see ValueGen */
public Generator generator ()
{
return valueGen;
} // generator
/** Add an InterfaceEntry to the list of interfaces which this value
supports. During parsing, the parameter to this method COULD be a
ForwardEntry, but when parsing is complete, calling supports will
return a vector which only contains InterfaceEntry's. */
public void addSupport (SymtabEntry supports)
{
_supports.addElement (supports);
} // addSupport
/** This method returns a vector of InterfaceEntry's. */
public Vector supports ()
{
return _supports;
} // supports
/** Add to the list of support names. */
public void addSupportName (String name)
{
_supportsNames.addElement (name);
} // addSupportName
/** This method returns a vector of Strings, each of which is a fully
qualified name of an interface. This vector corresponds to the
supports vector. The first element of this vector is the name of
the first element of the supports vector, etc. */
public Vector supportsNames ()
{
return _supportsNames;
} // supportsNames
/** Add a parent value type to the list of parent types for the value.
This method:
<UL>
<LI> Allows only the first added class to be concrete if the receiver is
concrete.
<LI> Does not allow any added classes to be concrete if the receiver is
abstract.
<LI> Does not allow duplicate classes to be added.
</UL> */
void derivedFromAddElement (SymtabEntry e, boolean isSafe, Scanner scanner)
{
if (((InterfaceType)e).getInterfaceType() != InterfaceType.ABSTRACT) {
if (isAbstract ())
ParseException.nonAbstractParent2 (scanner, fullName (), e.fullName ());
else if (derivedFrom ().size () > 0)
ParseException.nonAbstractParent3 (scanner, fullName (), e.fullName ());
}
if (derivedFrom ().contains (e))
ParseException.alreadyDerived (scanner, e.fullName (), fullName ());
if (isSafe)
_isSafe = true;
addDerivedFrom (e);
addDerivedFromName (e.fullName ());
addParentType (e, scanner);
} // derivedFromAddElement
void derivedFromAddElement (SymtabEntry e, Scanner scanner)
{
// This code must check for duplicate interfaces being supported...
addSupport (e);
addSupportName (e.fullName ());
addParentType (e, scanner);
} // derivedFromAddElement
public boolean replaceForwardDecl (ForwardEntry oldEntry, InterfaceEntry newEntry)
{
if (super.replaceForwardDecl (oldEntry, newEntry))
return true;
int index = _supports.indexOf (oldEntry);
if ( index >= 0)
_supports.setElementAt (newEntry, index);
return (index >= 0);
}
void initializersAddElement (MethodEntry method, Scanner scanner)
{
// Check to see if the parameter signature is a duplicate:
Vector params = method.parameters ();
int args = params.size ();
for (Enumeration e = _initializers.elements (); e.hasMoreElements ();)
{
Vector params2 = ( (MethodEntry) e.nextElement ()).parameters ();
if (args == params2.size ())
{
int i = 0;
for (; i < args; i++)
if (!((ParameterEntry)params.elementAt (i)).type ().equals (
((ParameterEntry)params2.elementAt (i)).type ()))
break;
if (i >= args)
ParseException.duplicateInit (scanner);
}
}
_initializers.addElement (method);
} // initializersAddElement
public Vector initializers ()
{
return _initializers;
}
/** Tag all methods introduced by the value type as 'value methods' so
they can be differentiated in the emitters from any interface methods
that the value type supports. */
public void tagMethods ()
{
for (Enumeration e = methods ().elements (); e.hasMoreElements ();)
((MethodEntry)e.nextElement ()).valueMethod (true);
}
// <46082.03> Revert to "IDL:"-style (i.e., regular) repository ID.
/** Calculate the 'repository ID' for the value. This method should not be
called before the complete value type has been parsed, since it computes
the repository ID by computing hashcodes using all information contained
in the value type definition, not just the value type's fully qualified
name.*/
/*
public void calcRepId ()
{
ValueRepositoryId repId = new ValueRepositoryId ();
repId.addType (this);
calcRepId (repId);
String scopedName = fullName ();
// KLR - following switched to new format 8/26/98 per Simon's request
repositoryID (new RepositoryID ( "H:" + repId.getHashcode() + ":" + scopedName));
} // calcRepId
*/
/*
public void calcRepId (ValueRepositoryId repId)
{
Vector baseClasses = derivedFrom ();
if (baseClasses.size () >= 1)
((ValueEntry)baseClasses.elementAt (0)).calcRepId (repId);
Vector state = state ();
if (state != null)
for (Enumeration e = state.elements (); e.hasMoreElements ();)
calcTypedefType (((InterfaceState)e.nextElement ()).entry, repId);
} // calcRepId
private void calcValueType (ValueEntry entry, ValueRepositoryId repId)
{
if (repId.isNewType (entry))
{
//<daz> repId.addValue (TypeCode.tk_value);
repId.addValue (org.omg.CORBA.TCKind._tk_value);
entry.calcRepId (repId);
}
} // calcValueType
private void calcValueBoxType (ValueBoxEntry entry, ValueRepositoryId repId)
{
if (repId.isNewType (entry))
{
//<daz> repId.addValue (TypeCode.tk_value_box);
repId.addValue (org.omg.CORBA.TCKind._tk_value_box);
entry.calcRepId (repId);
}
} // calcValueBoxType
private void calcTypedefType (TypedefEntry entry, ValueRepositoryId repId)
{
if (repId.isNewType (entry))
{
Vector arrayInfo = entry.arrayInfo ();
if (arrayInfo.size () > 0)
{
//<daz> repId.addValue (TypeCode.tk_array);
repId.addValue (org.omg.CORBA.TCKind._tk_array);
for (Enumeration e = arrayInfo.elements (); e.hasMoreElements ();)
repId.addValue (((Number)((Expression)e.nextElement ()).value ()).intValue ());
}
calcType (entry.type (), repId);
}
} // calcTypedefType
private void calcType (SymtabEntry entry, ValueRepositoryId repId)
{
if (entry instanceof TypedefEntry)
calcTypedefType ((TypedefEntry)entry, repId);
else if (entry instanceof PrimitiveEntry)
calcPrimitiveType (entry, repId);
else if (entry instanceof InterfaceEntry)
//<daz> repId.addValue (TypeCode._tk_objref);
repId.addValue (org.omg.CORBA.TCKind._tk_objref);
else if (entry instanceof EnumEntry)
//<daz> repId.addValue (TypeCode._tk_enum);
repId.addValue (org.omg.CORBA.TCKind._tk_enum);
else if (entry instanceof StringEntry)
calcStringType ( (StringEntry) entry, repId);
else if (entry instanceof SequenceEntry)
calcSequenceType ( (SequenceEntry) entry, repId);
else if (entry instanceof StructEntry)
calcStructType ( (StructEntry) entry, repId);
else if (entry instanceof UnionEntry)
calcUnionType ( (UnionEntry) entry, repId);
else if (entry instanceof ValueBoxEntry)
calcValueBoxType ( (ValueBoxEntry) entry, repId);
else if (entry instanceof ValueEntry)
calcValueType ( (ValueEntry) entry, repId);
} // calcType
private static Hashtable primTypes;
private void calcPrimitiveType (SymtabEntry entry, ValueRepositoryId repId)
{
if (primTypes == null)
{
primTypes = new Hashtable ();
//<daz> primTypes.put ("short", new Integer (TypeCode.tk_short ));
primTypes.put ("short", new Integer (org.omg.CORBA.TCKind._tk_short ));
//<daz> primTypes.put ("long", new Integer (TypeCode.tk_long ));
primTypes.put ("long", new Integer (org.omg.CORBA.TCKind._tk_long ));
//<daz> primTypes.put ("unsigned short", new Integer (TypeCode.tk_ushort ));
primTypes.put ("unsigned short", new Integer (org.omg.CORBA.TCKind._tk_ushort ));
//<daz> primTypes.put ("unsigned long", new Integer (TypeCode.tk_ulong ));
primTypes.put ("unsigned long", new Integer (org.omg.CORBA.TCKind._tk_ulong ));
//<daz> primTypes.put ("char", new Integer (TypeCode.tk_char ));
primTypes.put ("char", new Integer (org.omg.CORBA.TCKind._tk_char ));
//<daz> primTypes.put ("wchar", new Integer (TypeCode.tk_wchar ));
primTypes.put ("wchar", new Integer (org.omg.CORBA.TCKind._tk_wchar ));
//<daz> primTypes.put ("float", new Integer (TypeCode.tk_float ));
primTypes.put ("float", new Integer (org.omg.CORBA.TCKind._tk_float ));
//<daz> primTypes.put ("double", new Integer (TypeCode.tk_double ));
primTypes.put ("double", new Integer (org.omg.CORBA.TCKind._tk_double ));
//<daz> primTypes.put ("boolean", new Integer (TypeCode.tk_boolean));
primTypes.put ("boolean", new Integer (org.omg.CORBA.TCKind._tk_boolean));
//<daz> primTypes.put ("octet", new Integer (TypeCode.tk_octet ));
primTypes.put ("octet", new Integer (org.omg.CORBA.TCKind._tk_octet ));
//<daz> primTypes.put ("any", new Integer (TypeCode.tk_any )); }
primTypes.put ("any", new Integer (org.omg.CORBA.TCKind._tk_any ));
}
repId.addValue (((Integer)primTypes.get (entry.name ())).intValue ());
} // calcPrimitiveType
private void calcStringType (StringEntry entry, ValueRepositoryId repId)
{
repId.addValue (entry.name ().equals (Parser.overrideName ("string")) ?
//<daz> TypeCode.tk_string:
org.omg.CORBA.TCKind._tk_string :
//<daz> TypeCode.tk_wstring);
org.omg.CORBA.TCKind._tk_wstring);
if (entry.maxSize () != null)
try
{
repId.addValue ( ( (Number) (entry.maxSize ()).value ()). intValue ());
}
catch (Exception exception)
{}
} // calcStringType
private void calcSequenceType (SequenceEntry entry, ValueRepositoryId repId)
{
//<daz> repId.addValue (TypeCode.tk_sequence);
repId.addValue (org.omg.CORBA.TCKind._tk_sequence);
if (entry.maxSize () != null)
try
{
repId.addValue (((Number)(entry.maxSize ()).value ()).intValue ());
}
catch (Exception exception)
{}
} // calcSequenceType
private void calcStructType (StructEntry entry, ValueRepositoryId repId)
{
if (repId.isNewType (entry))
{
//<daz> repId.addValue (TypeCode.tk_struct);
repId.addValue (org.omg.CORBA.TCKind._tk_struct);
for (Enumeration e = entry.members ().elements (); e.hasMoreElements ();)
calcTypedefType ( (TypedefEntry) e.nextElement (), repId);
}
} // calcStructType
private void calcUnionType (UnionEntry entry, ValueRepositoryId repId)
{
if (repId.isNewType (entry))
{
//<daz> repId.addValue (TypeCode.tk_union);
repId.addValue (org.omg.CORBA.TCKind._tk_union);
calcType (entry.type (), repId);
for (Enumeration e = entry.branches ().elements (); e.hasMoreElements ();)
calcTypedefType ( ( (UnionBranch) e.nextElement ()).typedef, repId);
}
} // calcUnionType
*/
/** Get the 'custom' marshaling property. */
public boolean isCustom ()
{
return _custom;
}
/** Set the 'custom' marshaling property. */
public void setCustom (boolean isCustom)
{
_custom = isCustom;
}
/** Return whether or not the value type can be "safely" truncated to
its concrete parent type. */
public boolean isSafe ()
{
return _isSafe;
}
private Vector _supportsNames = new Vector ();
private Vector _supports = new Vector ();
private Vector _initializers = new Vector ();
private boolean _custom = false;
private boolean _isSafe = false;
static ValueGen valueGen;
} // class ValueEntry