diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f4ddf1d8319..b6700d21a70 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -681,10 +681,22 @@ namespace ts { return getSpanOfTokenAtPosition(sourceFile, node.pos); } - const pos = nodeIsMissing(errorNode) + const isMissing = nodeIsMissing(errorNode); + const pos = isMissing ? errorNode.pos : skipTrivia(sourceFile.text, errorNode.pos); + // These asserts should all be satisfied for a properly constructed `errorNode`. + // Upstream from https://github.com/Microsoft/TypeScript/issues/20809. + if (isMissing) { + Debug.assert(pos === errorNode.pos); + Debug.assert(pos === errorNode.end); + } + else { + Debug.assert(pos >= errorNode.pos); + Debug.assert(pos <= errorNode.end); + } + return createTextSpanFromBounds(pos, errorNode.end); } diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index e3a2763b783..9b397584fed 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -335,6 +335,15 @@ namespace ts.refactor.extractSymbol { Continue = 1 << 1, Return = 1 << 2 } + + // This assert is upstream from https://github.com/Microsoft/TypeScript/issues/20809. + // We believe it's true because the node is from the (unmodified) tree. + Debug.assert(nodeToCheck.pos <= nodeToCheck.end); + + // This assert is upstream from https://github.com/Microsoft/TypeScript/issues/20809. + // For understanding how skipTrivia functioned: + Debug.assert(!positionIsSynthesized(nodeToCheck.pos)); + if (!isStatement(nodeToCheck) && !(isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) { return [createDiagnosticForNode(nodeToCheck, Messages.statementOrExpressionExpected)]; }