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 }