    001    /* Copyright 2000, 2001, Compaq Computer Corporation */
    002
    003    package javafe.ast;
    004
    005    import javafe.util.Assert;
    006
    007
    008    /** Provides an extensible way to add 'fields' to the
    009    <code>ASTNode</code>.
    010
    011    Each <code>ASTDecoration</code> object essentially corresponds to an
    012    additional field in the <code>ASTNode</code> class. The value of this
    013    field for a particular <code>ASTNode</code> object is accessed and
    014    mutated via the instance methods <code>get</code> and
    015    <code>set</code>, respectively (see below). Each
    016    <code>ASTDecoration</code> object also has an associated
    017    <code>String</code>, which 'names' the corresponding field.
    018
    019    @see javafe.ast.ASTNode
    020    */
    021
    022    public class ASTDecoration {
    023
    024        /***************************************************
    025         *                                                 *
    026         * Class variables:                                *
    027         *                                                 *
    028         **************************************************/
    029
    030        //@ invariant allocated >= 0;
    031        //@ spec_public
    032        private static int allocated=0;
    033
    034        //@ invariant 0<=my_slot && my_slot<allocated;
    035        //@ spec_public
    036        private int my_slot;
    037
    038
    039        /***************************************************
    040         *                                                 *
    041         * Instance variables:                             *
    042         *                                                 *
    043         **************************************************/
    044
    045        /** The name of our decoration */
    046        //@ invariant name != null;
    047        //@ spec_public
    048        private String name;
    049
    050        /** Our decoration's actual "static" type */
    051        //@ ghost public \TYPE decorationType;
    052
    053
    054        /***************************************************
    055         *                                                 *
    056         * Creation:                                       *
    057         *                                                 *
    058         **************************************************/
    059
    060        /**
    061         * Creates a new <code>ASTDecoration</code> object with the given
    062         * name. <p>
    063         *
    064         * The caller should set the decorationType field of the result.<p>
    065         */
    066        //@ requires s != null;
    067        public ASTDecoration(String s) {
    068            name = s;
    069            my_slot = allocated;
    070            allocated++;
    071        }
    072
    073
    074        /***************************************************
    075         *                                                 *
    076         * Methods:                                        *
    077         *                                                 *
    078         **************************************************/
    079
    080       /**
    081        * Return the decoration value of an <code>ASTNode</code>, or <code> null
    082        * if the <code>ASTNode</code> has no decoration.
    083        */
    084        //@ requires n != null;
    085        //@ ensures \typeof(\result) <: decorationType;
    086        public Object get(ASTNode n) {
    087            Assert.notNull(n);
    088            Object[] v=n.decorations;
    089            if( v != null && my_slot < v.length )
    090                return v[my_slot];
    091            else
    092                return null;
    093        }    //@ nowarn Post;
    094
    095
    096        /**
    097         * Set the decoration value of an <code>ASTNode</code>.
    098         */
    099        //@ requires n != null;
    100        //@ requires \typeof(val) <: decorationType;
    101        public void set(ASTNode n, Object val) {
    102            Object[] v = n.decorations;
    103            if (v==null) {
    104                v = n.decorations = new Object[allocated];
    105            } else if (my_slot >= v.length) {
    106                Object[] _new = new Object[allocated];
    107                System.arraycopy( v, 0, _new, 0, v.length );
    108                v = n.decorations = _new;
    109            }
    110            v[my_slot] = val;
    111        }
    112
    113
    114        /**
    115         * Return the name associated with <code>this</code>.
    116         */
    117        public String toString() {
    118          return name;
    119        }
    120
    121        /**
    122         * Return a string  containing the decoration's name, and the
    123         * decoration value for this <code>ASTNode</code>.
    124         */
    125        //@ requires n != null;
    126        public String toString(ASTNode n) {
    127            Object val = get(n);
    128            return "[Decoration "+name+" "+ ( val==null? "" : val.toString() )
    129                    +"]";
    130        }
    131    }