From 7b9cbfe16c51a165bb75e7df2c4d528fe250737d Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 8 May 2018 12:00:03 -0700 Subject: [PATCH] Fix error where node in tsconfig file was missing a source file --- src/services/breakpoints.ts | 4 ++-- src/services/formatting/smartIndenter.ts | 2 +- src/services/refactors/moveToNewFile.ts | 3 ++- src/services/types.ts | 2 +- src/services/utilities.ts | 20 ++++++++++---------- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index faab2b08db67c..6815be9863d1a 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -41,7 +41,7 @@ namespace ts.BreakpointResolver { } function textSpanEndingAtNextToken(startNode: Node, previousTokenToFindNextEndToken: Node): TextSpan { - return textSpan(startNode, findNextToken(previousTokenToFindNextEndToken, previousTokenToFindNextEndToken.parent)); + return textSpan(startNode, findNextToken(previousTokenToFindNextEndToken, previousTokenToFindNextEndToken.parent, sourceFile)); } function spanInNodeIfStartsOnSameLine(node: Node, otherwiseOnNode?: Node): TextSpan { @@ -60,7 +60,7 @@ namespace ts.BreakpointResolver { } function spanInNextNode(node: Node): TextSpan { - return spanInNode(findNextToken(node, node.parent)); + return spanInNode(findNextToken(node, node.parent, sourceFile)); } function spanInNode(node: Node): TextSpan { diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 0e89be425328c..a75781b8da0e4 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -269,7 +269,7 @@ namespace ts.formatting { } function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken: Node, current: Node, lineAtPosition: number, sourceFile: SourceFile): NextTokenKind { - const nextToken = findNextToken(precedingToken, current); + const nextToken = findNextToken(precedingToken, current, sourceFile); if (!nextToken) { return NextTokenKind.Unknown; } diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index f75d9ce884236..2f5a27f87f781 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -53,7 +53,8 @@ namespace ts.refactor { const newFileAbsolutePath = normalizePath(combinePaths(oldFileName, "..", newFileNameWithExtension)); const newFilePath = getRelativePathFromFile(cfg.fileName, newFileAbsolutePath, getCanonicalFileName); - const filesProp = cfg.jsonObject && find(cfg.jsonObject.properties, (prop): prop is PropertyAssignment => + const cfgObject = cfg.statements[0] && tryCast(cfg.statements[0].expression, isObjectLiteralExpression); + const filesProp = cfgObject && find(cfgObject.properties, (prop): prop is PropertyAssignment => isPropertyAssignment(prop) && isStringLiteral(prop.name) && prop.name.text === "files"); if (filesProp && isArrayLiteralExpression(filesProp.initializer)) { changes.insertNodeInListAfter(cfg, last(filesProp.initializer.elements), createLiteral(newFilePath), filesProp.initializer.elements); diff --git a/src/services/types.ts b/src/services/types.ts index 785d3f3f05297..cf2e58a3712a6 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -13,7 +13,7 @@ namespace ts { getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number; getFullStart(): number; getEnd(): number; - getWidth(sourceFile?: SourceFile): number; + getWidth(sourceFile?: SourceFileLike): number; getFullWidth(): number; getLeadingTriviaWidth(sourceFile?: SourceFile): number; getFullText(sourceFile?: SourceFile): string; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index fac577b3597f0..55b5f4f0ff910 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -707,7 +707,7 @@ namespace ts { return findPrecedingToken(position, file); } - export function findNextToken(previousToken: Node, parent: Node): Node { + export function findNextToken(previousToken: Node, parent: Node, sourceFile: SourceFile): Node { return find(parent); function find(n: Node): Node { @@ -724,7 +724,7 @@ namespace ts { // previous token ends exactly at the beginning of child (child.pos === previousToken.end); - if (shouldDiveInChildNode && nodeHasTokens(child)) { + if (shouldDiveInChildNode && nodeHasTokens(child, sourceFile)) { return find(child); } } @@ -759,12 +759,12 @@ namespace ts { const start = child.getStart(sourceFile, includeJsDoc); const lookInPreviousChild = (start >= position) || // cursor in the leading trivia - !nodeHasTokens(child) || + !nodeHasTokens(child, sourceFile) || isWhiteSpaceOnlyJsxText(child); if (lookInPreviousChild) { // actual start of the node is past the position - previous token should be at the end of previous child - const candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i); + const candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i, sourceFile); return candidate && findRightmostToken(candidate, sourceFile); } else { @@ -781,7 +781,7 @@ namespace ts { // Try to find the rightmost token in the file without filtering. // Namely we are skipping the check: 'position < node.end' if (children.length) { - const candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length); + const candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length, sourceFile); return candidate && findRightmostToken(candidate, sourceFile); } } @@ -797,21 +797,21 @@ namespace ts { } const children = n.getChildren(sourceFile); - const candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length); + const candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length, sourceFile); return candidate && findRightmostToken(candidate, sourceFile); } /** * Finds the rightmost child to the left of `children[exclusiveStartPosition]` which is a non-all-whitespace token or has constituent tokens. */ - function findRightmostChildNodeWithTokens(children: Node[], exclusiveStartPosition: number): Node | undefined { + function findRightmostChildNodeWithTokens(children: Node[], exclusiveStartPosition: number, sourceFile: SourceFile): Node | undefined { for (let i = exclusiveStartPosition - 1; i >= 0; i--) { const child = children[i]; if (isWhiteSpaceOnlyJsxText(child)) { Debug.assert(i > 0, "`JsxText` tokens should not be the first child of `JsxElement | JsxSelfClosingElement`"); } - else if (nodeHasTokens(children[i])) { + else if (nodeHasTokens(children[i], sourceFile)) { return children[i]; } } @@ -1022,10 +1022,10 @@ namespace ts { } } - function nodeHasTokens(n: Node): boolean { + function nodeHasTokens(n: Node, sourceFile: SourceFileLike): boolean { // If we have a token or node that has a non-zero width, it must have tokens. // Note: getWidth() does not take trivia into account. - return n.getWidth() !== 0; + return n.getWidth(sourceFile) !== 0; } export function getNodeModifiers(node: Node): string {