1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/CRTable.java Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,616 @@ 1.4 +/* 1.5 + * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Sun designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Sun in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.26 + * have any questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.javac.jvm; 1.30 + 1.31 +import java.util.*; 1.32 + 1.33 +import com.sun.tools.javac.tree.*; 1.34 +import com.sun.tools.javac.util.*; 1.35 +import com.sun.tools.javac.util.List; 1.36 +import com.sun.tools.javac.tree.JCTree.*; 1.37 + 1.38 +/** This class contains the CharacterRangeTable for some method 1.39 + * and the hashtable for mapping trees or lists of trees to their 1.40 + * ending positions. 1.41 + * 1.42 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 1.43 + * you write code that depends on this, you do so at your own risk. 1.44 + * This code and its internal interfaces are subject to change or 1.45 + * deletion without notice.</b> 1.46 + */ 1.47 +public class CRTable 1.48 +implements CRTFlags { 1.49 + 1.50 + private final boolean crtDebug = false; 1.51 + 1.52 + /** The list of CRTable entries. 1.53 + */ 1.54 + private ListBuffer<CRTEntry> entries = new ListBuffer<CRTEntry>(); 1.55 + 1.56 + /** The hashtable for source positions. 1.57 + */ 1.58 + private Map<Object,SourceRange> positions = new HashMap<Object,SourceRange>(); 1.59 + 1.60 + /** The hashtable for ending positions stored in the parser. 1.61 + */ 1.62 + private Map<JCTree, Integer> endPositions; 1.63 + 1.64 + /** The tree of the method this table is intended for. 1.65 + * We should traverse this tree to get source ranges. 1.66 + */ 1.67 + JCTree.JCMethodDecl methodTree; 1.68 + 1.69 + /** Constructor 1.70 + */ 1.71 + public CRTable(JCTree.JCMethodDecl tree, Map<JCTree, Integer> endPositions) { 1.72 + this.methodTree = tree; 1.73 + this.endPositions = endPositions; 1.74 + } 1.75 + 1.76 + /** Create a new CRTEntry and add it to the entries. 1.77 + * @param tree The tree or the list of trees for which 1.78 + * we are storing the code pointers. 1.79 + * @param flags The set of flags designating type of the entry. 1.80 + * @param startPc The starting code position. 1.81 + * @param endPc The ending code position. 1.82 + */ 1.83 + public void put(Object tree, int flags, int startPc, int endPc) { 1.84 + entries.append(new CRTEntry(tree, flags, startPc, endPc)); 1.85 + } 1.86 + 1.87 + /** Compute source positions and write CRT to the databuf. 1.88 + * @param databuf The buffer to write bytecodes to. 1.89 + */ 1.90 + public int writeCRT(ByteBuffer databuf, Position.LineMap lineMap, Log log) { 1.91 + 1.92 + int crtEntries = 0; 1.93 + 1.94 + // compute source positions for the method 1.95 + new SourceComputer().csp(methodTree); 1.96 + 1.97 + for (List<CRTEntry> l = entries.toList(); l.nonEmpty(); l = l.tail) { 1.98 + 1.99 + CRTEntry entry = l.head; 1.100 + 1.101 + // eliminate entries that do not produce bytecodes: 1.102 + // for example, empty blocks and statements 1.103 + if (entry.startPc == entry.endPc) 1.104 + continue; 1.105 + 1.106 + SourceRange pos = positions.get(entry.tree); 1.107 + assert pos != null : "CRT: tree source positions are undefined"; 1.108 + if ((pos.startPos == Position.NOPOS) || (pos.endPos == Position.NOPOS)) 1.109 + continue; 1.110 + 1.111 + if (crtDebug) { 1.112 + System.out.println("Tree: " + entry.tree + ", type:" + getTypes(entry.flags)); 1.113 + System.out.print("Start: pos = " + pos.startPos + ", pc = " + entry.startPc); 1.114 + } 1.115 + 1.116 + // encode startPos into line/column representation 1.117 + int startPos = encodePosition(pos.startPos, lineMap, log); 1.118 + if (startPos == Position.NOPOS) 1.119 + continue; 1.120 + 1.121 + if (crtDebug) { 1.122 + System.out.print("End: pos = " + pos.endPos + ", pc = " + (entry.endPc - 1)); 1.123 + } 1.124 + 1.125 + // encode endPos into line/column representation 1.126 + int endPos = encodePosition(pos.endPos, lineMap, log); 1.127 + if (endPos == Position.NOPOS) 1.128 + continue; 1.129 + 1.130 + // write attribute 1.131 + databuf.appendChar(entry.startPc); 1.132 + // 'endPc - 1' because endPc actually points to start of the next command 1.133 + databuf.appendChar(entry.endPc - 1); 1.134 + databuf.appendInt(startPos); 1.135 + databuf.appendInt(endPos); 1.136 + databuf.appendChar(entry.flags); 1.137 + 1.138 + crtEntries++; 1.139 + } 1.140 + 1.141 + return crtEntries; 1.142 + } 1.143 + 1.144 + /** Return the number of the entries. 1.145 + */ 1.146 + public int length() { 1.147 + return entries.length(); 1.148 + } 1.149 + 1.150 + /** Return string describing flags enabled. 1.151 + */ 1.152 + private String getTypes(int flags) { 1.153 + String types = ""; 1.154 + if ((flags & CRT_STATEMENT) != 0) types += " CRT_STATEMENT"; 1.155 + if ((flags & CRT_BLOCK) != 0) types += " CRT_BLOCK"; 1.156 + if ((flags & CRT_ASSIGNMENT) != 0) types += " CRT_ASSIGNMENT"; 1.157 + if ((flags & CRT_FLOW_CONTROLLER) != 0) types += " CRT_FLOW_CONTROLLER"; 1.158 + if ((flags & CRT_FLOW_TARGET) != 0) types += " CRT_FLOW_TARGET"; 1.159 + if ((flags & CRT_INVOKE) != 0) types += " CRT_INVOKE"; 1.160 + if ((flags & CRT_CREATE) != 0) types += " CRT_CREATE"; 1.161 + if ((flags & CRT_BRANCH_TRUE) != 0) types += " CRT_BRANCH_TRUE"; 1.162 + if ((flags & CRT_BRANCH_FALSE) != 0) types += " CRT_BRANCH_FALSE"; 1.163 + return types; 1.164 + } 1.165 + 1.166 + /** Source file positions in CRT are integers in the format: 1.167 + * line-number << LINESHIFT + column-number 1.168 + */ 1.169 + private int encodePosition(int pos, Position.LineMap lineMap, Log log) { 1.170 + int line = lineMap.getLineNumber(pos); 1.171 + int col = lineMap.getColumnNumber(pos); 1.172 + int new_pos = Position.encodePosition(line, col); 1.173 + if (crtDebug) { 1.174 + System.out.println(", line = " + line + ", column = " + col + 1.175 + ", new_pos = " + new_pos); 1.176 + } 1.177 + if (new_pos == Position.NOPOS) 1.178 + log.warning(pos, "position.overflow", line); 1.179 + 1.180 + return new_pos; 1.181 + } 1.182 + 1.183 +/* ************************************************************************ 1.184 + * Traversal methods 1.185 + *************************************************************************/ 1.186 + 1.187 + /** 1.188 + * This class contains methods to compute source positions for trees. 1.189 + * Extends Tree.Visitor to traverse the abstract syntax tree. 1.190 + */ 1.191 + class SourceComputer extends JCTree.Visitor { 1.192 + 1.193 + /** The result of the tree traversal methods. 1.194 + */ 1.195 + SourceRange result; 1.196 + 1.197 + /** Visitor method: compute source positions for a single node. 1.198 + */ 1.199 + public SourceRange csp(JCTree tree) { 1.200 + if (tree == null) return null; 1.201 + tree.accept(this); 1.202 + if (result != null) { 1.203 + positions.put(tree, result); 1.204 + } 1.205 + return result; 1.206 + } 1.207 + 1.208 + /** Visitor method: compute source positions for a list of nodes. 1.209 + */ 1.210 + public SourceRange csp(List<? extends JCTree> trees) { 1.211 + if ((trees == null) || !(trees.nonEmpty())) return null; 1.212 + SourceRange list_sr = new SourceRange(); 1.213 + for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail) { 1.214 + list_sr.mergeWith(csp(l.head)); 1.215 + } 1.216 + positions.put(trees, list_sr); 1.217 + return list_sr; 1.218 + } 1.219 + 1.220 + /** Visitor method: compute source positions for 1.221 + * a list of case blocks of switch statements. 1.222 + */ 1.223 + public SourceRange cspCases(List<JCCase> trees) { 1.224 + if ((trees == null) || !(trees.nonEmpty())) return null; 1.225 + SourceRange list_sr = new SourceRange(); 1.226 + for (List<JCCase> l = trees; l.nonEmpty(); l = l.tail) { 1.227 + list_sr.mergeWith(csp(l.head)); 1.228 + } 1.229 + positions.put(trees, list_sr); 1.230 + return list_sr; 1.231 + } 1.232 + 1.233 + /** Visitor method: compute source positions for 1.234 + * a list of catch clauses in try statements. 1.235 + */ 1.236 + public SourceRange cspCatchers(List<JCCatch> trees) { 1.237 + if ((trees == null) || !(trees.nonEmpty())) return null; 1.238 + SourceRange list_sr = new SourceRange(); 1.239 + for (List<JCCatch> l = trees; l.nonEmpty(); l = l.tail) { 1.240 + list_sr.mergeWith(csp(l.head)); 1.241 + } 1.242 + positions.put(trees, list_sr); 1.243 + return list_sr; 1.244 + } 1.245 + 1.246 + public void visitMethodDef(JCMethodDecl tree) { 1.247 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.248 + sr.mergeWith(csp(tree.body)); 1.249 + result = sr; 1.250 + } 1.251 + 1.252 + public void visitVarDef(JCVariableDecl tree) { 1.253 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.254 + csp(tree.vartype); 1.255 + sr.mergeWith(csp(tree.init)); 1.256 + result = sr; 1.257 + } 1.258 + 1.259 + public void visitSkip(JCSkip tree) { 1.260 + // endPos is the same as startPos for the empty statement 1.261 + SourceRange sr = new SourceRange(startPos(tree), startPos(tree)); 1.262 + result = sr; 1.263 + } 1.264 + 1.265 + public void visitBlock(JCBlock tree) { 1.266 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.267 + csp(tree.stats); // doesn't compare because block's ending position is defined 1.268 + result = sr; 1.269 + } 1.270 + 1.271 + public void visitDoLoop(JCDoWhileLoop tree) { 1.272 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.273 + sr.mergeWith(csp(tree.body)); 1.274 + sr.mergeWith(csp(tree.cond)); 1.275 + result = sr; 1.276 + } 1.277 + 1.278 + public void visitWhileLoop(JCWhileLoop tree) { 1.279 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.280 + sr.mergeWith(csp(tree.cond)); 1.281 + sr.mergeWith(csp(tree.body)); 1.282 + result = sr; 1.283 + } 1.284 + 1.285 + public void visitForLoop(JCForLoop tree) { 1.286 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.287 + sr.mergeWith(csp(tree.init)); 1.288 + sr.mergeWith(csp(tree.cond)); 1.289 + sr.mergeWith(csp(tree.step)); 1.290 + sr.mergeWith(csp(tree.body)); 1.291 + result = sr; 1.292 + } 1.293 + 1.294 + public void visitForeachLoop(JCEnhancedForLoop tree) { 1.295 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.296 + sr.mergeWith(csp(tree.var)); 1.297 + sr.mergeWith(csp(tree.expr)); 1.298 + sr.mergeWith(csp(tree.body)); 1.299 + result = sr; 1.300 + } 1.301 + 1.302 + public void visitLabelled(JCLabeledStatement tree) { 1.303 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.304 + sr.mergeWith(csp(tree.body)); 1.305 + result = sr; 1.306 + } 1.307 + 1.308 + public void visitSwitch(JCSwitch tree) { 1.309 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.310 + sr.mergeWith(csp(tree.selector)); 1.311 + sr.mergeWith(cspCases(tree.cases)); 1.312 + result = sr; 1.313 + } 1.314 + 1.315 + public void visitCase(JCCase tree) { 1.316 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.317 + sr.mergeWith(csp(tree.pat)); 1.318 + sr.mergeWith(csp(tree.stats)); 1.319 + result = sr; 1.320 + } 1.321 + 1.322 + public void visitSynchronized(JCSynchronized tree) { 1.323 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.324 + sr.mergeWith(csp(tree.lock)); 1.325 + sr.mergeWith(csp(tree.body)); 1.326 + result = sr; 1.327 + } 1.328 + 1.329 + public void visitTry(JCTry tree) { 1.330 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.331 + sr.mergeWith(csp(tree.body)); 1.332 + sr.mergeWith(cspCatchers(tree.catchers)); 1.333 + sr.mergeWith(csp(tree.finalizer)); 1.334 + result = sr; 1.335 + } 1.336 + 1.337 + public void visitCatch(JCCatch tree) { 1.338 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.339 + sr.mergeWith(csp(tree.param)); 1.340 + sr.mergeWith(csp(tree.body)); 1.341 + result = sr; 1.342 + } 1.343 + 1.344 + public void visitConditional(JCConditional tree) { 1.345 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.346 + sr.mergeWith(csp(tree.cond)); 1.347 + sr.mergeWith(csp(tree.truepart)); 1.348 + sr.mergeWith(csp(tree.falsepart)); 1.349 + result = sr; 1.350 + } 1.351 + 1.352 + public void visitIf(JCIf tree) { 1.353 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.354 + sr.mergeWith(csp(tree.cond)); 1.355 + sr.mergeWith(csp(tree.thenpart)); 1.356 + sr.mergeWith(csp(tree.elsepart)); 1.357 + result = sr; 1.358 + } 1.359 + 1.360 + public void visitExec(JCExpressionStatement tree) { 1.361 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.362 + sr.mergeWith(csp(tree.expr)); 1.363 + result = sr; 1.364 + } 1.365 + 1.366 + public void visitBreak(JCBreak tree) { 1.367 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.368 + result = sr; 1.369 + } 1.370 + 1.371 + public void visitContinue(JCContinue tree) { 1.372 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.373 + result = sr; 1.374 + } 1.375 + 1.376 + public void visitReturn(JCReturn tree) { 1.377 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.378 + sr.mergeWith(csp(tree.expr)); 1.379 + result = sr; 1.380 + } 1.381 + 1.382 + public void visitThrow(JCThrow tree) { 1.383 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.384 + sr.mergeWith(csp(tree.expr)); 1.385 + result = sr; 1.386 + } 1.387 + 1.388 + public void visitAssert(JCAssert tree) { 1.389 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.390 + sr.mergeWith(csp(tree.cond)); 1.391 + sr.mergeWith(csp(tree.detail)); 1.392 + result = sr; 1.393 + } 1.394 + 1.395 + public void visitApply(JCMethodInvocation tree) { 1.396 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.397 + sr.mergeWith(csp(tree.meth)); 1.398 + sr.mergeWith(csp(tree.args)); 1.399 + result = sr; 1.400 + } 1.401 + 1.402 + public void visitNewClass(JCNewClass tree) { 1.403 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.404 + sr.mergeWith(csp(tree.encl)); 1.405 + sr.mergeWith(csp(tree.clazz)); 1.406 + sr.mergeWith(csp(tree.args)); 1.407 + sr.mergeWith(csp(tree.def)); 1.408 + result = sr; 1.409 + } 1.410 + 1.411 + public void visitNewArray(JCNewArray tree) { 1.412 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.413 + sr.mergeWith(csp(tree.elemtype)); 1.414 + sr.mergeWith(csp(tree.dims)); 1.415 + sr.mergeWith(csp(tree.elems)); 1.416 + result = sr; 1.417 + } 1.418 + 1.419 + public void visitParens(JCParens tree) { 1.420 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.421 + sr.mergeWith(csp(tree.expr)); 1.422 + result = sr; 1.423 + } 1.424 + 1.425 + public void visitAssign(JCAssign tree) { 1.426 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.427 + sr.mergeWith(csp(tree.lhs)); 1.428 + sr.mergeWith(csp(tree.rhs)); 1.429 + result = sr; 1.430 + } 1.431 + 1.432 + public void visitAssignop(JCAssignOp tree) { 1.433 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.434 + sr.mergeWith(csp(tree.lhs)); 1.435 + sr.mergeWith(csp(tree.rhs)); 1.436 + result = sr; 1.437 + } 1.438 + 1.439 + public void visitUnary(JCUnary tree) { 1.440 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.441 + sr.mergeWith(csp(tree.arg)); 1.442 + result = sr; 1.443 + } 1.444 + 1.445 + public void visitBinary(JCBinary tree) { 1.446 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.447 + sr.mergeWith(csp(tree.lhs)); 1.448 + sr.mergeWith(csp(tree.rhs)); 1.449 + result = sr; 1.450 + } 1.451 + 1.452 + public void visitTypeCast(JCTypeCast tree) { 1.453 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.454 + sr.mergeWith(csp(tree.clazz)); 1.455 + sr.mergeWith(csp(tree.expr)); 1.456 + result = sr; 1.457 + } 1.458 + 1.459 + public void visitTypeTest(JCInstanceOf tree) { 1.460 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.461 + sr.mergeWith(csp(tree.expr)); 1.462 + sr.mergeWith(csp(tree.clazz)); 1.463 + result = sr; 1.464 + } 1.465 + 1.466 + public void visitIndexed(JCArrayAccess tree) { 1.467 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.468 + sr.mergeWith(csp(tree.indexed)); 1.469 + sr.mergeWith(csp(tree.index)); 1.470 + result = sr; 1.471 + } 1.472 + 1.473 + public void visitSelect(JCFieldAccess tree) { 1.474 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.475 + sr.mergeWith(csp(tree.selected)); 1.476 + result = sr; 1.477 + } 1.478 + 1.479 + public void visitIdent(JCIdent tree) { 1.480 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.481 + result = sr; 1.482 + } 1.483 + 1.484 + public void visitLiteral(JCLiteral tree) { 1.485 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.486 + result = sr; 1.487 + } 1.488 + 1.489 + public void visitTypeIdent(JCPrimitiveTypeTree tree) { 1.490 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.491 + result = sr; 1.492 + } 1.493 + 1.494 + public void visitTypeArray(JCArrayTypeTree tree) { 1.495 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.496 + sr.mergeWith(csp(tree.elemtype)); 1.497 + result = sr; 1.498 + } 1.499 + 1.500 + public void visitTypeApply(JCTypeApply tree) { 1.501 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.502 + sr.mergeWith(csp(tree.clazz)); 1.503 + sr.mergeWith(csp(tree.arguments)); 1.504 + result = sr; 1.505 + } 1.506 + 1.507 + public void visitTypeParameter(JCTypeParameter tree) { 1.508 + SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); 1.509 + sr.mergeWith(csp(tree.bounds)); 1.510 + result = sr; 1.511 + } 1.512 + 1.513 + public void visitWildcard(JCWildcard tree) { 1.514 + result = null; 1.515 + } 1.516 + 1.517 + public void visitErroneous(JCErroneous tree) { 1.518 + result = null; 1.519 + } 1.520 + 1.521 + public void visitTree(JCTree tree) { 1.522 + assert false; 1.523 + } 1.524 + 1.525 + /** The start position of given tree. 1.526 + */ 1.527 + public int startPos(JCTree tree) { 1.528 + if (tree == null) return Position.NOPOS; 1.529 + return tree.pos; 1.530 + } 1.531 + 1.532 + /** The end position of given tree, if it has 1.533 + * defined endpos, NOPOS otherwise. 1.534 + */ 1.535 + public int endPos(JCTree tree) { 1.536 + if (tree == null) return Position.NOPOS; 1.537 + if (tree.getTag() == JCTree.BLOCK) 1.538 + return ((JCBlock) tree).endpos; 1.539 + Integer endpos = endPositions.get(tree); 1.540 + if (endpos != null) 1.541 + return endpos.intValue(); 1.542 + return Position.NOPOS; 1.543 + } 1.544 + } 1.545 + 1.546 + /** This class contains a CharacterRangeTableEntry. 1.547 + */ 1.548 + static class CRTEntry { 1.549 + 1.550 + /** A tree or a list of trees to obtain source positions. 1.551 + */ 1.552 + Object tree; 1.553 + 1.554 + /** The flags described in the CharacterRangeTable spec. 1.555 + */ 1.556 + int flags; 1.557 + 1.558 + /** The starting code position of this entry. 1.559 + */ 1.560 + int startPc; 1.561 + 1.562 + /** The ending code position of this entry. 1.563 + */ 1.564 + int endPc; 1.565 + 1.566 + /** Constructor */ 1.567 + CRTEntry(Object tree, int flags, int startPc, int endPc) { 1.568 + this.tree = tree; 1.569 + this.flags = flags; 1.570 + this.startPc = startPc; 1.571 + this.endPc = endPc; 1.572 + } 1.573 + } 1.574 + 1.575 + 1.576 + /** This class contains source positions 1.577 + * for some tree or list of trees. 1.578 + */ 1.579 + static class SourceRange { 1.580 + 1.581 + /** The starting source position. 1.582 + */ 1.583 + int startPos; 1.584 + 1.585 + /** The ending source position. 1.586 + */ 1.587 + int endPos; 1.588 + 1.589 + /** Constructor */ 1.590 + SourceRange() { 1.591 + startPos = Position.NOPOS; 1.592 + endPos = Position.NOPOS; 1.593 + } 1.594 + 1.595 + /** Constructor */ 1.596 + SourceRange(int startPos, int endPos) { 1.597 + this.startPos = startPos; 1.598 + this.endPos = endPos; 1.599 + } 1.600 + 1.601 + /** Compare the starting and the ending positions 1.602 + * of the source range and combines them assigning 1.603 + * the widest range to this. 1.604 + */ 1.605 + SourceRange mergeWith(SourceRange sr) { 1.606 + if (sr == null) return this; 1.607 + if (startPos == Position.NOPOS) 1.608 + startPos = sr.startPos; 1.609 + else if (sr.startPos != Position.NOPOS) 1.610 + startPos = (startPos < sr.startPos ? startPos : sr.startPos); 1.611 + if (endPos == Position.NOPOS) 1.612 + endPos = sr.endPos; 1.613 + else if (sr.endPos != Position.NOPOS) 1.614 + endPos = (endPos > sr.endPos ? endPos : sr.endPos); 1.615 + return this; 1.616 + } 1.617 + } 1.618 + 1.619 +}