1 21 22 package org.armedbear.j; 23 24 public final class Position implements Constants 25 { 26 private Line line; 27 private int offset; 28 29 public Position(Position pos) 30 { 31 line = pos.line; 32 offset = pos.offset; 33 Debug.assertTrue(line != null); 34 } 35 36 public Position(Line line, int offset) 37 { 38 this.line = line; 39 this.offset = offset; 40 Debug.assertTrue(line != null); 41 } 42 43 public final Position copy() 44 { 45 return new Position(this); 46 } 47 48 public final Line getLine() 49 { 50 return line; 51 } 52 53 public final void setLine(Line line) 54 { 55 this.line = line; 56 } 57 58 public final int getOffset() 59 { 60 return offset; 61 } 62 63 public final void setOffset(int offset) 64 { 65 this.offset = offset; 66 } 67 68 public final int getLineLength() 69 { 70 return line.length(); 71 } 72 73 public final int lineNumber() 74 { 75 return line.lineNumber(); 76 } 77 78 public final Line getNextLine() 79 { 80 return line.next(); 81 } 82 83 public final Line getPreviousLine() 84 { 85 return line.previous(); 86 } 87 88 public final boolean equals(Object obj) 89 { 90 if (!(obj instanceof Position)) 91 return false; 92 Position pos = (Position) obj; 93 return (line == pos.line && offset == pos.offset); 94 } 95 96 public final boolean isBefore(Position pos) 97 { 98 if (line.lineNumber() < pos.line.lineNumber()) 99 return true; 100 101 if (line == pos.line) 102 if (offset < pos.offset) 103 return true; 104 105 return false; 106 } 107 108 public final boolean isAfter(Position pos) 109 { 110 if (line.lineNumber() > pos.line.lineNumber()) 111 return true; 112 113 if (line == pos.line) 114 if (offset > pos.offset) 115 return true; 116 117 return false; 118 } 119 120 public final void moveLeft() 121 { 122 if (offset > 0) 123 --offset; 124 } 125 126 public final void moveRight() 127 { 128 if (offset < line.length()) 129 ++offset; 130 } 131 132 public final void moveTo(Position pos) 133 { 134 line = pos.line; 135 offset = pos.offset; 136 Debug.assertTrue(line != null); 137 } 138 139 public final void moveTo(Line line, int offset) 140 { 141 this.line = line; 142 this.offset = offset; 143 Debug.assertTrue(line != null); 144 } 145 146 public void moveToCol(int goal, int tabWidth) 150 { 151 final int limit = line.length(); 152 int i, col; 153 for (i = 0, col = 0; i < limit && col < goal; i++) { 154 if (line.charAt(i) == '\t') 155 col += tabWidth - col % tabWidth; 156 else 157 ++col; 158 } 159 offset = i; 160 } 161 162 public final boolean lookingAt(String s) 163 { 164 return s.regionMatches(0, line.getText(), offset, s.length()); 165 } 166 167 public final boolean lookingAtIgnoreCase(String s) 168 { 169 return s.regionMatches(true, 0, line.getText(), offset, s.length()); 170 } 171 172 public boolean atStart() 173 { 174 if (line.previous() != null) 175 return false; 176 if (offset > 0) 177 return false; 178 return true; 179 } 180 181 public boolean atEnd() 182 { 183 if (line != null) { 184 if (offset < line.length()) 185 return false; 186 if (line.next() != null) 187 return false; 188 } 189 return true; 190 } 191 192 public boolean next() 193 { 194 if (offset < line.length()) { 195 ++offset; 196 return true; 197 } 198 if (line.next() != null) { 199 line = line.next(); 200 offset = 0; 201 return true; 202 } 203 return false; 204 } 205 206 public boolean prev() 207 { 208 if (offset > 0) { 209 --offset; 210 return true; 211 } 212 if (line.previous() != null) { 213 line = line.previous(); 214 offset = line.length(); 215 return true; 216 } 217 return false; 218 } 219 220 public boolean nextLine() 221 { 222 if (line.next() != null) { 223 line = line.next(); 224 offset = 0; 225 return true; 226 } 227 return false; 228 } 229 230 public final void skip() 232 { 233 ++offset; 234 } 235 236 public final void skip(int count) 238 { 239 offset += count; 240 } 241 242 public void skipWhitespace() 243 { 244 while (Character.isWhitespace(getChar()) && next()) 245 ; 246 } 247 248 public void skipWhitespaceOnCurrentLine() 249 { 250 int limit = line.length(); 251 while (offset < limit && Character.isWhitespace(line.charAt(offset))) 252 ++offset; 253 } 254 255 public void skipQuote() 257 { 258 char quoteChar = getChar(); 259 if (quoteChar == '\'' || quoteChar == '"') { 260 while (next()) { 261 char c = getChar(); 262 if (c == '\\') { 263 next(); 265 continue; 266 } 267 if (c == quoteChar) { 268 next(); 270 return; 271 } 272 } 273 } 274 } 275 276 public char getChar() 277 { 278 if (offset < 0 || offset > line.length()) { 279 Log.error("Position.getChar() offset = " + offset + 280 " line.length() = " + line.length()); 281 Debug.assertTrue(false); 282 } 283 if (offset == line.length()) 284 return EOL; 285 return line.charAt(offset); 286 } 287 288 public final String getString() 290 { 291 return line.substring(offset); 292 } 293 294 public String getIdentifier(Mode mode) 296 { 297 int begin = offset; 298 int end = offset; 299 final int limit = line.length(); 300 while (mode.isIdentifierPart(line.charAt(end))) { 301 ++end; 302 if (end == limit) 303 break; 304 } 305 return line.substring(begin, end); 306 } 307 308 public String toString() 309 { 310 FastStringBuffer sb = new FastStringBuffer("line "); 311 if (line != null) 312 sb.append(line.lineNumber() + 1); 313 else 314 sb.append("is null"); 315 sb.append(" col "); 316 sb.append(offset + 1); 317 return sb.toString(); 318 } 319 320 public final boolean isHidden() 321 { 322 return line.isHidden(); 323 } 324 325 public static int getDistance(Position a, Position b) 327 { 328 if (a == null || b == null) 329 return -1; 330 Debug.assertTrue(a.getLine() != null); 331 Debug.assertTrue(b.getLine() != null); 332 if (a.equals(b)) 333 return 0; 334 Position pos, end; 335 if (a.isBefore(b)) { 336 pos = a.copy(); 337 end = b.copy(); 338 } else { 339 pos = b.copy(); 340 end = a.copy(); 341 } 342 final Line endLine = end.getLine(); 343 int distance = 0; 344 while (pos.getLine() != endLine) { 345 distance += (pos.getLineLength() + 1 - pos.getOffset()); 346 Line nextLine = pos.getNextLine(); 347 if (nextLine == null) 348 return -1; 349 pos.moveTo(nextLine, 0); 350 } 351 Debug.assertTrue(pos.getLine() == endLine); 352 distance += end.getOffset() - pos.getOffset(); 353 return distance; 354 } 355 } 356 | Popular Tags |