From f3c5029def53487af1ac0f53a717f4bc6e75fc03 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 3 Apr 2017 23:03:14 -0700 Subject: [PATCH 01/15] Add tests and fix bugs --- .../unittests/tsserverProjectSystem.ts | 61 ++++++++++-- src/server/editorServices.ts | 93 ++++++++++++++++++- src/server/protocol.ts | 2 + src/server/session.ts | 6 ++ 4 files changed, 150 insertions(+), 12 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index b78fa094571..e5b2d325411 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -17,6 +17,30 @@ namespace ts.projectSystem { }) }; + const typeMapList = { + path: "/typeMapList.json", + content: JSON.stringify({ + "jquery": { + // jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js") + "match": "/jquery(-(\\.\\d+)+)?(\\.intellisense)?(\\.min)?\\.js$", + "types": ["jquery"] + }, + "WinJS": { + "match": "^(.*/winjs)/base\\.js$", // If the winjs/base.js file is found.. + "exclude": [["^", 1, "/.*"]], // ..then exclude all files under the winjs folder + "types": ["winjs"] // And fetch the @types package for WinJS + }, + "Office Nuget": { + "match": "^(.*/1/office)/excel\\.debug\\.js$", // Office NuGet package is installed under a "1/office" folder + "exclude": [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it + "types": ["office"] // @types package to fetch instead + }, + "Minified files": { + "match": "^.*\\.min\\.js$" // Catch-all for minified files. Default exclude is the matched file. + } + }) + }; + export interface PostExecAction { readonly success: boolean; readonly callback: TI.RequestCompletedAction; @@ -1445,6 +1469,25 @@ namespace ts.projectSystem { checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]); }); + it("ignores files excluded by the safe type list", () => { + const file1 = { + path: "/a/b/f1.ts", + content: "export let x = 5" + }; + const office = { + path: "lib/1/office/excel.debug.js", + content: "whoa do @@ not parse me ok thanks!!!" + }; + const host = createServerHost([typeMapList, file1, office]); + const projectService = createProjectService(host); + projectService.loadSafeList(typeMapList.path); + + projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, office.path]) }); + const proj = projectService.externalProjects[0]; + assert.deepEqual(proj.getFileNames(true), [file1.path]); + assert.deepEqual(proj.getTypeAcquisition().include, ["office"]); + }); + it("open file become a part of configured project if it is referenced from root file", () => { const file1 = { path: "/a/b/f1.ts", @@ -1695,7 +1738,7 @@ namespace ts.projectSystem { checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]); }); - it ("loading files with correct priority", () => { + it("loading files with correct priority", () => { const f1 = { path: "/a/main.ts", content: "let x = 1" @@ -1720,14 +1763,14 @@ namespace ts.projectSystem { }); projectService.openClientFile(f1.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [ f1.path ]); + checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]); projectService.closeClientFile(f1.path); projectService.openClientFile(f2.path); projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 }); - checkProjectActualFiles(projectService.configuredProjects[0], [ f1.path ]); - checkProjectActualFiles(projectService.inferredProjects[0], [ f2.path ]); + checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]); + checkProjectActualFiles(projectService.inferredProjects[0], [f2.path]); }); it("tsconfig script block support", () => { @@ -1845,7 +1888,7 @@ namespace ts.projectSystem { // #3. Ensure no errors when compiler options aren't specified const config3 = { path: "/a/b/tsconfig.json", - content: JSON.stringify({ }) + content: JSON.stringify({}) }; host = createServerHost([file1, file2, config3, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") }); @@ -3381,13 +3424,13 @@ namespace ts.projectSystem { assert.equal((response)[0].projectUsesOutFile, expectedUsesOutFile, "usesOutFile"); } - it ("projectUsesOutFile should not be returned if not set", () => { + it("projectUsesOutFile should not be returned if not set", () => { test({}, /*expectedUsesOutFile*/ false); }); - it ("projectUsesOutFile should be true if outFile is set", () => { + it("projectUsesOutFile should be true if outFile is set", () => { test({ outFile: "/a/out.js" }, /*expectedUsesOutFile*/ true); }); - it ("projectUsesOutFile should be true if out is set", () => { + it("projectUsesOutFile should be true if out is set", () => { test({ out: "/a/out.js" }, /*expectedUsesOutFile*/ true); }); }); @@ -3468,7 +3511,7 @@ namespace ts.projectSystem { const cancellationToken = new TestServerCancellationToken(); const host = createServerHost([f1, config]); - const session = createSession(host, /*typingsInstaller*/ undefined, () => {}, cancellationToken); + const session = createSession(host, /*typingsInstaller*/ undefined, () => { }, cancellationToken); { session.executeCommandSeq({ command: "open", diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 30c7a87dc74..78108debef7 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -35,6 +35,10 @@ namespace ts.server { (event: ProjectServiceEvent): void; } + export interface SafeList { + [name: string]: { match: RegExp, exclude?: Array>, types?: string[] }; + } + function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions: CommandLineOption[]): Map> { const map: Map> = createMap>(); for (const option of commandLineOptions) { @@ -259,6 +263,7 @@ namespace ts.server { private readonly throttledOperations: ThrottledOperations; private readonly hostConfiguration: HostConfiguration; + private static safelist: SafeList = {}; private changedFiles: ScriptInfo[]; @@ -284,8 +289,6 @@ namespace ts.server { this.typingsCache = new TypingsCache(this.typingsInstaller); - // ts.disableIncrementalParsing = true; - this.hostConfiguration = { formatCodeOptions: getDefaultFormatCodeSettings(this.host), hostInfo: "Unknown host", @@ -831,7 +834,7 @@ namespace ts.server { getDirectoryPath(configFilename), /*existingOptions*/ {}, configFilename, - /*resolutionStack*/ [], + /*resolutionStack*/[], this.hostConfiguration.extraFileExtensions); if (parsedCommandLine.errors.length) { @@ -1399,6 +1402,87 @@ namespace ts.server { this.refreshInferredProjects(); } + /** Makes a filename safe to insert in a RegExp */ + private static filenameEscapeRegexp = /[-\/\\^$*+?.()|[\]{}]/g; + private static escapeFilenameForRegex(filename: string) { + return filename.replace(this.filenameEscapeRegexp, "\\$&"); + } + + loadSafeList(fileName: string): void { + const raw: SafeList = JSON.parse(this.host.readFile(fileName, "utf-8")); + // Parse the regexps + for (const k of Object.keys(raw)) { + raw[k].match = new RegExp(raw[k].match as {} as string, "gi"); + } + // raw is now fixed and ready + ProjectService.safelist = raw; + } + + applySafeList(proj: protocol.ExternalProject): void { + const { rootFiles, typeAcquisition } = proj; + const types = (typeAcquisition && typeAcquisition.include) || []; + + const excludeRules: string[] = []; + + for (const name of Object.keys(ProjectService.safelist)) { + const rule = ProjectService.safelist[name]; + for (const root of rootFiles) { + if (rule.match.test(root.fileName)) { + this.logger.info(`Excluding files based on rule ${name}`); + + // If the file matches, collect its types packages and exclude rules + if (rule.types) { + for (const type of rule.types) { + if (types.indexOf(type) < 0) { + types.push(type); + } + } + } + + if (rule.exclude) { + for (const exclude of rule.exclude) { + const processedRule = root.fileName.replace(rule.match, (...groups: Array) => { + return exclude.map(groupNumberOrString => { + // RegExp group numbers are 1-based, but the first element in groups + // is actually the original string, so it all works out in the end. + if (typeof groupNumberOrString === "number") { + if (typeof groups[groupNumberOrString] !== "string") { + // Specification was wrong - exclude nothing! + this.logger.info(`Incorrect RegExp specification in safelist rule ${name} - not enough groups`); + // * can't appear in a filename; escape it because it's feeding into a RegExp + return "\\*"; + } + return ProjectService.escapeFilenameForRegex(groups[groupNumberOrString]); + } + return groupNumberOrString; + }).join(""); + }); + + if (excludeRules.indexOf(processedRule) == -1) { + excludeRules.push(processedRule); + } + } + } + else { + // If not rules listed, add the default rule to exclude the matched file + if (excludeRules.indexOf(root.fileName) < 0) { + excludeRules.push(root.fileName); + } + } + } + } + + // Copy back this field into the project if needed + if (types.length > 0) { + proj.typeAcquisition = proj.typeAcquisition || { }; + proj.typeAcquisition.include = types; + } + } + + const excludeRegexes = excludeRules.map(e => new RegExp(e, "i")); + proj.rootFiles = proj.rootFiles.filter(file => !excludeRegexes.some(re => re.test(file.fileName))); + } + openExternalProject(proj: protocol.ExternalProject, suppressRefreshOfInferredProjects = false): void { // typingOptions has been deprecated and is only supported for backward compatibility // purposes. It should be removed in future releases - use typeAcquisition instead. @@ -1406,6 +1490,9 @@ namespace ts.server { const typeAcquisition = convertEnableAutoDiscoveryToEnable(proj.typingOptions); proj.typeAcquisition = typeAcquisition; } + + this.applySafeList(proj); + let tsConfigFiles: NormalizedPath[]; const rootFiles: protocol.ExternalFile[] = []; for (const file of proj.rootFiles) { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 0bf13df7f4b..bc96099f5e1 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -91,8 +91,10 @@ namespace ts.server.protocol { /* @internal */ export type BreakpointStatement = "breakpointStatement"; export type CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects"; + export type LoadTypesMap = "loadTypesMap"; export type GetCodeFixes = "getCodeFixes"; /* @internal */ + /* @internal */ export type GetCodeFixesFull = "getCodeFixes-full"; export type GetSupportedCodeFixes = "getSupportedCodeFixes"; } diff --git a/src/server/session.ts b/src/server/session.ts index 4cdddc831a1..97c221a8add 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -186,6 +186,7 @@ namespace ts.server { /* @internal */ export const BreakpointStatement: protocol.CommandTypes.BreakpointStatement = "breakpointStatement"; export const CompilerOptionsForInferredProjects: protocol.CommandTypes.CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects"; + export const LoadTypesMap: protocol.CommandTypes.LoadTypesMap = "loadTypesMap"; export const GetCodeFixes: protocol.CommandTypes.GetCodeFixes = "getCodeFixes"; /* @internal */ export const GetCodeFixesFull: protocol.CommandTypes.GetCodeFixesFull = "getCodeFixes-full"; @@ -1765,6 +1766,11 @@ namespace ts.server { this.setCompilerOptionsForInferredProjects(request.arguments); return this.requiredResponse(true); }, + [CommandNames.LoadTypesMap]: (request: protocol.FileRequest) => { + const loadArgs = request.arguments; + this.projectService.loadSafeList(loadArgs.file); + return this.notRequired(); + }, [CommandNames.ProjectInfo]: (request: protocol.ProjectInfoRequest) => { return this.requiredResponse(this.getProjectInfo(request.arguments)); }, From 54b1c34a4435d0f9c6581f241111b9d82914654d Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 4 Apr 2017 10:17:17 -0700 Subject: [PATCH 02/15] Fix failing test --- src/harness/unittests/typingsInstaller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index d6f8a2d01fc..af95874a32c 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -381,12 +381,12 @@ namespace ts.projectSystem { const p = projectService.externalProjects[0]; projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(p, [file1.path, file2.path]); + checkProjectActualFiles(p, [file2.path]); installer.checkPendingCommands(/*expectedCount*/ 0); checkNumberOfProjects(projectService, { externalProjects: 1 }); - checkProjectActualFiles(p, [file1.path, file2.path]); + checkProjectActualFiles(p, [file2.path]); }); it("external project - with type acquisition, with only js, d.ts files", () => { From a4c2f78b75e29486f66f4270968b24790d07215f Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 5 Apr 2017 09:24:35 -0700 Subject: [PATCH 03/15] Update tsserverProjectSystem.ts --- src/harness/unittests/tsserverProjectSystem.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index e5b2d325411..fb91aa9a431 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -22,7 +22,7 @@ namespace ts.projectSystem { content: JSON.stringify({ "jquery": { // jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js") - "match": "/jquery(-(\\.\\d+)+)?(\\.intellisense)?(\\.min)?\\.js$", + "match": "/jquery(-(\\.?\\d+)+)?(\\.intellisense)?(\\.min)?\\.js$", "types": ["jquery"] }, "WinJS": { @@ -3793,4 +3793,4 @@ namespace ts.projectSystem { assert.isUndefined(project.getCompilerOptions().maxNodeModuleJsDepth); }); }); -} \ No newline at end of file +} From 376cea648ef31136ef0666b3e4ffdedf7881ef44 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 5 Apr 2017 12:56:14 -0700 Subject: [PATCH 04/15] Allow resetting so tests pass --- .../unittests/tsserverProjectSystem.ts | 41 +++++++------------ src/server/editorServices.ts | 24 ++++++++++- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index fb91aa9a431..370c1a4cf22 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -17,27 +17,13 @@ namespace ts.projectSystem { }) }; - const typeMapList = { + const customSafeList = { path: "/typeMapList.json", content: JSON.stringify({ - "jquery": { - // jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js") - "match": "/jquery(-(\\.?\\d+)+)?(\\.intellisense)?(\\.min)?\\.js$", - "types": ["jquery"] + "quack": { + "match": "/duckquack-(\\d+)\\.min\\.js", + "types": ["duck-types"] }, - "WinJS": { - "match": "^(.*/winjs)/base\\.js$", // If the winjs/base.js file is found.. - "exclude": [["^", 1, "/.*"]], // ..then exclude all files under the winjs folder - "types": ["winjs"] // And fetch the @types package for WinJS - }, - "Office Nuget": { - "match": "^(.*/1/office)/excel\\.debug\\.js$", // Office NuGet package is installed under a "1/office" folder - "exclude": [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it - "types": ["office"] // @types package to fetch instead - }, - "Minified files": { - "match": "^.*\\.min\\.js$" // Catch-all for minified files. Default exclude is the matched file. - } }) }; @@ -1475,17 +1461,20 @@ namespace ts.projectSystem { content: "export let x = 5" }; const office = { - path: "lib/1/office/excel.debug.js", + path: "/lib/duckquack-3.min.js", content: "whoa do @@ not parse me ok thanks!!!" }; - const host = createServerHost([typeMapList, file1, office]); + const host = createServerHost([customSafeList, file1, office]); const projectService = createProjectService(host); - projectService.loadSafeList(typeMapList.path); - - projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, office.path]) }); - const proj = projectService.externalProjects[0]; - assert.deepEqual(proj.getFileNames(true), [file1.path]); - assert.deepEqual(proj.getTypeAcquisition().include, ["office"]); + projectService.loadSafeList(customSafeList.path); + try { + projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, office.path]) }); + const proj = projectService.externalProjects[0]; + assert.deepEqual(proj.getFileNames(true), [file1.path]); + assert.deepEqual(proj.getTypeAcquisition().include, ["duck-types"]); + } finally { + projectService.resetSafeList(); + } }); it("open file become a part of configured project if it is referenced from root file", () => { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 78108debef7..3d1406f3e43 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -61,6 +61,24 @@ namespace ts.server { "smart": IndentStyle.Smart }); + const defaultTypeSafeList: SafeList = { + "jquery": { + // jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js") + "match": /jquery(-(\.?\d+)+)?(\.intellisense)?(\.min)?\.js$/gi, + "types": ["jquery"] + }, + "WinJS": { + "match": /^(.*\/winjs)\/base\.js$/gi, // If the winjs/base.js file is found.. + "exclude": [["^", 1, "/.*"]], // ..then exclude all files under the winjs folder + "types": ["winjs"] // And fetch the @types package for WinJS + }, + "Office Nuget": { + "match": /^(.*\/1\/office)\/excel\.debug\.js$/gi, // Office NuGet package is installed under a "1/office" folder + "exclude": [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it + "types": ["office"] // @types package to fetch instead + } + }; + export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings { if (typeof protocolOptions.indentStyle === "string") { protocolOptions.indentStyle = indentStyle.get(protocolOptions.indentStyle.toLowerCase()); @@ -263,7 +281,7 @@ namespace ts.server { private readonly throttledOperations: ThrottledOperations; private readonly hostConfiguration: HostConfiguration; - private static safelist: SafeList = {}; + private static safelist: SafeList = defaultTypeSafeList; private changedFiles: ScriptInfo[]; @@ -1408,6 +1426,10 @@ namespace ts.server { return filename.replace(this.filenameEscapeRegexp, "\\$&"); } + resetSafeList(): void { + ProjectService.safelist = defaultTypeSafeList; + } + loadSafeList(fileName: string): void { const raw: SafeList = JSON.parse(this.host.readFile(fileName, "utf-8")); // Parse the regexps From 125c012c8d3e1ecdee9b264abe6854e1fa9bb100 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 5 Apr 2017 13:13:23 -0700 Subject: [PATCH 05/15] Lint --- src/harness/unittests/tsserverProjectSystem.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 370c1a4cf22..ccd46004540 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1470,7 +1470,7 @@ namespace ts.projectSystem { try { projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, office.path]) }); const proj = projectService.externalProjects[0]; - assert.deepEqual(proj.getFileNames(true), [file1.path]); + assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), [file1.path]); assert.deepEqual(proj.getTypeAcquisition().include, ["duck-types"]); } finally { projectService.resetSafeList(); From c164730a01719c78268767704e121ca383551aa6 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 6 Apr 2017 12:39:25 -0700 Subject: [PATCH 06/15] Add Kendo; fix Office --- src/server/editorServices.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 3d1406f3e43..21330fb319c 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -72,7 +72,15 @@ namespace ts.server { "exclude": [["^", 1, "/.*"]], // ..then exclude all files under the winjs folder "types": ["winjs"] // And fetch the @types package for WinJS }, - "Office Nuget": { + "Kendo": { + "match": /^(.*\/kendo\/.+\.js$/gi, + "exclude": [["^", 1, "/.*"]] + }, + "Office Loc Files": { + "match": /^(.*\/office\/1\/\w\w-\w\w\/).+\.js$/gi, // Office NuGet package is installed under a "office/1" folder + "exclude": [["^", 1, "/.*"]] // Exclude that whole folder if the file indicated above is found in it + }, + "Office Nuget": { // TODO this one "match": /^(.*\/1\/office)\/excel\.debug\.js$/gi, // Office NuGet package is installed under a "1/office" folder "exclude": [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it "types": ["office"] // @types package to fetch instead From 857b762edde9c72ad8fcc22acae5f6e34f0f1cd2 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 6 Apr 2017 12:50:22 -0700 Subject: [PATCH 07/15] Fixes --- src/server/editorServices.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 21330fb319c..12b3f84e050 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -64,24 +64,20 @@ namespace ts.server { const defaultTypeSafeList: SafeList = { "jquery": { // jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js") - "match": /jquery(-(\.?\d+)+)?(\.intellisense)?(\.min)?\.js$/gi, + "match": /jquery(-(\.?\d+)+)?(\.intellisense)?(\.min)?\.js$/i, "types": ["jquery"] }, "WinJS": { - "match": /^(.*\/winjs)\/base\.js$/gi, // If the winjs/base.js file is found.. + "match": /^(.*\/winjs)\/base\.js$/i, // If the winjs/base.js file is found.. "exclude": [["^", 1, "/.*"]], // ..then exclude all files under the winjs folder "types": ["winjs"] // And fetch the @types package for WinJS }, "Kendo": { - "match": /^(.*\/kendo\/.+\.js$/gi, + "match": /^(.*\/kendo\/.+\.js$/i, "exclude": [["^", 1, "/.*"]] }, - "Office Loc Files": { - "match": /^(.*\/office\/1\/\w\w-\w\w\/).+\.js$/gi, // Office NuGet package is installed under a "office/1" folder - "exclude": [["^", 1, "/.*"]] // Exclude that whole folder if the file indicated above is found in it - }, - "Office Nuget": { // TODO this one - "match": /^(.*\/1\/office)\/excel\.debug\.js$/gi, // Office NuGet package is installed under a "1/office" folder + "Office Nuget": { + "match": /^(.*\/1\/office)\/excel\.debug\.js$/i, // Office NuGet package is installed under a "1/office" folder "exclude": [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it "types": ["office"] // @types package to fetch instead } From 439f1c77bd5a152f4453dca2a13a8b8e0c7e23e5 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 6 Apr 2017 13:19:22 -0700 Subject: [PATCH 08/15] Fix regex for real this time --- src/server/editorServices.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 12b3f84e050..1dbf52b56a9 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -68,16 +68,20 @@ namespace ts.server { "types": ["jquery"] }, "WinJS": { - "match": /^(.*\/winjs)\/base\.js$/i, // If the winjs/base.js file is found.. + // e.g. c:/temp/UWApp1/lib/winjs-4.0.1/js/base.js + "match": /^(.*\/winjs-[.\d]+)\/js\/base\.js$/i, // If the winjs/base.js file is found.. "exclude": [["^", 1, "/.*"]], // ..then exclude all files under the winjs folder "types": ["winjs"] // And fetch the @types package for WinJS }, "Kendo": { - "match": /^(.*\/kendo\/.+\.js$/i, - "exclude": [["^", 1, "/.*"]] + // e.g. /Kendo3/wwwroot/lib/kendo/kendo.all.min.js + "match": /^(.*\/kendo)\/kendo\.all\.min\.js$/i, + "exclude": [["^", 1, "/.*"]], + "types": ["kendo-ui"] }, "Office Nuget": { - "match": /^(.*\/1\/office)\/excel\.debug\.js$/i, // Office NuGet package is installed under a "1/office" folder + // e.g. /scripts/Office/1/excel-15.debug.js + "match": /^(.*\/office\/1)\/excel-\d+\.debug\.js$/i, // Office NuGet package is installed under a "1/office" folder "exclude": [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it "types": ["office"] // @types package to fetch instead } From 47cf7caf6e08852690058472d480cf10a4945f96 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 7 Apr 2017 12:49:46 -0700 Subject: [PATCH 09/15] Fix path escaping and slash normalization --- src/server/editorServices.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 1dbf52b56a9..7dc17a385d3 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1454,10 +1454,12 @@ namespace ts.server { const excludeRules: string[] = []; + const normalizedNames = rootFiles.map(f => normalizeSlashes(f.fileName)); + for (const name of Object.keys(ProjectService.safelist)) { const rule = ProjectService.safelist[name]; - for (const root of rootFiles) { - if (rule.match.test(root.fileName)) { + for (const root of normalizedNames) { + if (rule.match.test(root)) { this.logger.info(`Excluding files based on rule ${name}`); // If the file matches, collect its types packages and exclude rules @@ -1471,7 +1473,7 @@ namespace ts.server { if (rule.exclude) { for (const exclude of rule.exclude) { - const processedRule = root.fileName.replace(rule.match, (...groups: Array) => { + const processedRule = root.replace(rule.match, (...groups: Array) => { return exclude.map(groupNumberOrString => { // RegExp group numbers are 1-based, but the first element in groups // is actually the original string, so it all works out in the end. @@ -1488,15 +1490,16 @@ namespace ts.server { }).join(""); }); - if (excludeRules.indexOf(processedRule) == -1) { + if (excludeRules.indexOf(processedRule) === -1) { excludeRules.push(processedRule); } } } else { // If not rules listed, add the default rule to exclude the matched file - if (excludeRules.indexOf(root.fileName) < 0) { - excludeRules.push(root.fileName); + const escaped = ProjectService.escapeFilenameForRegex(root); + if (excludeRules.indexOf(escaped) < 0) { + excludeRules.push(escaped); } } } @@ -1510,7 +1513,7 @@ namespace ts.server { } const excludeRegexes = excludeRules.map(e => new RegExp(e, "i")); - proj.rootFiles = proj.rootFiles.filter(file => !excludeRegexes.some(re => re.test(file.fileName))); + proj.rootFiles = proj.rootFiles.filter((_file, index) => !excludeRegexes.some(re => re.test(normalizedNames[index]))); } openExternalProject(proj: protocol.ExternalProject, suppressRefreshOfInferredProjects = false): void { From 7320891933fadb8d41d9115f437fe4b8636a671c Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 7 Apr 2017 13:13:39 -0700 Subject: [PATCH 10/15] boolean-trivia lint rule: Lint for null/undefined too --- Gulpfile.ts | 2 +- scripts/tslint/booleanTriviaRule.ts | 50 ++++++++++++++----- src/compiler/binder.ts | 10 ++-- src/compiler/checker.ts | 14 +++--- src/compiler/core.ts | 2 +- src/compiler/parser.ts | 2 +- src/compiler/program.ts | 2 +- src/compiler/scanner.ts | 4 +- src/compiler/sys.ts | 2 +- src/compiler/transformers/destructuring.ts | 2 +- src/compiler/transformers/es2015.ts | 2 +- src/harness/fourslash.ts | 2 +- src/harness/harnessLanguageService.ts | 2 +- src/harness/sourceMapRecorder.ts | 2 +- src/harness/unittests/matchFiles.ts | 22 ++++---- src/harness/unittests/moduleResolution.ts | 6 +-- src/harness/unittests/printer.ts | 2 + .../unittests/reuseProgramStructure.ts | 12 ++--- .../unittests/tsserverProjectSystem.ts | 2 +- src/harness/virtualFileSystem.ts | 2 +- src/server/server.ts | 7 ++- src/server/session.ts | 5 +- src/services/formatting/formatting.ts | 2 +- src/services/pathCompletions.ts | 2 +- 24 files changed, 92 insertions(+), 68 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 7b8c8f015a7..7a3cbb2538f 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -775,7 +775,7 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo }); const finalMap = chain.apply(); file.sourceMap = finalMap; - next(undefined, file); + next(/*err*/ undefined, file); }); })) .pipe(sourcemaps.write(".", { includeContent: false })) diff --git a/scripts/tslint/booleanTriviaRule.ts b/scripts/tslint/booleanTriviaRule.ts index 25d001ed9cd..ee5f855e864 100644 --- a/scripts/tslint/booleanTriviaRule.ts +++ b/scripts/tslint/booleanTriviaRule.ts @@ -8,37 +8,63 @@ export class Rule extends Lint.Rules.AbstractRule { } function walk(ctx: Lint.WalkContext): void { - ts.forEachChild(ctx.sourceFile, recur); - function recur(node: ts.Node): void { + ts.forEachChild(ctx.sourceFile, function recur(node: ts.Node): void { if (node.kind === ts.SyntaxKind.CallExpression) { checkCall(node as ts.CallExpression); } ts.forEachChild(node, recur); - } + }); function checkCall(node: ts.CallExpression): void { for (const arg of node.arguments) { - if (arg.kind !== ts.SyntaxKind.TrueKeyword && arg.kind !== ts.SyntaxKind.FalseKeyword) { - continue; + switch (arg.kind) { + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.NullKeyword: + break; + case ts.SyntaxKind.Identifier: + if ((arg as ts.Identifier).originalKeywordKind !== ts.SyntaxKind.UndefinedKeyword) { + continue; + } + break; + default: + continue; } if (node.expression.kind === ts.SyntaxKind.PropertyAccessExpression) { - const methodName = (node.expression as ts.PropertyAccessExpression).name.text + const methodName = (node.expression as ts.PropertyAccessExpression).name.text; // Skip certain method names whose parameter names are not informative - if (methodName === 'set' || - methodName === 'equal' || - methodName === 'fail' || - methodName === 'isTrue' || - methodName === 'assert') { + if (methodName.indexOf("set") === 0) { continue; } + switch (methodName) { + case "apply": + case "assert": + case "call": + case "equal": + case "fail": + case "isTrue": + case "output": + case "stringify": + continue; + } } else if (node.expression.kind === ts.SyntaxKind.Identifier) { const functionName = (node.expression as ts.Identifier).text; // Skip certain function names whose parameter names are not informative - if (functionName === 'assert') { + if (functionName.indexOf("set") === 0) { continue; } + switch (functionName) { + case "assert": + case "contains": + case "createAnonymousType": + case "createImportSpecifier": + case "createProperty": + case "createSignature": + case "resolveName": + continue; + } } const ranges = ts.getLeadingCommentRanges(arg.getFullText(), 0); diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4ec65bfce1c..2477e909705 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -418,7 +418,7 @@ namespace ts { return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); } else { - return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); + return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } } else { @@ -447,13 +447,13 @@ namespace ts { (symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) | (symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) | (symbolFlags & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0); - const local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes); + const local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes); local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); node.localSymbol = local; return local; } else { - return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); + return declareSymbol(container.locals, /*parent*/undefined, node, symbolFlags, symbolExcludes); } } } @@ -1545,7 +1545,7 @@ namespace ts { function declareSourceFileMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { return isExternalModule(file) ? declareModuleMember(node, symbolFlags, symbolExcludes) - : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes); + : declareSymbol(file.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean { @@ -1721,7 +1721,7 @@ namespace ts { blockScopeContainer.locals = createMap(); addToContainerChain(blockScopeContainer); } - declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes); + declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d7acedd663d..343dc724286 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4564,7 +4564,7 @@ namespace ts { // The outer type parameters are those defined by enclosing generic classes, methods, or functions. function getOuterTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] { const declaration = symbol.flags & SymbolFlags.Class ? symbol.valueDeclaration : getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration); - return appendOuterTypeParameters(undefined, declaration); + return appendOuterTypeParameters(/*typeParameters*/ undefined, declaration); } // The local type parameters are the combined set of type parameters from all declarations of the class, @@ -7702,7 +7702,7 @@ namespace ts { } function createTypeEraser(sources: Type[]): TypeMapper { - return createTypeMapper(sources, undefined); + return createTypeMapper(sources, /*targets*/ undefined); } /** @@ -8418,7 +8418,7 @@ namespace ts { } } if (source.flags & TypeFlags.StructuredOrTypeVariable || target.flags & TypeFlags.StructuredOrTypeVariable) { - return checkTypeRelatedTo(source, target, relation, undefined, undefined, undefined); + return checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined); } return false; } @@ -13665,7 +13665,7 @@ namespace ts { const links = getNodeLinks(node); if (!links.resolvedJsxElementAttributesType) { const elemClassType = getJsxGlobalElementClassType(); - return links.resolvedJsxElementAttributesType = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, undefined, elemClassType); + return links.resolvedJsxElementAttributesType = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, /*elementType*/ undefined, elemClassType); } return links.resolvedJsxElementAttributesType; } @@ -15717,7 +15717,7 @@ namespace ts { const parameter = signature.thisParameter; if (!parameter || parameter.valueDeclaration && !(parameter.valueDeclaration).type) { if (!parameter) { - signature.thisParameter = createSymbolWithType(context.thisParameter, undefined); + signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined); } assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper, checkMode); } @@ -17300,7 +17300,7 @@ namespace ts { Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter); } else { - const leadingError = chainDiagnosticMessages(undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); + const leadingError = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); checkTypeAssignableTo(typePredicate.type, getTypeOfNode(parent.parameters[typePredicate.parameterIndex]), node.type, @@ -20507,7 +20507,7 @@ namespace ts { const typeName1 = typeToString(existing.containingType); const typeName2 = typeToString(base); - let errorInfo = chainDiagnosticMessages(undefined, Diagnostics.Named_property_0_of_types_1_and_2_are_not_identical, symbolToString(prop), typeName1, typeName2); + let errorInfo = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Named_property_0_of_types_1_and_2_are_not_identical, symbolToString(prop), typeName1, typeName2); errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2); diagnostics.add(createDiagnosticForNodeFromMessageChain(typeNode, errorInfo)); } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 1cca48fd106..ac354e24eda 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -30,7 +30,7 @@ namespace ts { /** Create a MapLike with good performance. */ function createDictionaryObject(): MapLike { - const map = Object.create(null); // tslint:disable-line:no-null-keyword + const map = Object.create(/*prototype*/ null); // tslint:disable-line:no-null-keyword // Using 'delete' on an object causes V8 to put the object in dictionary mode. // This disables creation of hidden classes, which are expensive when an object is diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a82d5b02b44..c6fe2f79992 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2130,7 +2130,7 @@ namespace ts { function parseParameter(): ParameterDeclaration { const node = createNode(SyntaxKind.Parameter); if (token() === SyntaxKind.ThisKeyword) { - node.name = createIdentifier(/*isIdentifier*/true, undefined); + node.name = createIdentifier(/*isIdentifier*/ true); node.type = parseParameterType(); return finishNode(node); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 31fc665649a..ae15ece684e 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1218,7 +1218,7 @@ namespace ts { && !file.isDeclarationFile) { // synthesize 'import "tslib"' declaration const externalHelpersModuleReference = createLiteral(externalHelpersModuleNameText); - const importDecl = createImportDeclaration(undefined, undefined, undefined); + const importDecl = createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined); externalHelpersModuleReference.parent = importDecl; importDecl.parent = file; imports = [externalHelpersModuleReference]; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 7b6e0c09db4..41c48700a9a 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -735,11 +735,11 @@ namespace ts { } export function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined { - return reduceEachLeadingCommentRange(text, pos, appendCommentRange, undefined, undefined); + return reduceEachLeadingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined); } export function getTrailingCommentRanges(text: string, pos: number): CommentRange[] | undefined { - return reduceEachTrailingCommentRange(text, pos, appendCommentRange, undefined, undefined); + return reduceEachTrailingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined); } /** Optionally, get the shebang */ diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index b65370076d2..7074abd3436 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -232,7 +232,7 @@ namespace ts { try { fd = _fs.openSync(fileName, "w"); - _fs.writeSync(fd, data, undefined, "utf8"); + _fs.writeSync(fd, data, /*position*/ undefined, "utf8"); } finally { if (fd !== undefined) { diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index bbc79270c77..cd3b8bdce6b 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -518,7 +518,7 @@ namespace ts { } return createCall( getHelperName("__rest"), - undefined, + /*typeArguments*/ undefined, [ value, setTextRange( diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index a3e34693259..aabb452e90d 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -3109,7 +3109,7 @@ namespace ts { const ancestorFacts = enterSubtree(HierarchyFacts.BlockScopeExcludes, HierarchyFacts.BlockScopeIncludes); let updated: CatchClause; if (isBindingPattern(node.variableDeclaration.name)) { - const temp = createTempVariable(undefined); + const temp = createTempVariable(/*recordTempVariable*/ undefined); const newVariableDeclaration = createVariableDeclaration(temp); setTextRange(newVariableDeclaration, node.variableDeclaration); const vars = flattenDestructuringBinding( diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 32963b30a0a..db05f9f1ddf 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3191,7 +3191,7 @@ ${code} } // Add the remaining text - flush(undefined); + flush(/*lastSafeCharIndex*/ undefined); if (openRanges.length > 0) { const openRange = openRanges[0]; diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 14508640faf..b736ca1be72 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -795,7 +795,7 @@ namespace Harness.LanguageService { function makeDefaultProxy(info: ts.server.PluginCreateInfo) { // tslint:disable-next-line:no-null-keyword - const proxy = Object.create(null); + const proxy = Object.create(/*prototype*/ null); const langSvc: any = info.languageService; for (const k of Object.keys(langSvc)) { proxy[k] = function () { diff --git a/src/harness/sourceMapRecorder.ts b/src/harness/sourceMapRecorder.ts index 0ef9f7eb49f..aa66d713e1c 100644 --- a/src/harness/sourceMapRecorder.ts +++ b/src/harness/sourceMapRecorder.ts @@ -422,7 +422,7 @@ namespace Harness.SourceMapRecorder { const jsFileText = getTextOfLine(currentJsLine, jsLineMap, jsFile.code); if (prevEmittedCol < jsFileText.length) { // There is remaining text on this line that will be part of next source span so write marker that continues - writeSourceMapMarker(undefined, spansOnSingleLine.length, /*endColumn*/ jsFileText.length, /*endContinues*/ true); + writeSourceMapMarker(/*currentSpan*/ undefined, spansOnSingleLine.length, /*endColumn*/ jsFileText.length, /*endContinues*/ true); } // Emit Source text diff --git a/src/harness/unittests/matchFiles.ts b/src/harness/unittests/matchFiles.ts index 0a450c50151..652379abb31 100644 --- a/src/harness/unittests/matchFiles.ts +++ b/src/harness/unittests/matchFiles.ts @@ -212,7 +212,7 @@ namespace ts { fileNames: [], wildcardDirectories: {}, }; - const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath); + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); assertParsed(actual, expected); }); it("with missing files are excluded", () => { @@ -231,7 +231,7 @@ namespace ts { fileNames: [], wildcardDirectories: {}, }; - const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath); + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); assertParsed(actual, expected); }); it("with literal excludes", () => { @@ -584,7 +584,7 @@ namespace ts { "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; - const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath); + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); assertParsed(actual, expected); }); it("always include literal files", () => { @@ -728,7 +728,7 @@ namespace ts { "c:/dev/js": ts.WatchDirectoryFlags.None } }; - const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath); + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); assertParsed(actual, expected); }); it("include .js files when allowJs=true", () => { @@ -846,7 +846,7 @@ namespace ts { fileNames: [], wildcardDirectories: {} }; - const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath); + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); assertParsed(actual, expected); }); it("include files with .. in their name", () => { @@ -1087,7 +1087,7 @@ namespace ts { fileNames: [], wildcardDirectories: {} }; - const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath); + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); assertParsed(actual, expected); }); it("in excludes", () => { @@ -1108,7 +1108,7 @@ namespace ts { fileNames: [], wildcardDirectories: {} }; - const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath); + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); assertParsed(actual, expected); }); }); @@ -1129,7 +1129,7 @@ namespace ts { fileNames: [], wildcardDirectories: {} }; - const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath); + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); assertParsed(actual, expected); }); it("in excludes", () => { @@ -1178,7 +1178,7 @@ namespace ts { fileNames: [], wildcardDirectories: {} }; - const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath); + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); assertParsed(actual, expected); }); @@ -1198,7 +1198,7 @@ namespace ts { fileNames: [], wildcardDirectories: {} }; - const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath); + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); assertParsed(actual, expected); }); @@ -1382,7 +1382,7 @@ namespace ts { fileNames: [], wildcardDirectories: {} }; - const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath); + const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); assertParsed(actual, expected); }); }); diff --git a/src/harness/unittests/moduleResolution.ts b/src/harness/unittests/moduleResolution.ts index 5ea652573b6..4bb34cc2d03 100644 --- a/src/harness/unittests/moduleResolution.ts +++ b/src/harness/unittests/moduleResolution.ts @@ -152,10 +152,8 @@ namespace ts { testTypingsIgnored(["a", "b"]); testTypingsIgnored({ "a": "b" }); testTypingsIgnored(/*typings*/true); - /* tslint:disable no-null-keyword */ - testTypingsIgnored(null); - /* tslint:enable no-null-keyword */ - testTypingsIgnored(undefined); + testTypingsIgnored(/*typings*/ null); // tslint:disable-line no-null-keyword + testTypingsIgnored(/*typings*/ undefined); }); it("module name as directory - load index.d.ts", () => { test(/*hasDirectoryExists*/ false); diff --git a/src/harness/unittests/printer.ts b/src/harness/unittests/printer.ts index 894ffcf0ea2..0c6d4bfe8f7 100644 --- a/src/harness/unittests/printer.ts +++ b/src/harness/unittests/printer.ts @@ -80,6 +80,7 @@ namespace ts { describe("printNode", () => { const printsCorrectly = makePrintsCorrectly("printsNodeCorrectly"); const sourceFile = createSourceFile("source.ts", "", ScriptTarget.ES2015); + // tslint:disable boolean-trivia const syntheticNode = createClassDeclaration( undefined, undefined, @@ -97,6 +98,7 @@ namespace ts { ) ]) ); + // tslint:enable boolean-trivia printsCorrectly("class", {}, printer => printer.printNode(EmitHint.Unspecified, syntheticNode, sourceFile)); }); }); diff --git a/src/harness/unittests/reuseProgramStructure.ts b/src/harness/unittests/reuseProgramStructure.ts index c9ecef0de44..43014f25afb 100644 --- a/src/harness/unittests/reuseProgramStructure.ts +++ b/src/harness/unittests/reuseProgramStructure.ts @@ -323,7 +323,7 @@ namespace ts { const program_1 = newProgram(files, ["a.ts"], options); checkResolvedModulesCache(program_1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") })); - checkResolvedModulesCache(program_1, "b.ts", undefined); + checkResolvedModulesCache(program_1, "b.ts", /*expectedContent*/ undefined); const program_2 = updateProgram(program_1, ["a.ts"], options, files => { files[0].text = files[0].text.updateProgram("var x = 2"); @@ -332,14 +332,14 @@ namespace ts { // content of resolution cache should not change checkResolvedModulesCache(program_1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") })); - checkResolvedModulesCache(program_1, "b.ts", undefined); + checkResolvedModulesCache(program_1, "b.ts", /*expectedContent*/ undefined); // imports has changed - program is not reused const program_3 = updateProgram(program_2, ["a.ts"], options, files => { files[0].text = files[0].text.updateImportsAndExports(""); }); assert.isTrue(!program_2.structureIsReused); - checkResolvedModulesCache(program_3, "a.ts", undefined); + checkResolvedModulesCache(program_3, "a.ts", /*expectedContent*/ undefined); const program_4 = updateProgram(program_3, ["a.ts"], options, files => { const newImports = `import x from 'b' @@ -360,7 +360,7 @@ namespace ts { const program_1 = newProgram(files, ["/a.ts"], options); checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); - checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined); + checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); const program_2 = updateProgram(program_1, ["/a.ts"], options, files => { files[0].text = files[0].text.updateProgram("var x = 2"); @@ -369,7 +369,7 @@ namespace ts { // content of resolution cache should not change checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } })); - checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined); + checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); // type reference directives has changed - program is not reused const program_3 = updateProgram(program_2, ["/a.ts"], options, files => { @@ -377,7 +377,7 @@ namespace ts { }); assert.isTrue(!program_2.structureIsReused); - checkResolvedTypeDirectivesCache(program_3, "/a.ts", undefined); + checkResolvedTypeDirectivesCache(program_3, "/a.ts", /*expectedContent*/ undefined); updateProgram(program_3, ["/a.ts"], options, files => { const newReferences = `/// diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 53fcff30ad9..bf48232d6f3 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -310,7 +310,7 @@ namespace ts.projectSystem { register(cb: (...args: any[]) => void, args: any[]) { const timeoutId = this.nextId; this.nextId++; - this.map[timeoutId] = cb.bind(undefined, ...args); + this.map[timeoutId] = cb.bind(/*this*/ undefined, ...args); return timeoutId; } unregister(id: any) { diff --git a/src/harness/virtualFileSystem.ts b/src/harness/virtualFileSystem.ts index e409af9d4e7..b89f4c7232d 100644 --- a/src/harness/virtualFileSystem.ts +++ b/src/harness/virtualFileSystem.ts @@ -98,7 +98,7 @@ namespace Utils { useCaseSensitiveFileNames: boolean; constructor(currentDirectory: string, useCaseSensitiveFileNames: boolean) { - super(undefined, ""); + super(/*fileSystem*/ undefined, ""); this.fileSystem = this; this.root = new VirtualDirectory(this, ""); this.currentDirectory = currentDirectory; diff --git a/src/server/server.ts b/src/server/server.ts index ab746f44f5b..704193210e3 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -1,8 +1,6 @@ /// /// /// -// used in fs.writeSync -/* tslint:disable:no-null-keyword */ namespace ts.server { @@ -196,7 +194,8 @@ namespace ts.server { } if (this.fd >= 0) { const buf = new Buffer(s); - fs.writeSync(this.fd, buf, 0, buf.length, null); + // tslint:disable-next-line no-null-keyword + fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null); } if (this.traceToConsole) { console.warn(s); @@ -702,7 +701,7 @@ namespace ts.server { } sys.require = (initialDir: string, moduleName: string): RequireResult => { - const result = nodeModuleNameResolverWorker(moduleName, initialDir + "/program.ts", { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, sys, undefined, /*jsOnly*/ true); + const result = nodeModuleNameResolverWorker(moduleName, initialDir + "/program.ts", { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, sys, /*cache*/ undefined, /*jsOnly*/ true); try { return { module: require(result.resolvedModule.resolvedFileName), error: undefined }; } diff --git a/src/server/session.ts b/src/server/session.ts index d01f51cf6c3..73006ab899d 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -915,9 +915,8 @@ namespace ts.server { return combineProjectOutput( projects, project => project.getLanguageService().findReferences(file, position), - undefined, - // TODO: fixme - undefined + /*comparer*/ undefined, + /*areEqual (TODO: fixme)*/ undefined ); } diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 51b49a70d31..3a4547d4597 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -388,7 +388,7 @@ namespace ts.formatting { if (!formattingScanner.isOnToken()) { const leadingTrivia = formattingScanner.getCurrentLeadingTrivia(); if (leadingTrivia) { - processTrivia(leadingTrivia, enclosingNode, enclosingNode, undefined); + processTrivia(leadingTrivia, enclosingNode, enclosingNode, /*dynamicIndentation*/ undefined); trimTrailingWhitespacesForRemainingRange(); } } diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 96597da9d2d..f47837a70f7 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -214,7 +214,7 @@ namespace ts.Completions.PathCompletions { // doesn't support. For now, this is safer but slower const includeGlob = normalizedSuffix ? "**/*" : "./*"; - const matches = tryReadDirectory(host, baseDirectory, fileExtensions, undefined, [includeGlob]); + const matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]); if (matches) { const result: string[] = []; From fc988a16ee3300b8fa61cdaa758f0f0ed73e0ab0 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 7 Apr 2017 16:58:13 -0700 Subject: [PATCH 11/15] Pass correct regex flag --- src/server/editorServices.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 7dc17a385d3..6996f0c4df9 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1442,7 +1442,7 @@ namespace ts.server { const raw: SafeList = JSON.parse(this.host.readFile(fileName, "utf-8")); // Parse the regexps for (const k of Object.keys(raw)) { - raw[k].match = new RegExp(raw[k].match as {} as string, "gi"); + raw[k].match = new RegExp(raw[k].match as {} as string, "i"); } // raw is now fixed and ready ProjectService.safelist = raw; From 2b09e54baae89270445b5927f5bcfd27d410ff16 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 7 Apr 2017 16:58:21 -0700 Subject: [PATCH 12/15] Remove bad merge + unused cmd name --- src/server/protocol.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index bc96099f5e1..0bf13df7f4b 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -91,10 +91,8 @@ namespace ts.server.protocol { /* @internal */ export type BreakpointStatement = "breakpointStatement"; export type CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects"; - export type LoadTypesMap = "loadTypesMap"; export type GetCodeFixes = "getCodeFixes"; /* @internal */ - /* @internal */ export type GetCodeFixesFull = "getCodeFixes-full"; export type GetSupportedCodeFixes = "getSupportedCodeFixes"; } From a874567d46c3a6440f1fea5c75ec174026ea553d Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 7 Apr 2017 16:58:32 -0700 Subject: [PATCH 13/15] Remove tsserver command for loading different map --- src/server/session.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index 97c221a8add..4cdddc831a1 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -186,7 +186,6 @@ namespace ts.server { /* @internal */ export const BreakpointStatement: protocol.CommandTypes.BreakpointStatement = "breakpointStatement"; export const CompilerOptionsForInferredProjects: protocol.CommandTypes.CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects"; - export const LoadTypesMap: protocol.CommandTypes.LoadTypesMap = "loadTypesMap"; export const GetCodeFixes: protocol.CommandTypes.GetCodeFixes = "getCodeFixes"; /* @internal */ export const GetCodeFixesFull: protocol.CommandTypes.GetCodeFixesFull = "getCodeFixes-full"; @@ -1766,11 +1765,6 @@ namespace ts.server { this.setCompilerOptionsForInferredProjects(request.arguments); return this.requiredResponse(true); }, - [CommandNames.LoadTypesMap]: (request: protocol.FileRequest) => { - const loadArgs = request.arguments; - this.projectService.loadSafeList(loadArgs.file); - return this.notRequired(); - }, [CommandNames.ProjectInfo]: (request: protocol.ProjectInfoRequest) => { return this.requiredResponse(this.getProjectInfo(request.arguments)); }, From 2b3c2b34484872fc24bee6cdb92bc2cb88d112d3 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 10 Apr 2017 16:00:15 -0700 Subject: [PATCH 14/15] Add tests, comments, and min.js exclusion --- .../unittests/tsserverProjectSystem.ts | 40 ++++++++++++++++++- src/server/editorServices.ts | 25 +++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index c79d6c555e3..4b3fa82d79f 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1455,7 +1455,7 @@ namespace ts.projectSystem { checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]); }); - it("ignores files excluded by the safe type list", () => { + it("ignores files excluded by a custom safe type list", () => { const file1 = { path: "/a/b/f1.ts", content: "export let x = 5" @@ -1477,6 +1477,44 @@ namespace ts.projectSystem { } }); + it("ignores files excluded by the default type list", () => { + const file1 = { + path: "/a/b/f1.ts", + content: "export let x = 5" + }; + const minFile = { + path: "/c/moment.min.js", + content: "unspecified" + }; + const kendoFile1 = { + path: "/q/lib/kendo/kendo.all.min.js", + content: "unspecified" + }; + const kendoFile2 = { + path: "/q/lib/kendo/kendo.ui.min.js", + content: "unspecified" + }; + const officeFile1 = { + path: "/scripts/Office/1/excel-15.debug.js", + content: "unspecified" + }; + const officeFile2 = { + path: "/scripts/Office/1/powerpoint.js", + content: "unspecified" + }; + const files = [file1, minFile, kendoFile1, kendoFile2, officeFile1, officeFile2]; + const host = createServerHost(files); + const projectService = createProjectService(host); + try { + projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles(files.map(f => f.path)) }); + const proj = projectService.externalProjects[0]; + assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), [file1.path]); + assert.deepEqual(proj.getTypeAcquisition().include, ["kendo-ui", "office"]); + } finally { + projectService.resetSafeList(); + } + }); + it("open file become a part of configured project if it is referenced from root file", () => { const file1 = { path: "/a/b/f1.ts", diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 582c8974cec..3b79d6edca3 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -61,6 +61,24 @@ namespace ts.server { "smart": IndentStyle.Smart }); + /** + * How to understand this block: + * * The 'match' property is a regexp that matches a filename. + * * If 'match' is successful, then: + * * All files from 'exclude' are removed from the project. See below. + * * All 'types' are included in ATA + * * What the heck is 'exclude' ? + * * An array of an array of strings and numbers + * * Each array is: + * * An array of strings and numbers + * * The strings are literals + * * The numbers refer to capture group indices from the 'match' regexp + * * Remember that '1' is the first group + * * These are concatenated together to form a new regexp + * * Filenames matching these regexps are excluded from the project + * This default value is tested in tsserverProjectSystem.ts; add tests there + * if you are changing this so that you can be sure your regexp works! + */ const defaultTypeSafeList: SafeList = { "jquery": { // jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js") @@ -84,6 +102,11 @@ namespace ts.server { "match": /^(.*\/office\/1)\/excel-\d+\.debug\.js$/i, // Office NuGet package is installed under a "1/office" folder "exclude": [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it "types": ["office"] // @types package to fetch instead + }, + "Minified files": { + // e.g. /whatever/blah.min.js + "match": /^(.+\.min\.js)$/i, + "exclude": [["^", 1, "$"]] } }; @@ -1507,7 +1530,7 @@ namespace ts.server { // Copy back this field into the project if needed if (types.length > 0) { - proj.typeAcquisition = proj.typeAcquisition || { }; + proj.typeAcquisition = proj.typeAcquisition || {}; proj.typeAcquisition.include = types; } } From ed5eca2b7b8307ea2a666d9d72c68720db44d076 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 11 Apr 2017 09:37:31 -0700 Subject: [PATCH 15/15] boolean-trivia lint rule: Enforce space between comment and argument --- Gulpfile.ts | 18 +-- scripts/tslint/booleanTriviaRule.ts | 129 ++++++++++-------- src/compiler/binder.ts | 6 +- src/compiler/checker.ts | 14 +- src/compiler/commandLineParser.ts | 2 +- src/compiler/moduleNameResolver.ts | 6 +- src/compiler/parser.ts | 6 +- src/compiler/program.ts | 2 +- src/harness/fourslash.ts | 4 +- src/harness/harnessLanguageService.ts | 2 +- .../unittests/cachingInServerLSHost.ts | 2 +- src/harness/unittests/moduleResolution.ts | 6 +- .../unittests/services/preProcessFile.ts | 24 ++-- .../unittests/tsserverProjectSystem.ts | 16 +-- src/server/editorServices.ts | 2 +- src/services/codefixes/fixAddMissingMember.ts | 2 +- src/services/codefixes/helpers.ts | 6 +- .../codefixes/unusedIdentifierFixes.ts | 2 +- src/services/completions.ts | 4 +- src/services/documentRegistry.ts | 2 +- src/services/goToImplementation.ts | 2 +- src/services/pathCompletions.ts | 12 +- src/services/services.ts | 6 +- 23 files changed, 147 insertions(+), 128 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 7a3cbb2538f..3fcd972db34 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -384,7 +384,7 @@ function prependCopyright(outputCopyright: boolean = !useDebugMode) { } gulp.task(builtLocalCompiler, /*help*/ false, [servicesFile], () => { - const localCompilerProject = tsc.createProject("src/compiler/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/true)); + const localCompilerProject = tsc.createProject("src/compiler/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true)); return localCompilerProject.src() .pipe(newer(builtLocalCompiler)) .pipe(sourcemaps.init()) @@ -395,14 +395,14 @@ gulp.task(builtLocalCompiler, /*help*/ false, [servicesFile], () => { }); gulp.task(servicesFile, /*help*/ false, ["lib", "generate-diagnostics"], () => { - const servicesProject = tsc.createProject("src/services/tsconfig.json", getCompilerSettings({ removeComments: false }, /*useBuiltCompiler*/false)); + const servicesProject = tsc.createProject("src/services/tsconfig.json", getCompilerSettings({ removeComments: false }, /*useBuiltCompiler*/ false)); const {js, dts} = servicesProject.src() .pipe(newer(servicesFile)) .pipe(sourcemaps.init()) .pipe(servicesProject()); const completedJs = js.pipe(prependCopyright()) .pipe(sourcemaps.write(".")); - const completedDts = dts.pipe(prependCopyright(/*outputCopyright*/true)) + const completedDts = dts.pipe(prependCopyright(/*outputCopyright*/ true)) .pipe(insert.transform((contents, file) => { file.path = standaloneDefinitionsFile; return contents.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, "$1$2enum $3 {$4"); @@ -429,7 +429,7 @@ gulp.task(servicesFile, /*help*/ false, ["lib", "generate-diagnostics"], () => { // cancellationToken.js const cancellationTokenJs = path.join(builtLocalDirectory, "cancellationToken.js"); gulp.task(cancellationTokenJs, /*help*/ false, [servicesFile], () => { - const cancellationTokenProject = tsc.createProject("src/server/cancellationToken/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/true)); + const cancellationTokenProject = tsc.createProject("src/server/cancellationToken/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true)); return cancellationTokenProject.src() .pipe(newer(cancellationTokenJs)) .pipe(sourcemaps.init()) @@ -442,7 +442,7 @@ gulp.task(cancellationTokenJs, /*help*/ false, [servicesFile], () => { // typingsInstallerFile.js const typingsInstallerJs = path.join(builtLocalDirectory, "typingsInstaller.js"); gulp.task(typingsInstallerJs, /*help*/ false, [servicesFile], () => { - const cancellationTokenProject = tsc.createProject("src/server/typingsInstaller/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/true)); + const cancellationTokenProject = tsc.createProject("src/server/typingsInstaller/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true)); return cancellationTokenProject.src() .pipe(newer(typingsInstallerJs)) .pipe(sourcemaps.init()) @@ -455,7 +455,7 @@ gulp.task(typingsInstallerJs, /*help*/ false, [servicesFile], () => { const serverFile = path.join(builtLocalDirectory, "tsserver.js"); gulp.task(serverFile, /*help*/ false, [servicesFile, typingsInstallerJs, cancellationTokenJs], () => { - const serverProject = tsc.createProject("src/server/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/true)); + const serverProject = tsc.createProject("src/server/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true)); return serverProject.src() .pipe(newer(serverFile)) .pipe(sourcemaps.init()) @@ -479,7 +479,7 @@ gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile], (done) => { js.pipe(prependCopyright()) .pipe(sourcemaps.write(".")) .pipe(gulp.dest("src/server")), - dts.pipe(prependCopyright(/*outputCopyright*/true)) + dts.pipe(prependCopyright(/*outputCopyright*/ true)) .pipe(insert.transform((content) => { return content + "\r\nexport = ts;\r\nexport as namespace ts;"; })) @@ -551,7 +551,7 @@ gulp.task("LKG", "Makes a new LKG out of the built js files", ["clean", "dontUse // Task to build the tests infrastructure using the built compiler const run = path.join(builtLocalDirectory, "run.js"); gulp.task(run, /*help*/ false, [servicesFile], () => { - const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/true)); + const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true)); return testProject.src() .pipe(newer(run)) .pipe(sourcemaps.init()) @@ -757,7 +757,7 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo browserify(intoStream(file.contents), { debug: true }) .bundle((err, res) => { // assumes file.contents is a Buffer - const maps = JSON.parse(convertMap.fromSource(res.toString(), /*largeSource*/true).toJSON()); + const maps = JSON.parse(convertMap.fromSource(res.toString(), /*largeSource*/ true).toJSON()); delete maps.sourceRoot; maps.sources = maps.sources.map(s => path.resolve(s === "_stream_0.js" ? "built/local/_stream_0.js" : s)); // Strip browserify's inline comments away (could probably just let sorcery do this, but then we couldn't fix the paths) diff --git a/scripts/tslint/booleanTriviaRule.ts b/scripts/tslint/booleanTriviaRule.ts index ee5f855e864..a2a44b7a48a 100644 --- a/scripts/tslint/booleanTriviaRule.ts +++ b/scripts/tslint/booleanTriviaRule.ts @@ -8,7 +8,8 @@ export class Rule extends Lint.Rules.AbstractRule { } function walk(ctx: Lint.WalkContext): void { - ts.forEachChild(ctx.sourceFile, function recur(node: ts.Node): void { + const { sourceFile } = ctx; + ts.forEachChild(sourceFile, function recur(node: ts.Node): void { if (node.kind === ts.SyntaxKind.CallExpression) { checkCall(node as ts.CallExpression); } @@ -16,61 +17,79 @@ function walk(ctx: Lint.WalkContext): void { }); function checkCall(node: ts.CallExpression): void { - for (const arg of node.arguments) { - switch (arg.kind) { - case ts.SyntaxKind.TrueKeyword: - case ts.SyntaxKind.FalseKeyword: - case ts.SyntaxKind.NullKeyword: - break; - case ts.SyntaxKind.Identifier: - if ((arg as ts.Identifier).originalKeywordKind !== ts.SyntaxKind.UndefinedKeyword) { - continue; - } - break; - default: - continue; - } - - if (node.expression.kind === ts.SyntaxKind.PropertyAccessExpression) { - const methodName = (node.expression as ts.PropertyAccessExpression).name.text; - // Skip certain method names whose parameter names are not informative - if (methodName.indexOf("set") === 0) { - continue; - } - switch (methodName) { - case "apply": - case "assert": - case "call": - case "equal": - case "fail": - case "isTrue": - case "output": - case "stringify": - continue; - } - } - else if (node.expression.kind === ts.SyntaxKind.Identifier) { - const functionName = (node.expression as ts.Identifier).text; - // Skip certain function names whose parameter names are not informative - if (functionName.indexOf("set") === 0) { - continue; - } - switch (functionName) { - case "assert": - case "contains": - case "createAnonymousType": - case "createImportSpecifier": - case "createProperty": - case "createSignature": - case "resolveName": - continue; - } - } - - const ranges = ts.getLeadingCommentRanges(arg.getFullText(), 0); - if (!(ranges && ranges.length === 1 && ranges[0].kind === ts.SyntaxKind.MultiLineCommentTrivia)) { - ctx.addFailureAtNode(arg, 'Tag boolean argument with parameter name'); + if (!shouldIgnoreCalledExpression(node.expression)) { + for (const arg of node.arguments) { + checkArg(arg); } } } + + /** Skip certain function/method names whose parameter names are not informative. */ + function shouldIgnoreCalledExpression(expression: ts.Expression): boolean { + if (expression.kind === ts.SyntaxKind.PropertyAccessExpression) { + const methodName = (expression as ts.PropertyAccessExpression).name.text; + if (methodName.indexOf("set") === 0) { + return true; + } + switch (methodName) { + case "apply": + case "assert": + case "call": + case "equal": + case "fail": + case "isTrue": + case "output": + case "stringify": + return true; + } + } + else if (expression.kind === ts.SyntaxKind.Identifier) { + const functionName = (expression as ts.Identifier).text; + if (functionName.indexOf("set") === 0) { + return true; + } + switch (functionName) { + case "assert": + case "contains": + case "createAnonymousType": + case "createImportSpecifier": + case "createProperty": + case "createSignature": + case "resolveName": + return true; + } + } + return false; + } + + function checkArg(arg: ts.Expression): void { + if (!isTrivia(arg)) { + return; + } + + let ranges = ts.getTrailingCommentRanges(sourceFile.text, arg.pos) || ts.getLeadingCommentRanges(sourceFile.text, arg.pos); + if (ranges === undefined || ranges.length !== 1 || ranges[0].kind !== ts.SyntaxKind.MultiLineCommentTrivia) { + ctx.addFailureAtNode(arg, "Tag boolean argument with parameter name"); + return; + } + + const range = ranges[0]; + const argStart = arg.getStart(sourceFile); + if (range.end + 1 !== argStart && sourceFile.text.slice(range.end, argStart).indexOf("\n") === -1) { + ctx.addFailureAtNode(arg, "There should be 1 space between an argument and its comment."); + } + } + + function isTrivia(arg: ts.Expression): boolean { + switch (arg.kind) { + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.NullKeyword: + return true; + case ts.SyntaxKind.Identifier: + return (arg as ts.Identifier).originalKeywordKind === ts.SyntaxKind.UndefinedKeyword; + default: + return false; + } + } } diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 2477e909705..4e6a7a87afa 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -453,7 +453,7 @@ namespace ts { return local; } else { - return declareSymbol(container.locals, /*parent*/undefined, node, symbolFlags, symbolExcludes); + return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } } } @@ -2333,7 +2333,7 @@ namespace ts { function bindThisPropertyAssignment(node: BinaryExpression) { Debug.assert(isInJavaScriptFile(node)); - const container = getThisContainer(node, /*includeArrowFunctions*/false); + const container = getThisContainer(node, /*includeArrowFunctions*/ false); switch (container.kind) { case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: @@ -2423,7 +2423,7 @@ namespace ts { function bindCallExpression(node: CallExpression) { // We're only inspecting call expressions to detect CommonJS modules, so we can skip // this check if we've already seen the module indicator - if (!file.commonJsModuleIndicator && isRequireCall(node, /*checkArgumentIsStringLiteral*/false)) { + if (!file.commonJsModuleIndicator && isRequireCall(node, /*checkArgumentIsStringLiteral*/ false)) { setCommonJsModuleIndicator(node); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 343dc724286..aeae0de43fd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2620,7 +2620,7 @@ namespace ts { propertyName, optionalToken, propertyTypeNode, - /*initializer*/undefined)); + /*initializer*/ undefined)); } } return typeElements.length ? typeElements : undefined; @@ -2754,7 +2754,7 @@ namespace ts { /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { - let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/false); + let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/ false); let parentSymbol: Symbol; if (!accessibleSymbolChain || @@ -13386,7 +13386,7 @@ namespace ts { /// non-intrinsic elements' attributes type is the element instance type) function getJsxElementPropertiesName() { // JSX - const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/undefined); + const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined); // JSX.ElementAttributesProperty [symbol] const attribsPropTypeSym = jsxNamespace && getSymbol(jsxNamespace.exports, JsxNames.ElementAttributesPropertyNameContainer, SymbolFlags.Type); // JSX.ElementAttributesProperty [type] @@ -15615,7 +15615,7 @@ namespace ts { } function isCommonJsRequire(node: Node) { - if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) { + if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) { return false; } // Make sure require is not a local function @@ -17071,7 +17071,7 @@ namespace ts { function getTypeOfExpression(node: Expression, cache?: boolean) { // Optimize for the common case of a call to a function with a single non-generic call // signature where we can just fetch the return type without checking the arguments. - if (node.kind === SyntaxKind.CallExpression && (node).expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) { + if (node.kind === SyntaxKind.CallExpression && (node).expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) { const funcType = checkNonNullExpression((node).expression); const signature = getSingleCallSignature(funcType); if (signature && !signature.typeParameters) { @@ -21859,7 +21859,7 @@ namespace ts { } else if (isTypeReferenceIdentifier(entityName)) { const meaning = (entityName.parent.kind === SyntaxKind.TypeReference || entityName.parent.kind === SyntaxKind.JSDocTypeReference) ? SymbolFlags.Type : SymbolFlags.Namespace; - return resolveEntityName(entityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/true); + return resolveEntityName(entityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); } else if (entityName.parent.kind === SyntaxKind.JsxAttribute) { return getJsxAttributePropertySymbol(entityName.parent); @@ -22682,7 +22682,7 @@ namespace ts { ? SymbolFlags.Value | SymbolFlags.ExportValue : SymbolFlags.Type | SymbolFlags.Namespace; - const symbol = resolveEntityName(node, meaning, /*ignoreErrors*/true); + const symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true); return symbol && symbol !== unknownSymbol ? getTypeReferenceDirectivesForSymbol(symbol, meaning) : undefined; } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index a9df1d0d0b8..d5903b599b9 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1170,7 +1170,7 @@ namespace ts { const relativeDifference = convertToRelativePath(extendedDirname, basePath, getCanonicalFileName); const updatePath: (path: string) => string = path => isRootedDiskPath(path) ? path : combinePaths(relativeDifference, path); // Merge configs (copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios) - const result = parseJsonConfigFileContent(extendedResult.config, host, extendedDirname, /*existingOptions*/undefined, getBaseFileName(extendedConfigPath), resolutionStack.concat([resolvedPath])); + const result = parseJsonConfigFileContent(extendedResult.config, host, extendedDirname, /*existingOptions*/ undefined, getBaseFileName(extendedConfigPath), resolutionStack.concat([resolvedPath])); errors.push(...result.errors); const [include, exclude, files] = map(["include", "exclude", "files"], key => { if (!json[key] && extendedResult.config[key]) { diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 5280c794725..1603f08bb5f 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -656,7 +656,7 @@ namespace ts { // A path mapping may have a ".ts" extension; in contrast to an import, which should omit it. const tsExtension = tryGetExtensionFromPath(candidate); if (tsExtension !== undefined) { - const path = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/false, state); + const path = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state); return path && { path, extension: tsExtension }; } @@ -694,7 +694,7 @@ namespace ts { return { resolvedModule: undefined, failedLookupLocations }; function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> { - const loader: ResolutionKindSpecificLoader = (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/true); + const loader: ResolutionKindSpecificLoader = (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ true); const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state); if (resolved) { return toSearchResult({ resolved, isExternalLibraryImport: false }); @@ -710,7 +710,7 @@ namespace ts { } else { const candidate = normalizePath(combinePaths(containingDirectory, moduleName)); - const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/true); + const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true); return resolved && toSearchResult({ resolved, isExternalLibraryImport: false }); } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c6fe2f79992..f76b1a071f2 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3039,7 +3039,7 @@ namespace ts { // If we have an arrow, then try to parse the body. Even if not, try to parse if we // have an opening brace, just in case we're in an error state. const lastToken = token(); - arrowFunction.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/false, Diagnostics._0_expected, "=>"); + arrowFunction.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>"); arrowFunction.body = (lastToken === SyntaxKind.EqualsGreaterThanToken || lastToken === SyntaxKind.OpenBraceToken) ? parseArrowFunctionExpressionBody(isAsync) : parseIdentifier(); @@ -3808,7 +3808,7 @@ namespace ts { // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios // of one sort or another. if (inExpressionContext && token() === SyntaxKind.LessThanToken) { - const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElement(/*inExpressionContext*/true)); + const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true)); if (invalidElement) { parseErrorAtCurrentToken(Diagnostics.JSX_expressions_must_have_one_parent_element); const badNode = createNode(SyntaxKind.BinaryExpression, result.pos); @@ -5818,7 +5818,7 @@ namespace ts { } function processReferenceComments(sourceFile: SourceFile): void { - const triviaScanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/false, LanguageVariant.Standard, sourceText); + const triviaScanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, LanguageVariant.Standard, sourceText); const referencedFiles: FileReference[] = []; const typeReferenceDirectives: FileReference[] = []; const amdDependencies: { path: string; name: string }[] = []; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index ae15ece684e..f2d44adb1f1 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1291,7 +1291,7 @@ namespace ts { } function collectRequireCalls(node: Node): void { - if (isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) { + if (isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) { (imports || (imports = [])).push((node).arguments[0]); } else { diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index db05f9f1ddf..5ed1162bd93 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3787,11 +3787,11 @@ namespace FourSlashInterface { } public printCurrentFileStateWithWhitespace() { - this.state.printCurrentFileState(/*makeWhitespaceVisible*/true); + this.state.printCurrentFileState(/*makeWhitespaceVisible*/ true); } public printCurrentFileStateWithoutCaret() { - this.state.printCurrentFileState(/*makeWhitespaceVisible*/false, /*makeCaretVisible*/false); + this.state.printCurrentFileState(/*makeWhitespaceVisible*/ false, /*makeCaretVisible*/ false); } public printCurrentQuickInfo() { diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index b736ca1be72..c6477240161 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -210,7 +210,7 @@ namespace Harness.LanguageService { } readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] { return ts.matchFiles(path, extensions, exclude, include, - /*useCaseSensitiveFileNames*/false, + /*useCaseSensitiveFileNames*/ false, this.getCurrentDirectory(), (p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p)); } diff --git a/src/harness/unittests/cachingInServerLSHost.ts b/src/harness/unittests/cachingInServerLSHost.ts index e20288b8cd9..5389c8f37f8 100644 --- a/src/harness/unittests/cachingInServerLSHost.ts +++ b/src/harness/unittests/cachingInServerLSHost.ts @@ -65,7 +65,7 @@ namespace ts { }; const projectService = new server.ProjectService(serverHost, logger, { isCancellationRequested: () => false }, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined); - const rootScriptInfo = projectService.getOrCreateScriptInfo(rootFile, /* openedByClient */true, /*containingProject*/ undefined); + const rootScriptInfo = projectService.getOrCreateScriptInfo(rootFile, /*openedByClient*/ true, /*containingProject*/ undefined); const project = projectService.createInferredProjectWithRootFileIfNecessary(rootScriptInfo); project.setCompilerOptions({ module: ts.ModuleKind.AMD } ); return { diff --git a/src/harness/unittests/moduleResolution.ts b/src/harness/unittests/moduleResolution.ts index 4bb34cc2d03..14e13b60457 100644 --- a/src/harness/unittests/moduleResolution.ts +++ b/src/harness/unittests/moduleResolution.ts @@ -144,14 +144,14 @@ namespace ts { const resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile, indexFile)); - checkResolvedModule(resolution.resolvedModule, createResolvedModule(indexPath, /*isExternalLibraryImport*/true)); + checkResolvedModule(resolution.resolvedModule, createResolvedModule(indexPath, /*isExternalLibraryImport*/ true)); } } it("module name as directory - handle invalid 'typings'", () => { testTypingsIgnored(["a", "b"]); testTypingsIgnored({ "a": "b" }); - testTypingsIgnored(/*typings*/true); + testTypingsIgnored(/*typings*/ true); testTypingsIgnored(/*typings*/ null); // tslint:disable-line no-null-keyword testTypingsIgnored(/*typings*/ undefined); }); @@ -530,7 +530,7 @@ import b = require("./moduleB"); check("m1", main, m1); check("m2", main, m2); check("m3", main, m3Typings); - check("m4", main, m4, /*isExternalLibraryImport*/true); + check("m4", main, m4, /*isExternalLibraryImport*/ true); function check(name: string, caller: File, expected: File, isExternalLibraryImport = false) { const result = resolveModuleName(name, caller.name, options, host); diff --git a/src/harness/unittests/services/preProcessFile.ts b/src/harness/unittests/services/preProcessFile.ts index b7d319a690f..65f68b8ca25 100644 --- a/src/harness/unittests/services/preProcessFile.ts +++ b/src/harness/unittests/services/preProcessFile.ts @@ -34,7 +34,7 @@ describe("PreProcessFile:", function () { describe("Test preProcessFiles,", function () { it("Correctly return referenced files from triple slash", function () { test("///" + "\n" + "///" + "\n" + "///" + "\n" + "///", - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ false, { referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 37 }, { fileName: "refFile2.ts", pos: 38, end: 73 }, @@ -48,7 +48,7 @@ describe("PreProcessFile:", function () { it("Do not return reference path because of invalid triple-slash syntax", function () { test("///" + "\n" + "///" + "\n" + "///" + "\n" + "///", - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ false, { referencedFiles: [], @@ -61,7 +61,7 @@ describe("PreProcessFile:", function () { it("Correctly return imported files", function () { test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");", - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ false, { referencedFiles: [], @@ -88,7 +88,7 @@ describe("PreProcessFile:", function () { it("Do not return import path because of invalid import syntax", function () { test("import i1 require(\"r1.ts\"); import = require(\"r2.ts\") import i3= require(\"r3.ts\"); import i5", - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ false, { referencedFiles: [], @@ -101,7 +101,7 @@ describe("PreProcessFile:", function () { it("Correctly return referenced files and import files", function () { test("///" + "\n" + "///" + "\n" + "import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\");", - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ false, { referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 35 }, { fileName: "refFile2.ts", pos: 36, end: 71 }], @@ -114,7 +114,7 @@ describe("PreProcessFile:", function () { it("Correctly return referenced files and import files even with some invalid syntax", function () { test("///" + "\n" + "///" + "\n" + "import i1 = require(\"r1.ts\"); import = require(\"r2.ts\"); import i2 = require(\"r3.ts\");", - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ false, { referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 35 }], @@ -133,7 +133,7 @@ describe("PreProcessFile:", function () { "import {a as A} from \"m5\";" + "\n" + "import {a as A, b, c as C} from \"m6\";" + "\n" + "import def , {a, b, c as C} from \"m7\";" + "\n", - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ false, { referencedFiles: [], @@ -157,7 +157,7 @@ describe("PreProcessFile:", function () { "export {a} from \"m2\";" + "\n" + "export {a as A} from \"m3\";" + "\n" + "export {a as A, b, c as C} from \"m4\";" + "\n", - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ false, { referencedFiles: [], @@ -194,7 +194,7 @@ describe("PreProcessFile:", function () { it("Correctly handles export import declarations", function () { test("export import a = require(\"m1\");", - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ false, { referencedFiles: [], @@ -213,7 +213,7 @@ describe("PreProcessFile:", function () { foo(require('m3')); var z = { f: require('m4') } `, - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ true, { referencedFiles: [], @@ -233,7 +233,7 @@ describe("PreProcessFile:", function () { define(["mod1", "mod2"], (m1, m2) => { }); `, - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ true, { referencedFiles: [], @@ -251,7 +251,7 @@ describe("PreProcessFile:", function () { define("mod", ["mod1", "mod2"], (m1, m2) => { }); `, - /*readImportFile*/true, + /*readImportFile*/ true, /*detectJavaScriptImports*/ true, { referencedFiles: [], diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 10fb2832523..34e08f35699 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1795,9 +1795,9 @@ namespace ts.projectSystem { // Open HTML file projectService.applyChangesInOpenFiles( - /*openFiles*/[{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }], - /*changedFiles*/undefined, - /*closedFiles*/undefined); + /*openFiles*/ [{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }], + /*changedFiles*/ undefined, + /*closedFiles*/ undefined); // Now HTML file is included in the project checkNumberOfProjects(projectService, { configuredProjects: 1 }); @@ -1810,9 +1810,9 @@ namespace ts.projectSystem { // Close HTML file projectService.applyChangesInOpenFiles( - /*openFiles*/undefined, - /*changedFiles*/undefined, - /*closedFiles*/[file2.path]); + /*openFiles*/ undefined, + /*changedFiles*/ undefined, + /*closedFiles*/ [file2.path]); // HTML file is still included in project checkNumberOfProjects(projectService, { configuredProjects: 1 }); @@ -2270,12 +2270,12 @@ namespace ts.projectSystem { projectService.openClientFile(f1.path, "let x = 1;\nlet y = 2;"); projectService.checkNumberOfProjects({ externalProjects: 1 }); - projectService.externalProjects[0].getLanguageService(/*ensureSynchronized*/false).getNavigationBarItems(f1.path); + projectService.externalProjects[0].getLanguageService(/*ensureSynchronized*/ false).getNavigationBarItems(f1.path); projectService.closeClientFile(f1.path); projectService.openClientFile(f1.path); projectService.checkNumberOfProjects({ externalProjects: 1 }); - const navbar = projectService.externalProjects[0].getLanguageService(/*ensureSynchronized*/false).getNavigationBarItems(f1.path); + const navbar = projectService.externalProjects[0].getLanguageService(/*ensureSynchronized*/ false).getNavigationBarItems(f1.path); assert.equal(navbar[0].spans[0].length, f1.content.length); }); }); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 582c8974cec..00c81953ed4 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1091,7 +1091,7 @@ namespace ts.server { const { success, projectOptions, configFileErrors } = this.convertConfigFileContentToProjectOptions(project.getConfigFilePath()); if (!success) { // reset project settings to default - this.updateNonInferredProject(project, [], fileNamePropertyReader, {}, {}, /*compileOnSave*/false, configFileErrors); + this.updateNonInferredProject(project, [], fileNamePropertyReader, {}, {}, /*compileOnSave*/ false, configFileErrors); return configFileErrors; } diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index ec772e1e29e..a808786230d 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -118,7 +118,7 @@ namespace ts.codefix { stringTypeNode, /*initializer*/ undefined); const indexSignature = createIndexSignatureDeclaration( - /*decorators*/undefined, + /*decorators*/ undefined, /*modifiers*/ undefined, [indexingParameter], typeNode); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index d9e1387e029..0de04d7a9b9 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -194,7 +194,7 @@ namespace ts.codefix { modifiers, name, optional, - /*typeParameters*/undefined, + /*typeParameters*/ undefined, parameters, /*returnType*/ undefined); } @@ -217,9 +217,9 @@ namespace ts.codefix { [createThrow( createNew( createIdentifier("Error"), - /*typeArguments*/undefined, + /*typeArguments*/ undefined, [createLiteral("Method not implemented.")]))], - /*multiline*/true); + /*multiline*/ true); } function createVisibilityModifier(flags: ModifierFlags) { diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index f77f9723d0f..0daeea5df62 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -116,7 +116,7 @@ namespace ts.codefix { const nextToken = getTokenAtPosition(sourceFile, importClause.name.end); if (nextToken && nextToken.kind === SyntaxKind.CommaToken) { // shift first non-whitespace position after comma to the start position of the node - return deleteRange({ pos: start, end: skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/true) }); + return deleteRange({ pos: start, end: skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true) }); } else { return deleteNode(importClause.name); diff --git a/src/services/completions.ts b/src/services/completions.ts index c0b8be80441..2073b950bee 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -211,7 +211,7 @@ namespace ts.Completions { const type = typeChecker.getContextualType((element.parent)); const entries: CompletionEntry[] = []; if (type) { - getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/false, typeChecker, target, log); + getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/ false, typeChecker, target, log); if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries }; } @@ -239,7 +239,7 @@ namespace ts.Completions { const type = typeChecker.getTypeAtLocation(node.expression); const entries: CompletionEntry[] = []; if (type) { - getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/false, typeChecker, target, log); + getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false, typeChecker, target, log); if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries }; } diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index 891a25db76a..fa1b50a6662 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -214,7 +214,7 @@ namespace ts { } function releaseDocumentWithKey(path: Path, key: DocumentRegistryBucketKey): void { - const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/false); + const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ false); Debug.assert(bucket !== undefined); const entry = bucket.get(path); diff --git a/src/services/goToImplementation.ts b/src/services/goToImplementation.ts index dd3c06174af..1d9f48ae5e8 100644 --- a/src/services/goToImplementation.ts +++ b/src/services/goToImplementation.ts @@ -18,7 +18,7 @@ namespace ts.GoToImplementation { else { // Perform "Find all References" and retrieve only those that are implementations const referencedSymbols = FindAllReferences.getReferencedSymbolsForNode(context, - node, sourceFiles, /*findInStrings*/false, /*findInComments*/false, /*isForRename*/false, /*implementations*/true); + node, sourceFiles, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/ false, /*implementations*/ true); const result = flatMap(referencedSymbols, symbol => symbol.references); return result && result.length > 0 ? result : undefined; diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index f47837a70f7..2b45457c147 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -12,11 +12,11 @@ namespace ts.Completions.PathCompletions { const extensions = getSupportedExtensions(compilerOptions); if (compilerOptions.rootDirs) { entries = getCompletionEntriesForDirectoryFragmentWithRootDirs( - compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/false, span, compilerOptions, host, scriptPath); + compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, compilerOptions, host, scriptPath); } else { entries = getCompletionEntriesForDirectoryFragment( - literalValue, scriptDirectory, extensions, /*includeExtensions*/false, span, host, scriptPath); + literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, host, scriptPath); } } else { @@ -94,7 +94,7 @@ namespace ts.Completions.PathCompletions { if (tryDirectoryExists(host, baseDirectory)) { // Enumerate the available files if possible - const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/undefined, /*include*/["./*"]); + const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]); if (files) { /** @@ -153,7 +153,7 @@ namespace ts.Completions.PathCompletions { const fileExtensions = getSupportedExtensions(compilerOptions); const projectDir = compilerOptions.project || host.getCurrentDirectory(); const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl); - result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/false, span, host); + result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, span, host); if (paths) { for (const path in paths) { @@ -267,7 +267,7 @@ namespace ts.Completions.PathCompletions { nonRelativeModules.push(visibleModule.moduleName); } else if (startsWith(visibleModule.moduleName, moduleNameFragment)) { - const nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/undefined, /*include*/["./*"]); + const nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/ undefined, /*include*/ ["./*"]); if (nestedFiles) { for (let f of nestedFiles) { f = normalizePath(f); @@ -327,7 +327,7 @@ namespace ts.Completions.PathCompletions { if (kind === "path") { // Give completions for a relative path const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length); - completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, host, sourceFile.path); + completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/ true, span, host, sourceFile.path); } else { // Give completions based on the typings available diff --git a/src/services/services.ts b/src/services/services.ts index 3d108ac7fab..8ccc1d379d6 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1472,17 +1472,17 @@ namespace ts { } function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] { - const referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments, /*isForRename*/true); + const referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments, /*isForRename*/ true); return FindAllReferences.convertReferences(referencedSymbols); } function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] { - const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/false); + const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/ false); return FindAllReferences.convertReferences(referencedSymbols); } function findReferences(fileName: string, position: number): ReferencedSymbol[] { - const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/false); + const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/ false); // Only include referenced symbols that have a valid definition. return filter(referencedSymbols, rs => !!rs.definition); }