001 /* Copyright 2000, 2001, Compaq Computer Corporation */ 002 003 /* IF THIS IS A JAVA FILE, DO NOT EDIT IT! 004 005 Most Java files in this directory which are part of the Javafe AST 006 are automatically generated using the astgen comment (see 007 ESCTools/Javafe/astgen) from the input file 'hierarchy.h'. If you 008 wish to modify AST classes or introduce new ones, modify 009 'hierarchy.j.' 010 */ 011 012 package javafe.ast; 013 014 import javafe.util.Assert; 015 import javafe.util.Location; 016 import javafe.util.ErrorSet; 017 018 // Convention: unless otherwise noted, integer fields named "loc" refer 019 // to the location of the first character of the syntactic unit 020 021 022 public class CompoundName extends Name 023 { 024 //@ invariant length>1; 025 026 //@ invariant ids != null; 027 //@ invariant ids.count == length; 028 public /*@ non_null @*/ IdentifierVec ids; 029 030 031 //@ invariant locIds.length == length; 032 /*@ invariant (\forall int i; (0 <= i && i<locIds.length) 033 ==> locIds[i] != Location.NULL); */ 034 public /*@ non_null @*/ int[] locIds; 035 036 037 //@ invariant locDots.length == length-1; 038 /*@ invariant (\forall int i; (0 <= i && i<locDots.length) 039 ==> locDots[i] != Location.NULL); */ 040 public /*@ non_null @*/ int[] locDots; 041 042 043 /** Ensure there's at least two identifiers in this name. */ 044 private void postMake() { 045 Assert.notFalse(locIds.length > 1); 046 } 047 048 /** Check invariants on sizes. */ 049 private void postCheck() { 050 Assert.notFalse(ids.size() == locIds.length); 051 Assert.notFalse(locIds.length > 1); 052 Assert.notFalse(locIds.length == locDots.length+1); 053 } 054 055 /** 056 * @return a String representation of <code>this</code> in Java's 057 * syntax. 058 */ 059 public String printName() { 060 int sz = ids.size(); 061 StringBuffer result = new StringBuffer(10*sz); 062 for(int i = 0; i < sz; i++) { 063 if (i != 0) result.append('.'); 064 result.append(ids.elementAt(i).toString()); 065 } 066 return result.toString(); 067 } 068 069 /** Return true if <code>other</code> is a <code>Name</code> that 070 is component-wise equal to <code>this</code>. */ 071 072 public boolean equals(Object other) { 073 if (other instanceof CompoundName) { 074 Name o = (CompoundName)other; 075 int sz = this.ids.size(); 076 if (sz != o.size()) return false; 077 for(int i = 0; i < sz; i++) { 078 if (this.ids.elementAt(i) != o.identifierAt(i)) return false; 079 } 080 return true; 081 } else 082 return false; 083 } 084 085 /** Return a <code>Name</code> consisting of the first 086 <code>len</code> identifiers of <code>this</code>. Requires that 087 <code>len</code> is greater than zero and less than the length of 088 <code>this</code>. */ 089 090 public Name prefix(int len) { 091 Assert.precondition(len > 0 && len <= ids.size()); 092 if (len == 1) 093 return SimpleName.make(ids.elementAt(0), locIds[0]); 094 095 Identifier[] newIds = new Identifier[len]; 096 int[] newLocIds = new int[len]; 097 int[] newLocDots = new int[len-1]; 098 for(int i = 0; i < len; i++) newIds[i] = this.ids.elementAt(i); 099 System.arraycopy(locIds, 0, newLocIds, 0, len); 100 System.arraycopy(locDots, 0, newLocDots, 0, len-1); 101 return make(IdentifierVec.make(newIds), newLocIds, newLocDots); 102 } 103 104 /** Return a hash code for <code>this</code> such that two 105 <code>Name</code>s that are <code>equals</code> have the same hash 106 code. */ 107 108 public int hashCode() { 109 int result = 0; 110 for(int i = 0, sz = ids.size(); i < sz; i++) 111 result += ids.elementAt(i).hashCode(); 112 return result; 113 } 114 115 /** 116 * @return the first <code>len</code> identifiers in 117 * <code>this</code> in an array. Requires that <code>len</code> be 118 * between 0 and length of <code>this</code> inclusive. 119 */ 120 public String[] toStrings(int len) { 121 Assert.precondition(0 <= len && len <= ids.size()); 122 if (len == 0) return emptyStringArray; 123 String[] result = new String[len]; 124 for(int i = 0; i < len; i++) 125 result[i] = ids.elementAt(i).toString(); 126 return result; 127 } 128 129 /** Return the number of identifiers in <code>this</code>. */ 130 public int size() { return ids.size(); } 131 132 /** Return the ith identifier of <code>this</code>. */ 133 public Identifier identifierAt(int i) 134 /*throws ArrayIndexOutOfBoundsException*/ { 135 return ids.elementAt(i); 136 } 137 138 /** Return the location of the ith identifier of <code>this</code>. */ 139 public int locIdAt(int i) { return locIds[i]; } 140 141 /** Return the location of the dot after the ith identifier of 142 <code>this</code>. */ 143 public int locDotAfter(int i) { return locDots[i]; } 144 145 public int getStartLoc() { return locIds[0]; } 146 147 //@ requires ids.count>1; 148 //@ requires locIds.length == ids.count; 149 /*@ requires (\forall int i; (0 <= i && i<locIds.length) 150 ==> locIds[i] != Location.NULL); */ 151 //@ requires locDots.length == ids.count-1; 152 /*@ requires (\forall int i; (0 <= i && i<locDots.length) 153 ==> locDots[i] != Location.NULL); */ 154 // 155 //@ ensures \result != null; 156 public static CompoundName make(/*@ non_null @*/ IdentifierVec ids, 157 /*@ non_null @*/ int[] locIds, 158 /*@ non_null @*/ int[] locDots) { 159 //@ set I_will_establish_invariants_afterwards = true; 160 CompoundName result = new CompoundName(); 161 //@ set result.length = ids.count; 162 result.ids = ids; 163 result.locIds = locIds; 164 result.locDots = locDots; 165 result.postMake(); 166 return result; 167 } 168 169 170 // Generated boilerplate constructors: 171 172 /** 173 * Construct a raw CompoundName whose class invariant(s) have not 174 * yet been established. It is the caller's job to 175 * initialize the returned node's fields so that any 176 * class invariants hold. 177 */ 178 //@ requires I_will_establish_invariants_afterwards; 179 protected CompoundName() {} //@ nowarn Invariant,NonNullInit; 180 181 182 // Generated boilerplate methods: 183 184 public final int childCount() { 185 int sz = 0; 186 if (this.ids != null) sz += this.ids.size(); 187 return sz + 2; 188 } 189 190 public final Object childAt(int index) { 191 /*throws IndexOutOfBoundsException*/ 192 if (index < 0) 193 throw new IndexOutOfBoundsException("AST child index " + index); 194 int indexPre = index; 195 196 int sz; 197 198 sz = (this.ids == null ? 0 : this.ids.size()); 199 if (0 <= index && index < sz) 200 return this.ids.elementAt(index); 201 else index -= sz; 202 203 if (index == 0) return this.locIds; 204 else index--; 205 206 if (index == 0) return this.locDots; 207 else index--; 208 209 throw new IndexOutOfBoundsException("AST child index " + indexPre); 210 } //@ nowarn Exception; 211 212 public final String toString() { 213 return "[CompoundName" 214 + " ids = " + this.ids 215 + " locIds = " + this.locIds 216 + " locDots = " + this.locDots 217 + "]"; 218 } 219 220 public final int getTag() { 221 return TagConstants.COMPOUNDNAME; 222 } 223 224 public final void accept(Visitor v) { v.visitCompoundName(this); } 225 226 public final Object accept(VisitorArgResult v, Object o) {return v.visitCompoundName(this, o); } 227 228 public void check() { 229 super.check(); 230 if (this.ids == null) throw new RuntimeException(); 231 if (this.locIds == null) throw new RuntimeException(); 232 if (this.locDots == null) throw new RuntimeException(); 233 postCheck(); 234 } 235 236 }