src/share/classes/com/sun/tools/javac/jvm/CRTable.java

Mon, 14 Nov 2011 15:11:10 -0800

author
ksrini
date
Mon, 14 Nov 2011 15:11:10 -0800
changeset 1138
7375d4979bd3
parent 1127
ca49d50318dc
child 1280
5c0b3faeb0b0
permissions
-rw-r--r--

7106166: (javac) re-factor EndPos parser
Reviewed-by: jjg

duke@1 1 /*
jjg@816 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
ohair@554 7 * published by the Free Software Foundation. Oracle designates this
duke@1 8 * particular file as subject to the "Classpath" exception as provided
ohair@554 9 * by Oracle in the LICENSE file that accompanied this code.
duke@1 10 *
duke@1 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 15 * accompanied this code).
duke@1 16 *
duke@1 17 * You should have received a copy of the GNU General Public License version
duke@1 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 20 *
ohair@554 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554 22 * or visit www.oracle.com if you need additional information or have any
ohair@554 23 * questions.
duke@1 24 */
duke@1 25
duke@1 26 package com.sun.tools.javac.jvm;
duke@1 27
duke@1 28 import java.util.*;
duke@1 29
duke@1 30 import com.sun.tools.javac.tree.*;
duke@1 31 import com.sun.tools.javac.util.*;
duke@1 32 import com.sun.tools.javac.util.List;
duke@1 33 import com.sun.tools.javac.tree.JCTree.*;
ksrini@1138 34 import com.sun.tools.javac.parser.EndPosTable;
duke@1 35
duke@1 36 /** This class contains the CharacterRangeTable for some method
duke@1 37 * and the hashtable for mapping trees or lists of trees to their
duke@1 38 * ending positions.
duke@1 39 *
jjg@581 40 * <p><b>This is NOT part of any supported API.
jjg@581 41 * If you write code that depends on this, you do so at your own risk.
duke@1 42 * This code and its internal interfaces are subject to change or
duke@1 43 * deletion without notice.</b>
duke@1 44 */
duke@1 45 public class CRTable
duke@1 46 implements CRTFlags {
duke@1 47
duke@1 48 private final boolean crtDebug = false;
duke@1 49
duke@1 50 /** The list of CRTable entries.
duke@1 51 */
duke@1 52 private ListBuffer<CRTEntry> entries = new ListBuffer<CRTEntry>();
duke@1 53
duke@1 54 /** The hashtable for source positions.
duke@1 55 */
duke@1 56 private Map<Object,SourceRange> positions = new HashMap<Object,SourceRange>();
duke@1 57
ksrini@1138 58 /** The object for ending positions stored in the parser.
duke@1 59 */
ksrini@1138 60 private EndPosTable endPosTable;
duke@1 61
duke@1 62 /** The tree of the method this table is intended for.
duke@1 63 * We should traverse this tree to get source ranges.
duke@1 64 */
duke@1 65 JCTree.JCMethodDecl methodTree;
duke@1 66
duke@1 67 /** Constructor
duke@1 68 */
ksrini@1138 69 public CRTable(JCTree.JCMethodDecl tree, EndPosTable endPosTable) {
duke@1 70 this.methodTree = tree;
ksrini@1138 71 this.endPosTable = endPosTable;
duke@1 72 }
duke@1 73
duke@1 74 /** Create a new CRTEntry and add it to the entries.
duke@1 75 * @param tree The tree or the list of trees for which
duke@1 76 * we are storing the code pointers.
duke@1 77 * @param flags The set of flags designating type of the entry.
duke@1 78 * @param startPc The starting code position.
duke@1 79 * @param endPc The ending code position.
duke@1 80 */
duke@1 81 public void put(Object tree, int flags, int startPc, int endPc) {
duke@1 82 entries.append(new CRTEntry(tree, flags, startPc, endPc));
duke@1 83 }
duke@1 84
duke@1 85 /** Compute source positions and write CRT to the databuf.
duke@1 86 * @param databuf The buffer to write bytecodes to.
duke@1 87 */
duke@1 88 public int writeCRT(ByteBuffer databuf, Position.LineMap lineMap, Log log) {
duke@1 89
duke@1 90 int crtEntries = 0;
duke@1 91
duke@1 92 // compute source positions for the method
duke@1 93 new SourceComputer().csp(methodTree);
duke@1 94
duke@1 95 for (List<CRTEntry> l = entries.toList(); l.nonEmpty(); l = l.tail) {
duke@1 96
duke@1 97 CRTEntry entry = l.head;
duke@1 98
duke@1 99 // eliminate entries that do not produce bytecodes:
duke@1 100 // for example, empty blocks and statements
duke@1 101 if (entry.startPc == entry.endPc)
duke@1 102 continue;
duke@1 103
duke@1 104 SourceRange pos = positions.get(entry.tree);
jjg@816 105 Assert.checkNonNull(pos, "CRT: tree source positions are undefined");
duke@1 106 if ((pos.startPos == Position.NOPOS) || (pos.endPos == Position.NOPOS))
duke@1 107 continue;
duke@1 108
duke@1 109 if (crtDebug) {
duke@1 110 System.out.println("Tree: " + entry.tree + ", type:" + getTypes(entry.flags));
duke@1 111 System.out.print("Start: pos = " + pos.startPos + ", pc = " + entry.startPc);
duke@1 112 }
duke@1 113
duke@1 114 // encode startPos into line/column representation
duke@1 115 int startPos = encodePosition(pos.startPos, lineMap, log);
duke@1 116 if (startPos == Position.NOPOS)
duke@1 117 continue;
duke@1 118
duke@1 119 if (crtDebug) {
duke@1 120 System.out.print("End: pos = " + pos.endPos + ", pc = " + (entry.endPc - 1));
duke@1 121 }
duke@1 122
duke@1 123 // encode endPos into line/column representation
duke@1 124 int endPos = encodePosition(pos.endPos, lineMap, log);
duke@1 125 if (endPos == Position.NOPOS)
duke@1 126 continue;
duke@1 127
duke@1 128 // write attribute
duke@1 129 databuf.appendChar(entry.startPc);
duke@1 130 // 'endPc - 1' because endPc actually points to start of the next command
duke@1 131 databuf.appendChar(entry.endPc - 1);
duke@1 132 databuf.appendInt(startPos);
duke@1 133 databuf.appendInt(endPos);
duke@1 134 databuf.appendChar(entry.flags);
duke@1 135
duke@1 136 crtEntries++;
duke@1 137 }
duke@1 138
duke@1 139 return crtEntries;
duke@1 140 }
duke@1 141
duke@1 142 /** Return the number of the entries.
duke@1 143 */
duke@1 144 public int length() {
duke@1 145 return entries.length();
duke@1 146 }
duke@1 147
duke@1 148 /** Return string describing flags enabled.
duke@1 149 */
duke@1 150 private String getTypes(int flags) {
duke@1 151 String types = "";
duke@1 152 if ((flags & CRT_STATEMENT) != 0) types += " CRT_STATEMENT";
duke@1 153 if ((flags & CRT_BLOCK) != 0) types += " CRT_BLOCK";
duke@1 154 if ((flags & CRT_ASSIGNMENT) != 0) types += " CRT_ASSIGNMENT";
duke@1 155 if ((flags & CRT_FLOW_CONTROLLER) != 0) types += " CRT_FLOW_CONTROLLER";
duke@1 156 if ((flags & CRT_FLOW_TARGET) != 0) types += " CRT_FLOW_TARGET";
duke@1 157 if ((flags & CRT_INVOKE) != 0) types += " CRT_INVOKE";
duke@1 158 if ((flags & CRT_CREATE) != 0) types += " CRT_CREATE";
duke@1 159 if ((flags & CRT_BRANCH_TRUE) != 0) types += " CRT_BRANCH_TRUE";
duke@1 160 if ((flags & CRT_BRANCH_FALSE) != 0) types += " CRT_BRANCH_FALSE";
duke@1 161 return types;
duke@1 162 }
duke@1 163
duke@1 164 /** Source file positions in CRT are integers in the format:
duke@1 165 * line-number << LINESHIFT + column-number
duke@1 166 */
duke@1 167 private int encodePosition(int pos, Position.LineMap lineMap, Log log) {
duke@1 168 int line = lineMap.getLineNumber(pos);
duke@1 169 int col = lineMap.getColumnNumber(pos);
duke@1 170 int new_pos = Position.encodePosition(line, col);
duke@1 171 if (crtDebug) {
duke@1 172 System.out.println(", line = " + line + ", column = " + col +
duke@1 173 ", new_pos = " + new_pos);
duke@1 174 }
duke@1 175 if (new_pos == Position.NOPOS)
duke@1 176 log.warning(pos, "position.overflow", line);
duke@1 177
duke@1 178 return new_pos;
duke@1 179 }
duke@1 180
duke@1 181 /* ************************************************************************
duke@1 182 * Traversal methods
duke@1 183 *************************************************************************/
duke@1 184
duke@1 185 /**
duke@1 186 * This class contains methods to compute source positions for trees.
duke@1 187 * Extends Tree.Visitor to traverse the abstract syntax tree.
duke@1 188 */
duke@1 189 class SourceComputer extends JCTree.Visitor {
duke@1 190
duke@1 191 /** The result of the tree traversal methods.
duke@1 192 */
duke@1 193 SourceRange result;
duke@1 194
duke@1 195 /** Visitor method: compute source positions for a single node.
duke@1 196 */
duke@1 197 public SourceRange csp(JCTree tree) {
duke@1 198 if (tree == null) return null;
duke@1 199 tree.accept(this);
duke@1 200 if (result != null) {
duke@1 201 positions.put(tree, result);
duke@1 202 }
duke@1 203 return result;
duke@1 204 }
duke@1 205
duke@1 206 /** Visitor method: compute source positions for a list of nodes.
duke@1 207 */
duke@1 208 public SourceRange csp(List<? extends JCTree> trees) {
duke@1 209 if ((trees == null) || !(trees.nonEmpty())) return null;
duke@1 210 SourceRange list_sr = new SourceRange();
duke@1 211 for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail) {
duke@1 212 list_sr.mergeWith(csp(l.head));
duke@1 213 }
duke@1 214 positions.put(trees, list_sr);
duke@1 215 return list_sr;
duke@1 216 }
duke@1 217
duke@1 218 /** Visitor method: compute source positions for
duke@1 219 * a list of case blocks of switch statements.
duke@1 220 */
duke@1 221 public SourceRange cspCases(List<JCCase> trees) {
duke@1 222 if ((trees == null) || !(trees.nonEmpty())) return null;
duke@1 223 SourceRange list_sr = new SourceRange();
duke@1 224 for (List<JCCase> l = trees; l.nonEmpty(); l = l.tail) {
duke@1 225 list_sr.mergeWith(csp(l.head));
duke@1 226 }
duke@1 227 positions.put(trees, list_sr);
duke@1 228 return list_sr;
duke@1 229 }
duke@1 230
duke@1 231 /** Visitor method: compute source positions for
duke@1 232 * a list of catch clauses in try statements.
duke@1 233 */
duke@1 234 public SourceRange cspCatchers(List<JCCatch> trees) {
duke@1 235 if ((trees == null) || !(trees.nonEmpty())) return null;
duke@1 236 SourceRange list_sr = new SourceRange();
duke@1 237 for (List<JCCatch> l = trees; l.nonEmpty(); l = l.tail) {
duke@1 238 list_sr.mergeWith(csp(l.head));
duke@1 239 }
duke@1 240 positions.put(trees, list_sr);
duke@1 241 return list_sr;
duke@1 242 }
duke@1 243
duke@1 244 public void visitMethodDef(JCMethodDecl tree) {
duke@1 245 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 246 sr.mergeWith(csp(tree.body));
duke@1 247 result = sr;
duke@1 248 }
duke@1 249
duke@1 250 public void visitVarDef(JCVariableDecl tree) {
duke@1 251 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 252 csp(tree.vartype);
duke@1 253 sr.mergeWith(csp(tree.init));
duke@1 254 result = sr;
duke@1 255 }
duke@1 256
duke@1 257 public void visitSkip(JCSkip tree) {
duke@1 258 // endPos is the same as startPos for the empty statement
duke@1 259 SourceRange sr = new SourceRange(startPos(tree), startPos(tree));
duke@1 260 result = sr;
duke@1 261 }
duke@1 262
duke@1 263 public void visitBlock(JCBlock tree) {
duke@1 264 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 265 csp(tree.stats); // doesn't compare because block's ending position is defined
duke@1 266 result = sr;
duke@1 267 }
duke@1 268
duke@1 269 public void visitDoLoop(JCDoWhileLoop tree) {
duke@1 270 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 271 sr.mergeWith(csp(tree.body));
duke@1 272 sr.mergeWith(csp(tree.cond));
duke@1 273 result = sr;
duke@1 274 }
duke@1 275
duke@1 276 public void visitWhileLoop(JCWhileLoop tree) {
duke@1 277 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 278 sr.mergeWith(csp(tree.cond));
duke@1 279 sr.mergeWith(csp(tree.body));
duke@1 280 result = sr;
duke@1 281 }
duke@1 282
duke@1 283 public void visitForLoop(JCForLoop tree) {
duke@1 284 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 285 sr.mergeWith(csp(tree.init));
duke@1 286 sr.mergeWith(csp(tree.cond));
duke@1 287 sr.mergeWith(csp(tree.step));
duke@1 288 sr.mergeWith(csp(tree.body));
duke@1 289 result = sr;
duke@1 290 }
duke@1 291
duke@1 292 public void visitForeachLoop(JCEnhancedForLoop tree) {
duke@1 293 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 294 sr.mergeWith(csp(tree.var));
duke@1 295 sr.mergeWith(csp(tree.expr));
duke@1 296 sr.mergeWith(csp(tree.body));
duke@1 297 result = sr;
duke@1 298 }
duke@1 299
duke@1 300 public void visitLabelled(JCLabeledStatement tree) {
duke@1 301 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 302 sr.mergeWith(csp(tree.body));
duke@1 303 result = sr;
duke@1 304 }
duke@1 305
duke@1 306 public void visitSwitch(JCSwitch tree) {
duke@1 307 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 308 sr.mergeWith(csp(tree.selector));
duke@1 309 sr.mergeWith(cspCases(tree.cases));
duke@1 310 result = sr;
duke@1 311 }
duke@1 312
duke@1 313 public void visitCase(JCCase tree) {
duke@1 314 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 315 sr.mergeWith(csp(tree.pat));
duke@1 316 sr.mergeWith(csp(tree.stats));
duke@1 317 result = sr;
duke@1 318 }
duke@1 319
duke@1 320 public void visitSynchronized(JCSynchronized tree) {
duke@1 321 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 322 sr.mergeWith(csp(tree.lock));
duke@1 323 sr.mergeWith(csp(tree.body));
duke@1 324 result = sr;
duke@1 325 }
duke@1 326
duke@1 327 public void visitTry(JCTry tree) {
duke@1 328 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
darcy@609 329 sr.mergeWith(csp(tree.resources));
duke@1 330 sr.mergeWith(csp(tree.body));
duke@1 331 sr.mergeWith(cspCatchers(tree.catchers));
duke@1 332 sr.mergeWith(csp(tree.finalizer));
duke@1 333 result = sr;
duke@1 334 }
duke@1 335
duke@1 336 public void visitCatch(JCCatch tree) {
duke@1 337 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 338 sr.mergeWith(csp(tree.param));
duke@1 339 sr.mergeWith(csp(tree.body));
duke@1 340 result = sr;
duke@1 341 }
duke@1 342
duke@1 343 public void visitConditional(JCConditional tree) {
duke@1 344 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 345 sr.mergeWith(csp(tree.cond));
duke@1 346 sr.mergeWith(csp(tree.truepart));
duke@1 347 sr.mergeWith(csp(tree.falsepart));
duke@1 348 result = sr;
duke@1 349 }
duke@1 350
duke@1 351 public void visitIf(JCIf tree) {
duke@1 352 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 353 sr.mergeWith(csp(tree.cond));
duke@1 354 sr.mergeWith(csp(tree.thenpart));
duke@1 355 sr.mergeWith(csp(tree.elsepart));
duke@1 356 result = sr;
duke@1 357 }
duke@1 358
duke@1 359 public void visitExec(JCExpressionStatement tree) {
duke@1 360 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 361 sr.mergeWith(csp(tree.expr));
duke@1 362 result = sr;
duke@1 363 }
duke@1 364
duke@1 365 public void visitBreak(JCBreak tree) {
duke@1 366 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 367 result = sr;
duke@1 368 }
duke@1 369
duke@1 370 public void visitContinue(JCContinue tree) {
duke@1 371 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 372 result = sr;
duke@1 373 }
duke@1 374
duke@1 375 public void visitReturn(JCReturn tree) {
duke@1 376 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 377 sr.mergeWith(csp(tree.expr));
duke@1 378 result = sr;
duke@1 379 }
duke@1 380
duke@1 381 public void visitThrow(JCThrow tree) {
duke@1 382 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 383 sr.mergeWith(csp(tree.expr));
duke@1 384 result = sr;
duke@1 385 }
duke@1 386
duke@1 387 public void visitAssert(JCAssert tree) {
duke@1 388 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 389 sr.mergeWith(csp(tree.cond));
duke@1 390 sr.mergeWith(csp(tree.detail));
duke@1 391 result = sr;
duke@1 392 }
duke@1 393
duke@1 394 public void visitApply(JCMethodInvocation tree) {
duke@1 395 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 396 sr.mergeWith(csp(tree.meth));
duke@1 397 sr.mergeWith(csp(tree.args));
duke@1 398 result = sr;
duke@1 399 }
duke@1 400
duke@1 401 public void visitNewClass(JCNewClass tree) {
duke@1 402 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 403 sr.mergeWith(csp(tree.encl));
duke@1 404 sr.mergeWith(csp(tree.clazz));
duke@1 405 sr.mergeWith(csp(tree.args));
duke@1 406 sr.mergeWith(csp(tree.def));
duke@1 407 result = sr;
duke@1 408 }
duke@1 409
duke@1 410 public void visitNewArray(JCNewArray tree) {
duke@1 411 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 412 sr.mergeWith(csp(tree.elemtype));
duke@1 413 sr.mergeWith(csp(tree.dims));
duke@1 414 sr.mergeWith(csp(tree.elems));
duke@1 415 result = sr;
duke@1 416 }
duke@1 417
duke@1 418 public void visitParens(JCParens tree) {
duke@1 419 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 420 sr.mergeWith(csp(tree.expr));
duke@1 421 result = sr;
duke@1 422 }
duke@1 423
duke@1 424 public void visitAssign(JCAssign tree) {
duke@1 425 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 426 sr.mergeWith(csp(tree.lhs));
duke@1 427 sr.mergeWith(csp(tree.rhs));
duke@1 428 result = sr;
duke@1 429 }
duke@1 430
duke@1 431 public void visitAssignop(JCAssignOp tree) {
duke@1 432 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 433 sr.mergeWith(csp(tree.lhs));
duke@1 434 sr.mergeWith(csp(tree.rhs));
duke@1 435 result = sr;
duke@1 436 }
duke@1 437
duke@1 438 public void visitUnary(JCUnary tree) {
duke@1 439 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 440 sr.mergeWith(csp(tree.arg));
duke@1 441 result = sr;
duke@1 442 }
duke@1 443
duke@1 444 public void visitBinary(JCBinary tree) {
duke@1 445 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 446 sr.mergeWith(csp(tree.lhs));
duke@1 447 sr.mergeWith(csp(tree.rhs));
duke@1 448 result = sr;
duke@1 449 }
duke@1 450
duke@1 451 public void visitTypeCast(JCTypeCast tree) {
duke@1 452 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 453 sr.mergeWith(csp(tree.clazz));
duke@1 454 sr.mergeWith(csp(tree.expr));
duke@1 455 result = sr;
duke@1 456 }
duke@1 457
duke@1 458 public void visitTypeTest(JCInstanceOf tree) {
duke@1 459 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 460 sr.mergeWith(csp(tree.expr));
duke@1 461 sr.mergeWith(csp(tree.clazz));
duke@1 462 result = sr;
duke@1 463 }
duke@1 464
duke@1 465 public void visitIndexed(JCArrayAccess tree) {
duke@1 466 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 467 sr.mergeWith(csp(tree.indexed));
duke@1 468 sr.mergeWith(csp(tree.index));
duke@1 469 result = sr;
duke@1 470 }
duke@1 471
duke@1 472 public void visitSelect(JCFieldAccess tree) {
duke@1 473 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 474 sr.mergeWith(csp(tree.selected));
duke@1 475 result = sr;
duke@1 476 }
duke@1 477
duke@1 478 public void visitIdent(JCIdent tree) {
duke@1 479 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 480 result = sr;
duke@1 481 }
duke@1 482
duke@1 483 public void visitLiteral(JCLiteral tree) {
duke@1 484 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 485 result = sr;
duke@1 486 }
duke@1 487
duke@1 488 public void visitTypeIdent(JCPrimitiveTypeTree tree) {
duke@1 489 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 490 result = sr;
duke@1 491 }
duke@1 492
duke@1 493 public void visitTypeArray(JCArrayTypeTree tree) {
duke@1 494 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 495 sr.mergeWith(csp(tree.elemtype));
duke@1 496 result = sr;
duke@1 497 }
duke@1 498
duke@1 499 public void visitTypeApply(JCTypeApply tree) {
duke@1 500 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 501 sr.mergeWith(csp(tree.clazz));
duke@1 502 sr.mergeWith(csp(tree.arguments));
duke@1 503 result = sr;
duke@1 504 }
duke@1 505
duke@1 506 public void visitTypeParameter(JCTypeParameter tree) {
duke@1 507 SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
duke@1 508 sr.mergeWith(csp(tree.bounds));
duke@1 509 result = sr;
duke@1 510 }
duke@1 511
duke@1 512 public void visitWildcard(JCWildcard tree) {
duke@1 513 result = null;
duke@1 514 }
duke@1 515
duke@1 516 public void visitErroneous(JCErroneous tree) {
duke@1 517 result = null;
duke@1 518 }
duke@1 519
duke@1 520 public void visitTree(JCTree tree) {
jjg@816 521 Assert.error();
duke@1 522 }
duke@1 523
duke@1 524 /** The start position of given tree.
duke@1 525 */
duke@1 526 public int startPos(JCTree tree) {
duke@1 527 if (tree == null) return Position.NOPOS;
duke@1 528 return tree.pos;
duke@1 529 }
duke@1 530
duke@1 531 /** The end position of given tree, if it has
duke@1 532 * defined endpos, NOPOS otherwise.
duke@1 533 */
duke@1 534 public int endPos(JCTree tree) {
duke@1 535 if (tree == null) return Position.NOPOS;
jjg@1127 536 if (tree.hasTag(JCTree.Tag.BLOCK))
duke@1 537 return ((JCBlock) tree).endpos;
ksrini@1138 538 return endPosTable.getEndPos(tree);
duke@1 539 }
duke@1 540 }
duke@1 541
duke@1 542 /** This class contains a CharacterRangeTableEntry.
duke@1 543 */
duke@1 544 static class CRTEntry {
duke@1 545
duke@1 546 /** A tree or a list of trees to obtain source positions.
duke@1 547 */
duke@1 548 Object tree;
duke@1 549
duke@1 550 /** The flags described in the CharacterRangeTable spec.
duke@1 551 */
duke@1 552 int flags;
duke@1 553
duke@1 554 /** The starting code position of this entry.
duke@1 555 */
duke@1 556 int startPc;
duke@1 557
duke@1 558 /** The ending code position of this entry.
duke@1 559 */
duke@1 560 int endPc;
duke@1 561
duke@1 562 /** Constructor */
duke@1 563 CRTEntry(Object tree, int flags, int startPc, int endPc) {
duke@1 564 this.tree = tree;
duke@1 565 this.flags = flags;
duke@1 566 this.startPc = startPc;
duke@1 567 this.endPc = endPc;
duke@1 568 }
duke@1 569 }
duke@1 570
duke@1 571
duke@1 572 /** This class contains source positions
duke@1 573 * for some tree or list of trees.
duke@1 574 */
duke@1 575 static class SourceRange {
duke@1 576
duke@1 577 /** The starting source position.
duke@1 578 */
duke@1 579 int startPos;
duke@1 580
duke@1 581 /** The ending source position.
duke@1 582 */
duke@1 583 int endPos;
duke@1 584
duke@1 585 /** Constructor */
duke@1 586 SourceRange() {
duke@1 587 startPos = Position.NOPOS;
duke@1 588 endPos = Position.NOPOS;
duke@1 589 }
duke@1 590
duke@1 591 /** Constructor */
duke@1 592 SourceRange(int startPos, int endPos) {
duke@1 593 this.startPos = startPos;
duke@1 594 this.endPos = endPos;
duke@1 595 }
duke@1 596
duke@1 597 /** Compare the starting and the ending positions
duke@1 598 * of the source range and combines them assigning
duke@1 599 * the widest range to this.
duke@1 600 */
duke@1 601 SourceRange mergeWith(SourceRange sr) {
duke@1 602 if (sr == null) return this;
duke@1 603 if (startPos == Position.NOPOS)
duke@1 604 startPos = sr.startPos;
duke@1 605 else if (sr.startPos != Position.NOPOS)
duke@1 606 startPos = (startPos < sr.startPos ? startPos : sr.startPos);
duke@1 607 if (endPos == Position.NOPOS)
duke@1 608 endPos = sr.endPos;
duke@1 609 else if (sr.endPos != Position.NOPOS)
duke@1 610 endPos = (endPos > sr.endPos ? endPos : sr.endPos);
duke@1 611 return this;
duke@1 612 }
duke@1 613 }
duke@1 614
duke@1 615 }

mercurial