diff --git a/src/compiler/core.ts b/src/compiler/core.ts index ec171d4aee2..db16975b0fe 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -193,6 +193,13 @@ namespace ts { return array[array.length - 1]; } + /** + * Performs a binary search, finding the index at which 'value' occurs in 'array'. + * If no such index is found, returns the 2's-complement of first index at which + * number[index] exceeds number. + * @param array A sorted array whose first element must be no larger than number + * @param number The value to be searched for in the array. + */ export function binarySearch(array: number[], value: number): number { let low = 0; let high = array.length - 1; @@ -805,4 +812,4 @@ namespace ts { Debug.assert(false, message); } } -} +} diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 9122cadc287..2e692470cc5 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -320,13 +320,20 @@ namespace ts { /* @internal */ export function computeLineAndCharacterOfPosition(lineStarts: number[], position: number) { + Debug.assert(lineStarts.length && lineStarts[0] === 0, "the first line should start at position 0"); + Debug.assert(0 <= position, "position should be positive"); + let lineNumber = binarySearch(lineStarts, position); if (lineNumber < 0) { // If the actual position was not found, - // the binary search returns the negative value of the next line start + // the binary search returns the 2's-complement of the next line start // e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20 - // then the search will return -2 + // then the search will return -2. + // + // We want the index of the previous line start, so we subtract 1. + // Review 2's-complement if this is confusing. lineNumber = ~lineNumber - 1; + Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file"); } return { line: lineNumber, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e0f16a00c2b..cdd814065c5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -583,9 +583,9 @@ namespace ts { * Several node kinds share function-like features such as a signature, * a name, and a body. These nodes should extend FunctionLikeDeclaration. * Examples: - * FunctionDeclaration - * MethodDeclaration - * AccessorDeclaration + * * FunctionDeclaration + * * MethodDeclaration + * * AccessorDeclaration */ export interface FunctionLikeDeclaration extends SignatureDeclaration { _functionLikeDeclarationBrand: any; @@ -1774,10 +1774,10 @@ namespace ts { StringLike = String | StringLiteral, NumberLike = Number | Enum, ObjectType = Class | Interface | Reference | Tuple | Anonymous, - UnionOrIntersection = Union | Intersection, + UnionOrIntersection = Union | Intersection, StructuredType = ObjectType | Union | Intersection, /* @internal */ - RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral + RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral } // Properties common to all types