Get the token whose text contains the position
(sourceFile, position, allowPositionInLeadingTrivia, includePrecedingTokenAtEndPosition, includeEndPosition)
| 127417 | ts.getTokenAtPosition = getTokenAtPosition; |
| 127418 | /** Get the token whose text contains the position */ |
| 127419 | function getTokenAtPositionWorker(sourceFile, position, allowPositionInLeadingTrivia, includePrecedingTokenAtEndPosition, includeEndPosition) { |
| 127420 | var current = sourceFile; |
| 127421 | var foundToken; |
| 127422 | var _loop_1 = function () { |
| 127423 | // find the child that contains 'position' |
| 127424 | var children = current.getChildren(sourceFile); |
| 127425 | var i = ts.binarySearchKey(children, position, function (_, i) { return i; }, function (middle, _) { |
| 127426 | // This last callback is more of a selector than a comparator - |
| 127427 | // `EqualTo` causes the `middle` result to be returned |
| 127428 | // `GreaterThan` causes recursion on the left of the middle |
| 127429 | // `LessThan` causes recursion on the right of the middle |
| 127430 | // Let's say you have 3 nodes, spanning positons |
| 127431 | // pos: 1, end: 3 |
| 127432 | // pos: 3, end: 3 |
| 127433 | // pos: 3, end: 5 |
| 127434 | // and you're looking for the token at positon 3 - all 3 of these nodes are overlapping with position 3. |
| 127435 | // In fact, there's a _good argument_ that node 2 shouldn't even be allowed to exist - depending on if |
| 127436 | // the start or end of the ranges are considered inclusive, it's either wholly subsumed by the first or the last node. |
| 127437 | // Unfortunately, such nodes do exist. :( - See fourslash/completionsImport_tsx.tsx - empty jsx attributes create |
| 127438 | // a zero-length node. |
| 127439 | // What also you may not expect is that which node we return depends on the includePrecedingTokenAtEndPosition flag. |
| 127440 | // Specifically, if includePrecedingTokenAtEndPosition is set, we return the 1-3 node, while if it's unset, we |
| 127441 | // return the 3-5 node. (The zero length node is never correct.) This is because the includePrecedingTokenAtEndPosition |
| 127442 | // flag causes us to return the first node whose end position matches the position and which produces and acceptable token |
| 127443 | // kind. Meanwhile, if includePrecedingTokenAtEndPosition is unset, we look for the first node whose start is <= the |
| 127444 | // position and whose end is greater than the position. |
| 127445 | var start = allowPositionInLeadingTrivia ? children[middle].getFullStart() : children[middle].getStart(sourceFile, /*includeJsDoc*/ true); |
| 127446 | if (start > position) { |
| 127447 | return 1 /* Comparison.GreaterThan */; |
| 127448 | } |
| 127449 | // first element whose start position is before the input and whose end position is after or equal to the input |
| 127450 | if (nodeContainsPosition(children[middle])) { |
| 127451 | if (children[middle - 1]) { |
| 127452 | // we want the _first_ element that contains the position, so left-recur if the prior node also contains the position |
| 127453 | if (nodeContainsPosition(children[middle - 1])) { |
| 127454 | return 1 /* Comparison.GreaterThan */; |
| 127455 | } |
| 127456 | } |
| 127457 | return 0 /* Comparison.EqualTo */; |
| 127458 | } |
| 127459 | // this complex condition makes us left-recur around a zero-length node when includePrecedingTokenAtEndPosition is set, rather than right-recur on it |
| 127460 | if (includePrecedingTokenAtEndPosition && start === position && children[middle - 1] && children[middle - 1].getEnd() === position && nodeContainsPosition(children[middle - 1])) { |
| 127461 | return 1 /* Comparison.GreaterThan */; |
| 127462 | } |
| 127463 | return -1 /* Comparison.LessThan */; |
| 127464 | }); |
| 127465 | if (foundToken) { |
| 127466 | return { value: foundToken }; |
| 127467 | } |
| 127468 | if (i >= 0 && children[i]) { |
| 127469 | current = children[i]; |
| 127470 | return "continue-outer"; |
| 127471 | } |
| 127472 | return { value: current }; |
| 127473 | }; |
| 127474 | outer: while (true) { |
| 127475 | var state_1 = _loop_1(); |
| 127476 | if (typeof state_1 === "object") |
no test coverage detected