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