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

Fri, 16 Jul 2010 19:35:24 -0700

author
darcy
date
Fri, 16 Jul 2010 19:35:24 -0700
changeset 609
13354e1abba7
parent 581
f2fdd52e4e87
child 798
4868a36f6fd8
permissions
-rw-r--r--

6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
6964740: Project Coin: More tests for ARM compiler changes
6965277: Project Coin: Correctness issues in ARM implementation
6967065: add -Xlint warning category for Automatic Resource Management (ARM)
Reviewed-by: jjb, darcy, mcimadamore, jjg, briangoetz
Contributed-by: tball@google.com

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

mercurial