    001    /* Copyright 2000, 2001, Compaq Computer Corporation */
    002
    003    package javafe.ast;
    004    //@ model import javafe.parser.TagConstants;
    005
    006    /** <CODE>_SpecialParserInterface</CODE> is not a class that should be
    007    used by general clients of the <CODE>javafe.ast</CODE> package.  It
    008    holds a number of routines and constants used by the
    009    <CODE>javafe.parser</CODE> package that we want to hide from other,
    010    more general clients of <CODE>javafe.ast</CODE>.
    011
    012    <CODE>_SpecialParserInterface</CODE> serves two purposes:
    013
    014    <UL>
    015
    016    <LI> It defines two constants, <CODE>DUMMYLOC</CODE> and
    017    <CODE>IDENT</CODE> common to both packages, breaking what would
    018    otherwise be a mutual recursion between the two packages.  This lets
    019    <CODE>javafe.ast</CODE> be completely independent of
    020    <CODE>javafe.parser</CODE>.
    021
    022    <P> <LI> It defines a "friend" interface to the
    023    <CODE>Identifier</CODE> class, allowing the scanner to have a
    024    specialized interface to <CODE>Identifier</CODE> without exposing that
    025    interface to more general clients.
    026
    027    </UL>
    028
    029    <P> The "friend" interface to <CODE>Identifier</CODE> exposed by
    030    <CODE>_SpecialParserInterface</CODE> includes a extra integer field of
    031    <CODE>Identifier</CODE> objects used to hold token types.  For most
    032    instances of <CODE>Identifier</CODE>, this hidden field holds the
    033    value <CODE>IDENT</CODE>, the token code for identifiers.  However,
    034    for an <CODE>Identifier</CODE> object associated with a keyword, the
    035    hidden field holds the token type for the keyword.  During its
    036    initialization, the scanner class interns all keywords and uses the
    037    <CODE>_SpecialParserInterface.setTokenType</CODE> to write the
    038    appropriate token-type values into the hidden fields of the resulting
    039    <CODE>Identifier</CODE> objects.  Note that no synchronization is done
    040    by <CODE>_SpecialParserInterface</CODE> when reading and writing these
    041    fields.
    042
    043    */
    044
    045
    046    public abstract class _SpecialParserInterface {
    047
    048        /**
    049         * Return the hidden "token type" field of <CODE>id</CODE>.
    050         *
    051         * The token code will be one that does not require a
    052         * non-null auxVal (cf. Token.auxVal).
    053         */
    054        //@ ensures \result != TagConstants.BOOLEANLIT;
    055        //@ ensures \result != TagConstants.INTLIT;
    056        //@ ensures \result != TagConstants.LONGLIT;
    057        //@ ensures \result != TagConstants.FLOATLIT;
    058        //@ ensures \result != TagConstants.DOUBLELIT;
    059        //@ ensures \result != TagConstants.STRINGLIT;
    060        //@ ensures \result != TagConstants.CHARLIT;
    061        //@ ensures \result != TagConstants.LEXICALPRAGMA;
    062        //@ ensures \result != TagConstants.MODIFIERPRAGMA;
    063        //@ ensures \result != TagConstants.STMTPRAGMA;
    064        //@ ensures \result != TagConstants.TYPEDECLELEMPRAGMA;
    065        //@ ensures \result != TagConstants.TYPEMODIFIERPRAGMA;
    066        public static int getTokenType(/*@ non_null @*/ Identifier id) {
    067            return id.tokenType;
    068        }
    069
    070
    071        /**
    072         * Set the hidden "token type" field of <CODE>id</CODE>.
    073         *
    074         * The token code must be one that does not require a
    075         * non-null auxVal (cf. Token.auxVal).
    076         */
    077        //@ requires tokenType != TagConstants.BOOLEANLIT;
    078        //@ requires tokenType != TagConstants.INTLIT;
    079        //@ requires tokenType != TagConstants.LONGLIT;
    080        //@ requires tokenType != TagConstants.FLOATLIT;
    081        //@ requires tokenType != TagConstants.DOUBLELIT;
    082        //@ requires tokenType != TagConstants.STRINGLIT;
    083        //@ requires tokenType != TagConstants.CHARLIT;
    084        //@ requires tokenType != TagConstants.LEXICALPRAGMA;
    085        //@ requires tokenType != TagConstants.MODIFIERPRAGMA;
    086        //@ requires tokenType != TagConstants.STMTPRAGMA;
    087        //@ requires tokenType != TagConstants.TYPEDECLELEMPRAGMA;
    088        //@ requires tokenType != TagConstants.TYPEMODIFIERPRAGMA;
    089        public static void setTokenType(/*@ non_null @*/ Identifier id,
    090                                        int tokenType) {
    091            id.tokenType = tokenType;
    092        }
    093
    094
    095      /** Intern a sequence of characters with a pre-computed hashcode.
    096
    097        <BR> Requires: <CODE>hashcode = hash(text, textlen)</CODE>
    098
    099        <P> Ensures: returns the <CODE>Identifier</CODE> instance
    100        associated with the symbol consisting of the first
    101        <CODE>textlen</CODE> characters of <CODE>text</CODE>. */
    102
    103      //@ requires text != null;
    104      //@ requires 0 <= textlen && textlen <= text.length;
    105      //@ ensures \result != null;
    106      public static Identifier intern(char[] text, int textlen, int hashcode) {
    107        return Identifier.intern(text, textlen, hashcode);
    108      }
    109
    110      /** Constant used for hashing.  The hash function used to hash a
    111        <i>n</i>-character identifier <code>idn</code> is to sum
    112        <code>HC</code>^<i>(n-(i+1))</i><code>*idn[</code><i>i</i><code>]</code>.
    113        Note that this is the same hash function used by Java 1.1 for
    114        hashing <code>String</code> objects.  */
    115      public static final int HC = Identifier.HC;
    116
    117      /** Return the hash code used by <CODE>Identifier</CODE> for a given
    118        sequence of characters. */
    119
    120      //@ requires text != null;
    121      //@ requires 0 <= textlen && textlen < text.length;
    122      public static int hash(char[] text, int textlen)
    123      { return Identifier.hash(text, textlen); }
    124    }