From 2b45d3b64fa1cc30bc22ddb23e06ce94d933b6c9 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 7 Jun 2021 11:43:06 -0400 Subject: [PATCH] `getEditsForFileRename`: fix `updateTsconfigFiles` w/ empty `include` Avoid the assumption that there are always include patterns: when there are none (and therefore the renamed file didn't match anyway), just skip the test for added include. Also change the code to use `return` to make it flatter. (Also get rid of a redundant type.) Fixes #40386. --- src/services/getEditsForFileRename.ts | 23 +++++++++---------- ...itsForFileRename_tsconfig_empty_include.ts | 14 +++++++++++ 2 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 tests/cases/fourslash/getEditsForFileRename_tsconfig_empty_include.ts diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index 563e10680522a..907cc8f221ee6 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -59,16 +59,16 @@ namespace ts { case "include": case "exclude": { const foundExactMatch = updatePaths(property); - if (!foundExactMatch && propertyName === "include" && isArrayLiteralExpression(property.initializer)) { - const includes = mapDefined(property.initializer.elements, e => isStringLiteral(e) ? e.text : undefined); - const matchers = getFileMatcherPatterns(configDir, /*excludes*/ [], includes, useCaseSensitiveFileNames, currentDirectory); - // If there isn't some include for this, add a new one. - if (getRegexFromPattern(Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(oldFileOrDirPath) && - !getRegexFromPattern(Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(newFileOrDirPath)) { - changeTracker.insertNodeAfter(configFile, last(property.initializer.elements), factory.createStringLiteral(relativePath(newFileOrDirPath))); - } + if (foundExactMatch || propertyName !== "include" || !isArrayLiteralExpression(property.initializer)) return; + const includes = mapDefined(property.initializer.elements, e => isStringLiteral(e) ? e.text : undefined); + if (includes.length === 0) return; + const matchers = getFileMatcherPatterns(configDir, /*excludes*/ [], includes, useCaseSensitiveFileNames, currentDirectory); + // If there isn't some include for this, add a new one. + if (getRegexFromPattern(Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(oldFileOrDirPath) && + !getRegexFromPattern(Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(newFileOrDirPath)) { + changeTracker.insertNodeAfter(configFile, last(property.initializer.elements), factory.createStringLiteral(relativePath(newFileOrDirPath))); } - break; + return; } case "compilerOptions": forEachProperty(property.initializer, (property, propertyName) => { @@ -85,13 +85,12 @@ namespace ts { }); } }); - break; + return; } }); function updatePaths(property: PropertyAssignment): boolean { - // Type annotation needed due to #7294 - const elements: readonly Expression[] = isArrayLiteralExpression(property.initializer) ? property.initializer.elements : [property.initializer]; + const elements = isArrayLiteralExpression(property.initializer) ? property.initializer.elements : [property.initializer]; let foundExactMatch = false; for (const element of elements) { foundExactMatch = tryUpdateString(element) || foundExactMatch; diff --git a/tests/cases/fourslash/getEditsForFileRename_tsconfig_empty_include.ts b/tests/cases/fourslash/getEditsForFileRename_tsconfig_empty_include.ts new file mode 100644 index 0000000000000..968f16e32c5cd --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_tsconfig_empty_include.ts @@ -0,0 +1,14 @@ +/// + +// @Filename: /a/foo.ts +////const x = 1 + +// @Filename: /a/tsconfig.json +////{ "include": [] } + +verify.getEditsForFileRename({ + oldPath: "/a/foo.ts", + newPath: "/a/bar.ts", + newFileContents: { + } +});