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    }