From 1c1d2851e84c925534883eac0e61863d5369104d Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 7 Mar 2018 14:14:28 -0800 Subject: [PATCH 1/4] Resolve config wildcards result order in a platform independent manner --- src/compiler/commandLineParser.ts | 62 ++++++++++++------- .../unittests/tsserverProjectSystem.ts | 16 ++--- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b0370620be47b..c44e7663ff673 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -2016,6 +2016,21 @@ namespace ts { return getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions); } + interface WildcardFileInfo { + path: string; + includeIndex: number; + } + + function makeCompareWildcardFileInfo(basePath: string) { + return (a: WildcardFileInfo, b: WildcardFileInfo) => { + return compareValues(a.includeIndex, b.includeIndex) || comparePaths(a.path, b.path, basePath); // Always compare case-sensitive so included files are in the same order on all platforms + }; + } + + function getFilePathFromWildcardFileInfo(info: WildcardFileInfo) { + return info.path; + } + /** * Gets the file names from the provided config file specs that contain, files, include, exclude and * other properties needed to resolve the file names @@ -2039,7 +2054,7 @@ namespace ts { // Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a // file map with a possibly case insensitive key. We use this map to store paths matched // via wildcard, and to handle extension priority. - const wildcardFileMap = createMap(); + const wildcardFileMap = createMap(); const { filesSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories } = spec; @@ -2057,32 +2072,35 @@ namespace ts { } if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) { - for (const file of host.readDirectory(basePath, supportedExtensions, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined)) { - // If we have already included a literal or wildcard path with a - // higher priority extension, we should skip this file. - // - // This handles cases where we may encounter both .ts and - // .d.ts (or .js if "allowJs" is enabled) in the same - // directory when they are compilation outputs. - if (hasFileWithHigherPriorityExtension(file, literalFileMap, wildcardFileMap, supportedExtensions, keyMapper)) { - continue; - } + for (let i = 0; i < validatedIncludeSpecs.length; i++) { + // We search one include spec at a time to ensure we respect include spec ordering + for (const file of host.readDirectory(basePath, supportedExtensions, validatedExcludeSpecs, [validatedIncludeSpecs[i]], /*depth*/ undefined)) { + // If we have already included a literal or wildcard path with a + // higher priority extension, we should skip this file. + // + // This handles cases where we may encounter both .ts and + // .d.ts (or .js if "allowJs" is enabled) in the same + // directory when they are compilation outputs. + if (hasFileWithHigherPriorityExtension(file, literalFileMap, wildcardFileMap, supportedExtensions, keyMapper)) { + continue; + } - // We may have included a wildcard path with a lower priority - // extension due to the user-defined order of entries in the - // "include" array. If there is a lower priority extension in the - // same directory, we should remove it. - removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper); + // We may have included a wildcard path with a lower priority + // extension due to the user-defined order of entries in the + // "include" array. If there is a lower priority extension in the + // same directory, we should remove it. + removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper); - const key = keyMapper(file); - if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) { - wildcardFileMap.set(key, file); + const key = keyMapper(file); + if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) { + wildcardFileMap.set(key, { path: file, includeIndex: i }); + } } } } const literalFiles = arrayFrom(literalFileMap.values()); - const wildcardFiles = arrayFrom(wildcardFileMap.values()); + const wildcardFiles = map(sort(arrayFrom(wildcardFileMap.values()), makeCompareWildcardFileInfo(basePath)), getFilePathFromWildcardFileInfo); return { fileNames: literalFiles.concat(wildcardFiles), wildcardDirectories, @@ -2201,7 +2219,7 @@ namespace ts { * @param extensionPriority The priority of the extension. * @param context The expansion context. */ - function hasFileWithHigherPriorityExtension(file: string, literalFiles: Map, wildcardFiles: Map, extensions: ReadonlyArray, keyMapper: (value: string) => string) { + function hasFileWithHigherPriorityExtension(file: string, literalFiles: Map, wildcardFiles: Map, extensions: ReadonlyArray, keyMapper: (value: string) => string) { const extensionPriority = getExtensionPriority(file, extensions); const adjustedExtensionPriority = adjustExtensionPriority(extensionPriority, extensions); for (let i = ExtensionPriority.Highest; i < adjustedExtensionPriority; i++) { @@ -2223,7 +2241,7 @@ namespace ts { * @param extensionPriority The priority of the extension. * @param context The expansion context. */ - function removeWildcardFilesWithLowerPriorityExtension(file: string, wildcardFiles: Map, extensions: ReadonlyArray, keyMapper: (value: string) => string) { + function removeWildcardFilesWithLowerPriorityExtension(file: string, wildcardFiles: Map, extensions: ReadonlyArray, keyMapper: (value: string) => string) { const extensionPriority = getExtensionPriority(file, extensions); const nextExtensionPriority = getNextLowestExtensionPriority(extensionPriority, extensions); for (let i = nextExtensionPriority; i < extensions.length; i++) { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 1ad8a594c78c5..5b19ff5c2def0 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -7313,10 +7313,11 @@ namespace ts.projectSystem { const resolutionTrace = createHostModuleResolutionTrace(host); const service = createProjectService(host); service.openClientFile(file1.path); - const expectedTrace = getExpectedRelativeModuleResolutionTrace(host, file1, module1, module1Name); - getExpectedRelativeModuleResolutionTrace(host, file1, module2, module2Name, expectedTrace); - getExpectedRelativeModuleResolutionTrace(host, file2, module1, module3Name, expectedTrace); + // The correct (execution) order for the created files is file2, file1, file4, file3, as that is the (case sensitive) order of the file paths + const expectedTrace = getExpectedRelativeModuleResolutionTrace(host, file2, module1, module3Name); getExpectedRelativeModuleResolutionTrace(host, file2, module2, module4Name, expectedTrace); + getExpectedRelativeModuleResolutionTrace(host, file1, module1, module1Name, expectedTrace); + getExpectedRelativeModuleResolutionTrace(host, file1, module2, module2Name, expectedTrace); getExpectedRelativeModuleResolutionTrace(host, file4, module1, module6Name, expectedTrace); getExpectedRelativeModuleResolutionTrace(host, file4, module2, module2Name, expectedTrace); getExpectedRelativeModuleResolutionTrace(host, file3, module1, module5Name, expectedTrace); @@ -7349,10 +7350,11 @@ namespace ts.projectSystem { const resolutionTrace = createHostModuleResolutionTrace(host); const service = createProjectService(host); service.openClientFile(file1.path); - const expectedTrace = getExpectedNonRelativeModuleResolutionTrace(host, file1, module1, module1Name); - getExpectedNonRelativeModuleResolutionTrace(host, file1, module2, module2Name, expectedTrace); - getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file2, module1, module1Name, getDirectoryPath(file1.path), expectedTrace); - getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file2, module2, module2Name, getDirectoryPath(file1.path), expectedTrace); + // The correct (execution) order for the created files is file2, file1, file4, file3, as that is the (case sensitive) order of the file paths + const expectedTrace = getExpectedNonRelativeModuleResolutionTrace(host, file2, module1, module1Name); + getExpectedNonRelativeModuleResolutionTrace(host, file2, module2, module2Name, expectedTrace); + getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file1, module1, module1Name, getDirectoryPath(file1.path), expectedTrace); + getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file1, module2, module2Name, getDirectoryPath(file1.path), expectedTrace); getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file4, module1, module1Name, `${projectLocation}/product`, expectedTrace); getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file4, module2, module2Name, `${projectLocation}/product`, expectedTrace); getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file3, module1, module1Name, getDirectoryPath(file4.path), expectedTrace); From 1f72a87e5b89c14ba298286dc9162612ec60c8cb Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 7 Mar 2018 15:37:40 -0800 Subject: [PATCH 2/4] Accept affected user test baseline --- tests/baselines/reference/user/chrome-devtools-frontend.log | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/baselines/reference/user/chrome-devtools-frontend.log b/tests/baselines/reference/user/chrome-devtools-frontend.log index 1d046e53073ed..4c8d5b96c44c2 100644 --- a/tests/baselines/reference/user/chrome-devtools-frontend.log +++ b/tests/baselines/reference/user/chrome-devtools-frontend.log @@ -14,7 +14,6 @@ Standard output: ../../../../built/local/lib.dom.d.ts(13705,13): error TS2300: Duplicate identifier 'Window'. ../../../../built/local/lib.es5.d.ts(1328,11): error TS2300: Duplicate identifier 'ArrayLike'. ../../../../built/local/lib.es5.d.ts(1364,6): error TS2300: Duplicate identifier 'Record'. -../../../../node_modules/@types/node/index.d.ts(150,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'module' must be of type '{ [x: string]: any; }', but here has type 'NodeModule'. node_modules/chrome-devtools-frontend/front_end/Runtime.js(43,8): error TS2339: Property '_importScriptPathPrefix' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/Runtime.js(95,28): error TS2339: Property 'response' does not exist on type 'EventTarget'. node_modules/chrome-devtools-frontend/front_end/Runtime.js(147,37): error TS2339: Property '_importScriptPathPrefix' does not exist on type 'Window'. @@ -9017,6 +9016,7 @@ node_modules/chrome-devtools-frontend/front_end/externs.js(336,68): error TS1003 node_modules/chrome-devtools-frontend/front_end/externs.js(338,65): error TS1003: Identifier expected. node_modules/chrome-devtools-frontend/front_end/externs.js(340,31): error TS1003: Identifier expected. node_modules/chrome-devtools-frontend/front_end/externs.js(344,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/externs.js(354,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'module' must be of type 'NodeModule', but here has type '{ [x: string]: any; }'. node_modules/chrome-devtools-frontend/front_end/externs.js(366,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/externs.js(395,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/externs.js(416,14): error TS1110: Type expected. @@ -13084,9 +13084,9 @@ node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1057,39): node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1108,15): error TS2339: Property 'valuesArray' does not exist on type 'Set'. node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1116,15): error TS2339: Property 'firstValue' does not exist on type 'Set'. node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1126,15): error TS2339: Property 'addAll' does not exist on type 'Set'. -node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1127,17): error TS2495: Type 'T[] | Iterable' is not an array type or a string type. +node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1127,17): error TS2495: Type 'Iterable | T[]' is not an array type or a string type. node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1136,15): error TS2339: Property 'containsAll' does not exist on type 'Set'. -node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1137,17): error TS2495: Type 'T[] | Iterable' is not an array type or a string type. +node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1137,17): error TS2495: Type 'Iterable | T[]' is not an array type or a string type. node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1148,15): error TS2339: Property 'remove' does not exist on type 'Map'. node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1155,21): error TS2304: Cannot find name 'VALUE'. node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1157,15): error TS2339: Property 'valuesArray' does not exist on type 'Map'. From bd4df400cd8a47c577e1d3c775c4084a5efdc4a3 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 7 Mar 2018 19:12:02 -0800 Subject: [PATCH 3/4] Per reccomendation, just change matchFiles --- src/compiler/commandLineParser.ts | 62 +++++++------------ src/compiler/core.ts | 5 +- .../unittests/tsserverProjectSystem.ts | 16 +++-- .../user/chrome-devtools-frontend.log | 2 +- 4 files changed, 32 insertions(+), 53 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index c44e7663ff673..b0370620be47b 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -2016,21 +2016,6 @@ namespace ts { return getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions); } - interface WildcardFileInfo { - path: string; - includeIndex: number; - } - - function makeCompareWildcardFileInfo(basePath: string) { - return (a: WildcardFileInfo, b: WildcardFileInfo) => { - return compareValues(a.includeIndex, b.includeIndex) || comparePaths(a.path, b.path, basePath); // Always compare case-sensitive so included files are in the same order on all platforms - }; - } - - function getFilePathFromWildcardFileInfo(info: WildcardFileInfo) { - return info.path; - } - /** * Gets the file names from the provided config file specs that contain, files, include, exclude and * other properties needed to resolve the file names @@ -2054,7 +2039,7 @@ namespace ts { // Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a // file map with a possibly case insensitive key. We use this map to store paths matched // via wildcard, and to handle extension priority. - const wildcardFileMap = createMap(); + const wildcardFileMap = createMap(); const { filesSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories } = spec; @@ -2072,35 +2057,32 @@ namespace ts { } if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) { - for (let i = 0; i < validatedIncludeSpecs.length; i++) { - // We search one include spec at a time to ensure we respect include spec ordering - for (const file of host.readDirectory(basePath, supportedExtensions, validatedExcludeSpecs, [validatedIncludeSpecs[i]], /*depth*/ undefined)) { - // If we have already included a literal or wildcard path with a - // higher priority extension, we should skip this file. - // - // This handles cases where we may encounter both .ts and - // .d.ts (or .js if "allowJs" is enabled) in the same - // directory when they are compilation outputs. - if (hasFileWithHigherPriorityExtension(file, literalFileMap, wildcardFileMap, supportedExtensions, keyMapper)) { - continue; - } + for (const file of host.readDirectory(basePath, supportedExtensions, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined)) { + // If we have already included a literal or wildcard path with a + // higher priority extension, we should skip this file. + // + // This handles cases where we may encounter both .ts and + // .d.ts (or .js if "allowJs" is enabled) in the same + // directory when they are compilation outputs. + if (hasFileWithHigherPriorityExtension(file, literalFileMap, wildcardFileMap, supportedExtensions, keyMapper)) { + continue; + } - // We may have included a wildcard path with a lower priority - // extension due to the user-defined order of entries in the - // "include" array. If there is a lower priority extension in the - // same directory, we should remove it. - removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper); + // We may have included a wildcard path with a lower priority + // extension due to the user-defined order of entries in the + // "include" array. If there is a lower priority extension in the + // same directory, we should remove it. + removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper); - const key = keyMapper(file); - if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) { - wildcardFileMap.set(key, { path: file, includeIndex: i }); - } + const key = keyMapper(file); + if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) { + wildcardFileMap.set(key, file); } } } const literalFiles = arrayFrom(literalFileMap.values()); - const wildcardFiles = map(sort(arrayFrom(wildcardFileMap.values()), makeCompareWildcardFileInfo(basePath)), getFilePathFromWildcardFileInfo); + const wildcardFiles = arrayFrom(wildcardFileMap.values()); return { fileNames: literalFiles.concat(wildcardFiles), wildcardDirectories, @@ -2219,7 +2201,7 @@ namespace ts { * @param extensionPriority The priority of the extension. * @param context The expansion context. */ - function hasFileWithHigherPriorityExtension(file: string, literalFiles: Map, wildcardFiles: Map, extensions: ReadonlyArray, keyMapper: (value: string) => string) { + function hasFileWithHigherPriorityExtension(file: string, literalFiles: Map, wildcardFiles: Map, extensions: ReadonlyArray, keyMapper: (value: string) => string) { const extensionPriority = getExtensionPriority(file, extensions); const adjustedExtensionPriority = adjustExtensionPriority(extensionPriority, extensions); for (let i = ExtensionPriority.Highest; i < adjustedExtensionPriority; i++) { @@ -2241,7 +2223,7 @@ namespace ts { * @param extensionPriority The priority of the extension. * @param context The expansion context. */ - function removeWildcardFilesWithLowerPriorityExtension(file: string, wildcardFiles: Map, extensions: ReadonlyArray, keyMapper: (value: string) => string) { + function removeWildcardFilesWithLowerPriorityExtension(file: string, wildcardFiles: Map, extensions: ReadonlyArray, keyMapper: (value: string) => string) { const extensionPriority = getExtensionPriority(file, extensions); const nextExtensionPriority = getNextLowestExtensionPriority(extensionPriority, extensions); for (let i = nextExtensionPriority; i < extensions.length; i++) { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index d44cbf4a72de4..33cd19d207c98 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2539,7 +2539,6 @@ namespace ts { path = normalizePath(path); currentDirectory = normalizePath(currentDirectory); - const comparer = useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive; const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory); const regexFlag = useCaseSensitiveFileNames ? "" : "i"; @@ -2560,7 +2559,7 @@ namespace ts { function visitDirectory(path: string, absolutePath: string, depth: number | undefined) { const { files, directories } = getFileSystemEntries(path); - for (const current of sort(files, comparer)) { + for (const current of sort(files, compareStringsCaseSensitive)) { const name = combinePaths(path, current); const absoluteName = combinePaths(absolutePath, current); if (extensions && !fileExtensionIsOneOf(name, extensions)) continue; @@ -2583,7 +2582,7 @@ namespace ts { } } - for (const current of sort(directories, comparer)) { + for (const current of sort(directories, compareStringsCaseSensitive)) { const name = combinePaths(path, current); const absoluteName = combinePaths(absolutePath, current); if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) && diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 5b19ff5c2def0..1ad8a594c78c5 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -7313,11 +7313,10 @@ namespace ts.projectSystem { const resolutionTrace = createHostModuleResolutionTrace(host); const service = createProjectService(host); service.openClientFile(file1.path); - // The correct (execution) order for the created files is file2, file1, file4, file3, as that is the (case sensitive) order of the file paths - const expectedTrace = getExpectedRelativeModuleResolutionTrace(host, file2, module1, module3Name); - getExpectedRelativeModuleResolutionTrace(host, file2, module2, module4Name, expectedTrace); - getExpectedRelativeModuleResolutionTrace(host, file1, module1, module1Name, expectedTrace); + const expectedTrace = getExpectedRelativeModuleResolutionTrace(host, file1, module1, module1Name); getExpectedRelativeModuleResolutionTrace(host, file1, module2, module2Name, expectedTrace); + getExpectedRelativeModuleResolutionTrace(host, file2, module1, module3Name, expectedTrace); + getExpectedRelativeModuleResolutionTrace(host, file2, module2, module4Name, expectedTrace); getExpectedRelativeModuleResolutionTrace(host, file4, module1, module6Name, expectedTrace); getExpectedRelativeModuleResolutionTrace(host, file4, module2, module2Name, expectedTrace); getExpectedRelativeModuleResolutionTrace(host, file3, module1, module5Name, expectedTrace); @@ -7350,11 +7349,10 @@ namespace ts.projectSystem { const resolutionTrace = createHostModuleResolutionTrace(host); const service = createProjectService(host); service.openClientFile(file1.path); - // The correct (execution) order for the created files is file2, file1, file4, file3, as that is the (case sensitive) order of the file paths - const expectedTrace = getExpectedNonRelativeModuleResolutionTrace(host, file2, module1, module1Name); - getExpectedNonRelativeModuleResolutionTrace(host, file2, module2, module2Name, expectedTrace); - getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file1, module1, module1Name, getDirectoryPath(file1.path), expectedTrace); - getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file1, module2, module2Name, getDirectoryPath(file1.path), expectedTrace); + const expectedTrace = getExpectedNonRelativeModuleResolutionTrace(host, file1, module1, module1Name); + getExpectedNonRelativeModuleResolutionTrace(host, file1, module2, module2Name, expectedTrace); + getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file2, module1, module1Name, getDirectoryPath(file1.path), expectedTrace); + getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file2, module2, module2Name, getDirectoryPath(file1.path), expectedTrace); getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file4, module1, module1Name, `${projectLocation}/product`, expectedTrace); getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file4, module2, module2Name, `${projectLocation}/product`, expectedTrace); getExpectedNonRelativeModuleResolutionFromCacheTrace(host, file3, module1, module1Name, getDirectoryPath(file4.path), expectedTrace); diff --git a/tests/baselines/reference/user/chrome-devtools-frontend.log b/tests/baselines/reference/user/chrome-devtools-frontend.log index 4c8d5b96c44c2..331637827b34d 100644 --- a/tests/baselines/reference/user/chrome-devtools-frontend.log +++ b/tests/baselines/reference/user/chrome-devtools-frontend.log @@ -14,6 +14,7 @@ Standard output: ../../../../built/local/lib.dom.d.ts(13705,13): error TS2300: Duplicate identifier 'Window'. ../../../../built/local/lib.es5.d.ts(1328,11): error TS2300: Duplicate identifier 'ArrayLike'. ../../../../built/local/lib.es5.d.ts(1364,6): error TS2300: Duplicate identifier 'Record'. +../../../../node_modules/@types/node/index.d.ts(150,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'module' must be of type '{ [x: string]: any; }', but here has type 'NodeModule'. node_modules/chrome-devtools-frontend/front_end/Runtime.js(43,8): error TS2339: Property '_importScriptPathPrefix' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/Runtime.js(95,28): error TS2339: Property 'response' does not exist on type 'EventTarget'. node_modules/chrome-devtools-frontend/front_end/Runtime.js(147,37): error TS2339: Property '_importScriptPathPrefix' does not exist on type 'Window'. @@ -9016,7 +9017,6 @@ node_modules/chrome-devtools-frontend/front_end/externs.js(336,68): error TS1003 node_modules/chrome-devtools-frontend/front_end/externs.js(338,65): error TS1003: Identifier expected. node_modules/chrome-devtools-frontend/front_end/externs.js(340,31): error TS1003: Identifier expected. node_modules/chrome-devtools-frontend/front_end/externs.js(344,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/externs.js(354,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'module' must be of type 'NodeModule', but here has type '{ [x: string]: any; }'. node_modules/chrome-devtools-frontend/front_end/externs.js(366,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/externs.js(395,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/externs.js(416,14): error TS1110: Type expected. From d9b7cf20d757a5d61b7ea18d9d60027f6ba06d88 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 7 Mar 2018 19:33:33 -0800 Subject: [PATCH 4/4] Add test asserting the same order on differing case sensitive platforms --- src/harness/unittests/matchFiles.ts | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/harness/unittests/matchFiles.ts b/src/harness/unittests/matchFiles.ts index bbefd24bb57d6..b2f41ba4fa2fa 100644 --- a/src/harness/unittests/matchFiles.ts +++ b/src/harness/unittests/matchFiles.ts @@ -91,6 +91,18 @@ namespace ts { "c:/dev/g.min.js/.g/g.ts" ]); + const caseInsensitiveOrderingDiffersWithCaseHost = new Utils.MockParseConfigHost(caseInsensitiveBasePath, /*useCaseSensitiveFileNames*/ false, [ + "c:/dev/xylophone.ts", + "c:/dev/Yosemite.ts", + "c:/dev/zebra.ts", + ]); + + const caseSensitiveOrderingDiffersWithCaseHost = new Utils.MockParseConfigHost(caseSensitiveBasePath, /*useCaseSensitiveFileNames*/ true, [ + "/dev/xylophone.ts", + "/dev/Yosemite.ts", + "/dev/zebra.ts", + ]); + function assertParsed(actual: ParsedCommandLine, expected: ParsedCommandLine): void { assert.deepEqual(actual.fileNames, expected.fileNames); assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); @@ -1482,5 +1494,25 @@ namespace ts { validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath); }); }); + + it("can include files in the same order on multiple platforms", () => { + function getExpected(basePath: string): ParsedCommandLine { + return { + options: {}, + errors: [], + fileNames: [ + `${basePath}Yosemite.ts`, // capital always comes before lowercase letters + `${basePath}xylophone.ts`, + `${basePath}zebra.ts` + ], + wildcardDirectories: { + [basePath.slice(0, basePath.length - 1)]: WatchDirectoryFlags.Recursive + }, + }; + } + const json = {}; + validateMatches(getExpected(caseSensitiveBasePath), json, caseSensitiveOrderingDiffersWithCaseHost, caseSensitiveBasePath); + validateMatches(getExpected(caseInsensitiveBasePath), json, caseInsensitiveOrderingDiffersWithCaseHost, caseInsensitiveBasePath); + }); }); }