/* * Copyright (c) 1999, 2004, 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; /** * This is the symbol table entry for interfaces. **/ public class InterfaceEntry extends SymtabEntry implements InterfaceType { protected InterfaceEntry () { super (); } // ctor protected InterfaceEntry (InterfaceEntry that) { super (that); _derivedFromNames = (Vector)that._derivedFromNames.clone (); _derivedFrom = (Vector)that._derivedFrom.clone (); _methods = (Vector)that._methods.clone (); _allMethods = (Vector)that._allMethods.clone (); forwardedDerivers = (Vector)that.forwardedDerivers.clone (); _contained = (Vector)that._contained.clone (); _interfaceType = that._interfaceType; } // ctor protected InterfaceEntry (SymtabEntry that, IDLID clone) { super (that, clone); if (module ().equals ("")) module (name ()); else if (!name ().equals ("")) module (module () + "/" + name ()); } // ctor public boolean isAbstract() { return _interfaceType == ABSTRACT ; } public boolean isLocal() { return _interfaceType == LOCAL ; } public boolean isLocalServant() { return _interfaceType == LOCALSERVANT ; } public boolean isLocalSignature() { return _interfaceType == LOCAL_SIGNATURE_ONLY ; } public Object clone () { return new InterfaceEntry (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) { interfaceGen.generate (symbolTable, this, stream); } // generate /** Access the interface generator. @return an object which implements the InterfaceGen interface. @see InterfaceGen */ public Generator generator () { return interfaceGen; } // generator /** Add an InterfaceEntry to the list of interfaces which this interface is derivedFrom. During parsing, the parameter to this method COULD be a ForwardEntry, but when parsing is complete, calling derivedFrom will return a vector which only contains InterfaceEntry's. */ public void addDerivedFrom (SymtabEntry derivedFrom) { _derivedFrom.addElement (derivedFrom); } // addDerivedFrom /** This method returns a vector of InterfaceEntry's. */ public Vector derivedFrom () { return _derivedFrom; } // derivedFrom /** Add to the list of derivedFrom names. */ public void addDerivedFromName (String name) { _derivedFromNames.addElement (name); } // addDerivedFromName /** This method returns a vector of Strings, each of which is a fully qualified name of an interface. This vector corresponds to the derivedFrom vector. The first element of this vector is the name of the first element of the derivedFrom vector, etc. */ public Vector derivedFromNames () { return _derivedFromNames; } // derivedFromNames /** Add a method/attribute to the list of methods. */ public void addMethod (MethodEntry method) { _methods.addElement (method); } // addMethod /** This is a vector of MethodEntry's. These are the methods and attributes contained within this Interface. */ public Vector methods () { return _methods; } // methods /** Add a symbol table entry to this interface's contained vector. */ public void addContained (SymtabEntry entry) { _contained.addElement (entry); } // addContained /** This is a vector of SymtabEntry's. Valid entries in this vector are: AttributeEntry, ConstEntry, EnumEntry, ExceptionEntry, MethodEntry, StructEntry, NativeEntry, TypedefEntry, UnionEntry. Note that the methods vector is a subset of this vector. */ public Vector contained () { return _contained; } // contained void methodsAddElement (MethodEntry method, Scanner scanner) { if (verifyMethod (method, scanner, false)) { addMethod (method); _allMethods.addElement (method); // Add this method to the 'allMethods' list of any interfaces // which may have inherited this one when it was a forward // reference. addToForwardedAllMethods (method, scanner); } } // methodsAddElement void addToForwardedAllMethods (MethodEntry method, Scanner scanner) { Enumeration e = forwardedDerivers.elements (); while (e.hasMoreElements ()) { InterfaceEntry derived = (InterfaceEntry)e.nextElement (); if (derived.verifyMethod (method, scanner, true)) derived._allMethods.addElement (method); } } // addToForwardedAllMethods // Make sure a method by this name doesn't exist in this class or // in this class's parents private boolean verifyMethod (MethodEntry method, Scanner scanner, boolean clash) { boolean unique = true; String lcName = method.name ().toLowerCase (); Enumeration e = _allMethods.elements (); while (e.hasMoreElements ()) { MethodEntry emethod = (MethodEntry)e.nextElement (); // Make sure the method doesn't exist either in its // original name or in all lower case. In IDL, identifiers // which differ only in case are collisions. String lceName = emethod.name ().toLowerCase (); if (method != emethod && lcName.equals (lceName)) { if (clash) ParseException.methodClash (scanner, fullName (), method.name ()); else ParseException.alreadyDeclared (scanner, method.name ()); unique = false; break; } } return unique; } // verifyMethod void derivedFromAddElement (SymtabEntry e, Scanner scanner) { addDerivedFrom (e); addDerivedFromName (e.fullName ()); addParentType( e, scanner ); } // derivedFromAddElement void addParentType (SymtabEntry e, Scanner scanner) { if (e instanceof ForwardEntry) addToDerivers ((ForwardEntry)e); else { // e instanceof InterfaceEntry InterfaceEntry derivedFrom = (InterfaceEntry)e; // Compare all of the parent's methods to the methods on this // interface, looking for name clashes: for ( Enumeration enumeration = derivedFrom._allMethods.elements (); enumeration.hasMoreElements (); ) { MethodEntry method = (MethodEntry)enumeration.nextElement (); if ( verifyMethod (method, scanner, true)) _allMethods.addElement (method); // Add this method to the 'allMethods' list of any interfaces // which may have inherited this one when it was a forward // reference: addToForwardedAllMethods (method, scanner); } // If any of the parent's parents are forward entries, make // sure this interface gets added to their derivers list so // that when the forward entry is defined, the 'allMethods' // list of this interface can be updated. lookForForwardEntrys (scanner, derivedFrom); } } // addParentType private void lookForForwardEntrys (Scanner scanner, InterfaceEntry entry) { Enumeration parents = entry.derivedFrom ().elements (); while (parents.hasMoreElements ()) { SymtabEntry parent = (SymtabEntry)parents.nextElement (); if (parent instanceof ForwardEntry) addToDerivers ((ForwardEntry)parent); else if (parent == entry) ParseException.selfInherit (scanner, entry.fullName ()); else // it must be an InterfaceEntry lookForForwardEntrys (scanner, (InterfaceEntry)parent); } } // lookForForwardEntrys public boolean replaceForwardDecl (ForwardEntry oldEntry, InterfaceEntry newEntry) { int index = _derivedFrom.indexOf( oldEntry ); if ( index >= 0 ) _derivedFrom.setElementAt( newEntry, index ); return (index >= 0); } // replaceForwardDecl private void addToDerivers (ForwardEntry forward) { // Add this interface to the derivers list on the forward entry // so that when the forward entry is defined, the 'allMethods' // list of this interface can be updated. forward.derivers.addElement (this); Enumeration e = forwardedDerivers.elements (); while (e.hasMoreElements ()) forward.derivers.addElement ((InterfaceEntry)e.nextElement ()); } // addToDerivers /** This method returns a vector of the elements in the state block. If it is null, this is not a stateful interface. If it is non-null, but of zero length, then it is still stateful; it has no state entries itself, but it has an ancestor which does. */ public Vector state () { return _state; } // state public void initState () { _state = new Vector (); } // initState public void addStateElement (InterfaceState state, Scanner scanner) { if (_state == null) _state = new Vector (); String name = state.entry.name (); for (Enumeration e = _state.elements (); e.hasMoreElements ();) if (name.equals (((InterfaceState) e.nextElement ()).entry.name ())) ParseException.duplicateState (scanner, name); _state.addElement (state); } // state public int getInterfaceType () { return _interfaceType; } public void setInterfaceType (int type) { _interfaceType = type; } /** Get the allMethods vector. */ public Vector allMethods () { return _allMethods; } private Vector _derivedFromNames = new Vector(); private Vector _derivedFrom = new Vector(); private Vector _methods = new Vector(); Vector _allMethods = new Vector(); Vector forwardedDerivers = new Vector(); private Vector _contained = new Vector(); private Vector _state = null; private int _interfaceType = NORMAL; static InterfaceGen interfaceGen; } // class InterfaceEntry