PathEnclosingInterval returns the node that encloses the source interval [start, end), and all its ancestors up to the AST root.

The definition of "enclosing" used by this function considers additional whitespace abutting a node to be enclosed by it. In this example:

z := x + y // add them

the ast.BinaryExpr(+) node is considered to enclose interval B even though its [Pos()..End()) is actually only interval A. This behaviour makes user interfaces more tolerant of imperfect input.

This function treats tokens as nodes, though they are not included in the result. e.g. PathEnclosingInterval("+") returns the enclosing ast.BinaryExpr("x + y").

If start==end, the 1-char interval following start is used instead.

The 'exact' result is true if the interval contains only path[0] and perhaps some adjacent whitespace. It is false if the interval overlaps multiple children of path[0], or if it contains only interior whitespace of path[0]. In this example:

z := x + y // add them
  <--C-->     <---E-->

intervals C, D and E are inexact. C is contained by the z-assignment statement, because it spans three of its children (:=, x, +). So too is the 1-char interval D, because it contains only interior whitespace of the assignment. E is considered interior whitespace of the BlockStmt containing the assignment.

Precondition: [start, end) both lie within the same file as root. TODO(adonovan): return (nil, false) in this case and remove precond. Requires FileSet; see loader.tokenFileContainsPos.

Postcondition: path is never nil; it always contains at least 'root'.

PathEnclosingInterval is referenced in 0 repositories